Changeset - de26de99ac5b
kallithea/controllers/admin/auth_settings.py
Show inline comments
 
@@ -8,109 +8,109 @@
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.controllers.admin.auth_settings
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
pluggable authentication controller for RhodeCode
 

	
 
:created_on: Nov 26, 2010
 
:author: akesterson
 
"""
 

	
 
import pprint
 
import logging
 
import formencode.htmlfill
 
import traceback
 

	
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 

	
 
from sqlalchemy.exc import DatabaseError
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.lib.compat import json, formatted_json
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.auth import LoginRequired, HasPermissionAllDecorator
 
from kallithea.lib import auth_modules
 
from kallithea.model.forms import AuthSettingsForm
 
from kallithea.model.db import Setting
 
from kallithea.model.meta import Session
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class AuthSettingsController(BaseController):
 

	
 
    @LoginRequired()
 
    @HasPermissionAllDecorator('hg.admin')
 
    def __before__(self):
 
        super(AuthSettingsController, self).__before__()
 

	
 
    def __load_defaults(self):
 
        c.available_plugins = [
 
            'kallithea.lib.auth_modules.auth_rhodecode',
 
            'kallithea.lib.auth_modules.auth_internal',
 
            'kallithea.lib.auth_modules.auth_container',
 
            'kallithea.lib.auth_modules.auth_ldap',
 
            'kallithea.lib.auth_modules.auth_crowd',
 
        ]
 
        c.enabled_plugins = Setting.get_auth_plugins()
 

	
 
    def index(self, defaults=None, errors=None, prefix_error=False):
 
        self.__load_defaults()
 
        _defaults = {}
 
        # default plugins loaded
 
        formglobals = {
 
            "auth_plugins": ["kallithea.lib.auth_modules.auth_rhodecode"]
 
            "auth_plugins": ["kallithea.lib.auth_modules.auth_internal"]
 
        }
 
        formglobals.update(Setting.get_auth_settings())
 
        formglobals["plugin_settings"] = {}
 
        formglobals["auth_plugins_shortnames"] = {}
 
        _defaults["auth_plugins"] = formglobals["auth_plugins"]
 

	
 
        for module in formglobals["auth_plugins"]:
 
            plugin = auth_modules.loadplugin(module)
 
            plugin_name = plugin.name
 
            formglobals["auth_plugins_shortnames"][module] = plugin_name
 
            formglobals["plugin_settings"][module] = plugin.plugin_settings()
 
            for v in formglobals["plugin_settings"][module]:
 
                fullname = ("auth_" + plugin_name + "_" + v["name"])
 
                if "default" in v:
 
                    _defaults[fullname] = v["default"]
 
                # Current values will be the default on the form, if there are any
 
                setting = Setting.get_by_name(fullname)
 
                if setting:
 
                    _defaults[fullname] = setting.app_settings_value
 
        # we want to show , seperated list of enabled plugins
 
        _defaults['auth_plugins'] = ','.join(_defaults['auth_plugins'])
 
        if defaults:
 
            _defaults.update(defaults)
 

	
 
        formglobals["defaults"] = _defaults
 
        # set template context variables
 
        for k, v in formglobals.iteritems():
 
            setattr(c, k, v)
 

	
 
        log.debug(pprint.pformat(formglobals, indent=4))
 
        log.debug(formatted_json(defaults))
 
        return formencode.htmlfill.render(
 
            render('admin/auth/auth_settings.html'),
 
            defaults=_defaults,
 
            errors=errors,
 
            prefix_error=prefix_error,
 
            encoding="UTF-8",
 
            force_defaults=True,
 
        )
 

	
 
    def auth_settings(self):
 
        """POST create and store auth settings"""
 
        self.__load_defaults()
 
        _form = AuthSettingsForm(c.enabled_plugins)()
 
        log.debug("POST Result: %s" % formatted_json(dict(request.POST)))
 

	
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
kallithea/controllers/admin/my_account.py
Show inline comments
 
@@ -71,97 +71,97 @@ class MyAccountController(BaseController
 

	
 
    def _load_my_repos_data(self, watched=False):
 
        if watched:
 
            admin = False
 
            repos_list = [x.follows_repository for x in
 
                          Session().query(UserFollowing).filter(
 
                              UserFollowing.user_id ==
 
                              self.authuser.user_id).all()]
 
        else:
 
            admin = True
 
            repos_list = Session().query(Repository)\
 
                         .filter(Repository.user_id ==
 
                                 self.authuser.user_id)\
 
                         .order_by(func.lower(Repository.repo_name)).all()
 

	
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
 
                                                   admin=admin)
 
        #json used to render the grid
 
        return json.dumps(repos_data)
 

	
 
    def my_account(self):
 
        """
 
        GET /_admin/my_account Displays info about my account
 
        """
 
        # url('my_account')
 
        c.active = 'profile'
 
        self.__load_data()
 
        c.perm_user = AuthUser(user_id=self.authuser.user_id,
 
                               ip_addr=self.ip_addr)
 
        c.extern_type = c.user.extern_type
 
        c.extern_name = c.user.extern_name
 

	
 
        defaults = c.user.get_dict()
 
        update = False
 
        if request.POST:
 
            _form = UserForm(edit=True,
 
                             old_data={'user_id': self.authuser.user_id,
 
                                       'email': self.authuser.email})()
 
            form_result = {}
 
            try:
 
                post_data = dict(request.POST)
 
                post_data['new_password'] = ''
 
                post_data['password_confirmation'] = ''
 
                form_result = _form.to_python(post_data)
 
                # skip updating those attrs for my account
 
                skip_attrs = ['admin', 'active', 'extern_type', 'extern_name',
 
                              'new_password', 'password_confirmation']
 
                #TODO: plugin should define if username can be updated
 
                if c.extern_type != "rhodecode":
 
                if c.extern_type != "internal":
 
                    # forbid updating username for external accounts
 
                    skip_attrs.append('username')
 

	
 
                UserModel().update(self.authuser.user_id, form_result,
 
                                   skip_attrs=skip_attrs)
 
                h.flash(_('Your account was updated successfully'),
 
                        category='success')
 
                Session().commit()
 
                update = True
 

	
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                    render('admin/my_account/my_account.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
 
            except Exception:
 
                log.error(traceback.format_exc())
 
                h.flash(_('Error occurred during update of user %s') \
 
                        % form_result.get('username'), category='error')
 
        if update:
 
            return redirect('my_account')
 
        return htmlfill.render(
 
            render('admin/my_account/my_account.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 

	
 
    def my_account_password(self):
 
        c.active = 'password'
 
        self.__load_data()
 
        if request.POST:
 
            _form = PasswordChangeForm(self.authuser.username)()
 
            try:
 
                form_result = _form.to_python(request.POST)
 
                UserModel().update(self.authuser.user_id, form_result)
 
                Session().commit()
 
                h.flash(_("Successfully updated password"), category='success')
 
            except formencode.Invalid as errors:
 
                return htmlfill.render(
 
                    render('admin/my_account/my_account.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
 
            except Exception:
kallithea/controllers/admin/users.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.controllers.admin.users
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Users crud controller for pylons
 

	
 
:created_on: Apr 4, 2010
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 
import logging
 
import traceback
 
import formencode
 
from pylons import response
 

	
 
from formencode import htmlfill
 
from pylons import request, session, tmpl_context as c, url, config
 
from pylons.controllers.util import redirect
 
from pylons.i18n.translation import _
 
from sqlalchemy.sql.expression import func
 

	
 
import kallithea
 
from kallithea.lib.exceptions import DefaultUserException, \
 
    UserOwnsReposException, UserCreationError
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
    AuthUser, generate_api_key
 
import kallithea.lib.auth_modules.auth_rhodecode
 
import kallithea.lib.auth_modules.auth_internal
 
from kallithea.lib import auth_modules
 
from kallithea.lib.base import BaseController, render
 
from kallithea.model.api_key import ApiKeyModel
 

	
 
from kallithea.model.db import User, UserEmailMap, UserIpMap, UserToPerm
 
from kallithea.model.forms import UserForm, CustomDefaultPermissionsForm
 
from kallithea.model.user import UserModel
 
from kallithea.model.meta import Session
 
from kallithea.lib.utils import action_logger
 
from kallithea.lib.compat import json
 
from kallithea.lib.utils2 import datetime_to_time, str2bool, safe_int
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class UsersController(BaseController):
 
    """REST Controller styled on the Atom Publishing Protocol"""
 

	
 
    @LoginRequired()
 
    @HasPermissionAllDecorator('hg.admin')
 
    def __before__(self):
 
        super(UsersController, self).__before__()
 
        c.available_permissions = config['available_permissions']
 

	
 
    def index(self, format='html'):
 
        """GET /users: All items in the collection"""
 
        # url('users')
 

	
 
        c.users_list = User.query().order_by(User.username)\
 
                        .filter(User.username != User.DEFAULT_USER)\
 
                        .order_by(func.lower(User.username))\
 
                        .all()
 

	
 
        users_data = []
 
        total_records = len(c.users_list)
 
        _tmpl_lookup = kallithea.CONFIG['pylons.app_globals'].mako_lookup
 
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
        grav_tmpl = lambda user_email, size: (
 
                template.get_def("user_gravatar")
 
                .render(user_email, size, _=_, h=h, c=c))
 

	
 
        username = lambda user_id, username: (
 
                template.get_def("user_name")
 
                .render(user_id, username, _=_, h=h, c=c))
 

	
 
        user_actions = lambda user_id, username: (
 
                template.get_def("user_actions")
 
                .render(user_id, username, _=_, h=h, c=c))
 

	
 
        for user in c.users_list:
 

	
 
            users_data.append({
 
                "gravatar": grav_tmpl(user. email, 20),
 
                "raw_name": user.username,
 
                "username": username(user.user_id, user.username),
 
                "firstname": user.name,
 
                "lastname": user.lastname,
 
                "last_login": h.fmt_date(user.last_login),
 
                "last_login_raw": datetime_to_time(user.last_login),
 
                "active": h.boolicon(user.active),
 
                "admin": h.boolicon(user.admin),
 
                "extern_type": user.extern_type,
 
                "extern_name": user.extern_name,
 
                "action": user_actions(user.user_id, user.username),
 
            })
 

	
 
        c.data = json.dumps({
 
            "totalRecords": total_records,
 
            "startIndex": 0,
 
            "sort": None,
 
            "dir": "asc",
 
            "records": users_data
 
        })
 

	
 
        return render('admin/users/users.html')
 

	
 
    def create(self):
 
        """POST /users: Create a new item"""
 
        # url('users')
 
        c.default_extern_type = auth_modules.auth_rhodecode.RhodeCodeAuthPlugin.name
 
        c.default_extern_type = auth_modules.auth_internal.RhodeCodeAuthPlugin.name
 
        user_model = UserModel()
 
        user_form = UserForm()()
 
        try:
 
            form_result = user_form.to_python(dict(request.POST))
 
            user_model.create(form_result)
 
            usr = form_result['username']
 
            action_logger(self.authuser, 'admin_created_user:%s' % usr,
 
                          None, self.ip_addr, self.sa)
 
            h.flash(_('Created user %s') % usr,
 
                    category='success')
 
            Session().commit()
 
        except formencode.Invalid, errors:
 
            return htmlfill.render(
 
                render('admin/users/user_add.html'),
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
        except UserCreationError, e:
 
            h.flash(e, 'error')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('Error occurred during creation of user %s') \
 
                    % request.POST.get('username'), category='error')
 
        return redirect(url('users'))
 

	
 
    def new(self, format='html'):
 
        """GET /users/new: Form to create a new item"""
 
        # url('new_user')
 
        c.default_extern_type = auth_modules.auth_rhodecode.RhodeCodeAuthPlugin.name
 
        c.default_extern_type = auth_modules.auth_internal.RhodeCodeAuthPlugin.name
 
        return render('admin/users/user_add.html')
 

	
 
    def update(self, id):
 
        """PUT /users/id: Update an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="PUT" />
 
        # Or using helpers:
 
        #    h.form(url('update_user', id=ID),
 
        #           method='put')
 
        # url('user', id=ID)
 
        c.active = 'profile'
 
        user_model = UserModel()
 
        c.user = user_model.get(id)
 
        c.extern_type = c.user.extern_type
 
        c.extern_name = c.user.extern_name
 
        c.perm_user = AuthUser(user_id=id, ip_addr=self.ip_addr)
 
        _form = UserForm(edit=True, old_data={'user_id': id,
 
                                              'email': c.user.email})()
 
        form_result = {}
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            skip_attrs = ['extern_type', 'extern_name']
 
            #TODO: plugin should define if username can be updated
 
            if c.extern_type != "rhodecode":
 
            if c.extern_type != "internal":
 
                # forbid updating username for external accounts
 
                skip_attrs.append('username')
 

	
 
            user_model.update(id, form_result, skip_attrs=skip_attrs)
 
            usr = form_result['username']
 
            action_logger(self.authuser, 'admin_updated_user:%s' % usr,
 
                          None, self.ip_addr, self.sa)
 
            h.flash(_('User updated successfully'), category='success')
 
            Session().commit()
 
        except formencode.Invalid, errors:
 
            defaults = errors.value
 
            e = errors.error_dict or {}
 
            defaults.update({
 
                'create_repo_perm': user_model.has_perm(id,
 
                                                        'hg.create.repository'),
 
                'fork_repo_perm': user_model.has_perm(id, 'hg.fork.repository'),
 
                '_method': 'put'
 
            })
 
            return htmlfill.render(
 
                render('admin/users/user_edit.html'),
 
                defaults=defaults,
 
                errors=e,
 
                prefix_error=False,
 
                encoding="UTF-8")
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('Error occurred during update of user %s') \
 
                    % form_result.get('username'), category='error')
 
        return redirect(url('edit_user', id=id))
 

	
 
    def delete(self, id):
 
        """DELETE /users/id: Delete an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="DELETE" />
 
        # Or using helpers:
 
        #    h.form(url('delete_user', id=ID),
 
        #           method='delete')
 
        # url('user', id=ID)
 
        usr = User.get_or_404(id)
 
        try:
 
            UserModel().delete(usr)
 
            Session().commit()
 
            h.flash(_('Successfully deleted user'), category='success')
 
        except (UserOwnsReposException, DefaultUserException), e:
 
            h.flash(e, category='warning')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during deletion of user'),
kallithea/controllers/api/api.py
Show inline comments
 
@@ -573,98 +573,98 @@ class ApiController(JSONRPCController):
 

	
 
            error:  null
 

	
 
        """
 
        if not HasPermissionAnyApi('hg.admin')(user=apiuser):
 
            # make sure normal user does not pass someone else userid,
 
            # he is not allowed to do that
 
            if not isinstance(userid, Optional) and userid != apiuser.user_id:
 
                raise JSONRPCError(
 
                    'userid is not the same as your user'
 
                )
 

	
 
        if isinstance(userid, Optional):
 
            userid = apiuser.user_id
 

	
 
        user = get_user_or_error(userid)
 
        data = user.get_api_data()
 
        data['permissions'] = AuthUser(user_id=user.user_id).permissions
 
        return data
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def get_users(self, apiuser):
 
        """
 
        Lists all existing users. This command can be executed only using api_key
 
        belonging to user with admin rights.
 

	
 
        :param apiuser: filled automatically from apikey
 
        :type apiuser: AuthUser
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: [<user_object>, ...]
 
            error:  null
 
        """
 

	
 
        result = []
 
        users_list = User.query().order_by(User.username) \
 
            .filter(User.username != User.DEFAULT_USER) \
 
            .all()
 
        for user in users_list:
 
            result.append(user.get_api_data())
 
        return result
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def create_user(self, apiuser, username, email, password=Optional(''),
 
                    firstname=Optional(''), lastname=Optional(''),
 
                    active=Optional(True), admin=Optional(False),
 
                    extern_name=Optional('rhodecode'),
 
                    extern_type=Optional('rhodecode')):
 
                    extern_name=Optional('internal'),
 
                    extern_type=Optional('internal')):
 
        """
 
        Creates new user. Returns new user object. This command can
 
        be executed only using api_key belonging to user with admin rights.
 

	
 
        :param apiuser: filled automatically from apikey
 
        :type apiuser: AuthUser
 
        :param username: new username
 
        :type username: str or int
 
        :param email: email
 
        :type email: str
 
        :param password: password
 
        :type password: Optional(str)
 
        :param firstname: firstname
 
        :type firstname: Optional(str)
 
        :param lastname: lastname
 
        :type lastname: Optional(str)
 
        :param active: active
 
        :type active: Optional(bool)
 
        :param admin: admin
 
        :type admin: Optional(bool)
 
        :param extern_name: name of extern
 
        :type extern_name: Optional(str)
 
        :param extern_type: extern_type
 
        :type extern_type: Optional(str)
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: {
 
                      "msg" : "created new user `<username>`",
 
                      "user": <user_obj>
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "user `<username>` already exist"
 
            or
 
            "email `<email>` already exist"
 
            or
 
            "failed to create user `<username>`"
 
          }
 

	
 
        """
kallithea/lib/auth_modules/__init__.py
Show inline comments
 
@@ -260,97 +260,97 @@ class RhodeCodeExternalAuthPlugin(RhodeC
 
            userobj, username, passwd, settings, **kwargs)
 
        if auth:
 
            # maybe plugin will clean the username ?
 
            # we should use the return value
 
            username = auth['username']
 
            # if user is not active from our extern type we should fail to authe
 
            # this can prevent from creating users in RhodeCode when using
 
            # external authentication, but if it's inactive user we shouldn't
 
            # create that user anyway
 
            if auth['active_from_extern'] is False:
 
                log.warning("User %s authenticated against %s, but is inactive"
 
                            % (username, self.__module__))
 
                return None
 

	
 
            if self.use_fake_password():
 
                # Randomize the PW because we don't need it, but don't want
 
                # them blank either
 
                passwd = PasswordGenerator().gen_password(length=8)
 

	
 
            log.debug('Updating or creating user info from %s plugin'
 
                      % self.name)
 
            user = UserModel().create_or_update(
 
                username=username,
 
                password=passwd,
 
                email=auth["email"],
 
                firstname=auth["firstname"],
 
                lastname=auth["lastname"],
 
                active=auth["active"],
 
                admin=auth["admin"],
 
                extern_name=auth["extern_name"],
 
                extern_type=self.name
 
            )
 
            Session().flush()
 
            # enforce user is just in given groups, all of them has to be ones
 
            # created from plugins. We store this info in _group_data JSON field
 
            try:
 
                groups = auth['groups'] or []
 
                UserGroupModel().enforce_groups(user, groups, self.name)
 
            except Exception:
 
                # for any reason group syncing fails, we should proceed with login
 
                log.error(traceback.format_exc())
 
            Session().commit()
 
        return auth
 

	
 

	
 
def importplugin(plugin):
 
    """
 
    Imports and returns the authentication plugin in the module named by plugin
 
    (e.g., plugin='kallithea.lib.auth_modules.auth_rhodecode'). Returns the
 
    (e.g., plugin='kallithea.lib.auth_modules.auth_internal'). Returns the
 
    RhodeCodeAuthPluginBase subclass on success, raises exceptions on failure.
 

	
 
    raises:
 
        AttributeError -- no RhodeCodeAuthPlugin class in the module
 
        TypeError -- if the RhodeCodeAuthPlugin is not a subclass of ours RhodeCodeAuthPluginBase
 
        ImportError -- if we couldn't import the plugin at all
 
    """
 
    log.debug("Importing %s" % plugin)
 
    PLUGIN_CLASS_NAME = "RhodeCodeAuthPlugin"
 
    try:
 
        module = importlib.import_module(plugin)
 
    except (ImportError, TypeError):
 
        log.error(traceback.format_exc())
 
        # TODO: make this more error prone, if by some accident we screw up
 
        # the plugin name, the crash is preatty bad and hard to recover
 
        raise
 

	
 
    log.debug("Loaded auth plugin from %s (module:%s, file:%s)"
 
              % (plugin, module.__name__, module.__file__))
 

	
 
    pluginclass = getattr(module, PLUGIN_CLASS_NAME)
 
    if not issubclass(pluginclass, RhodeCodeAuthPluginBase):
 
        raise TypeError("Authentication class %s.RhodeCodeAuthPlugin is not "
 
                        "a subclass of %s" % (plugin, RhodeCodeAuthPluginBase))
 
    return pluginclass
 

	
 

	
 
def loadplugin(plugin):
 
    """
 
    Loads and returns an instantiated authentication plugin.
 

	
 
        see: importplugin
 
    """
 
    plugin = importplugin(plugin)()
 
    if plugin.plugin_settings.im_func != RhodeCodeAuthPluginBase.plugin_settings.im_func:
 
        raise TypeError("Authentication class %s.RhodeCodeAuthPluginBase "
 
                        "has overriden the plugin_settings method, which is "
 
                        "forbidden." % plugin)
 
    return plugin
 

	
 

	
 
def authenticate(username, password, environ=None):
 
    """
 
    Authentication function used for access control,
 
    It tries to authenticate based on enabled authentication modules.
 

	
 
    :param username: username can be empty for container auth
 
    :param password: password can be empty for container auth
kallithea/lib/auth_modules/auth_internal.py
Show inline comments
 
file renamed from kallithea/lib/auth_modules/auth_rhodecode.py to kallithea/lib/auth_modules/auth_internal.py
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.lib.auth_modules.auth_rhodecode
 
kallithea.lib.auth_modules.auth_internal
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
RhodeCode authentication plugin for built in internal auth
 

	
 
:created_on: Created on Nov 17, 2012
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 

	
 
import logging
 
from kallithea.lib import auth_modules
 
from kallithea.lib.compat import formatted_json, hybrid_property
 
from kallithea.model.db import User
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class RhodeCodeAuthPlugin(auth_modules.RhodeCodeAuthPluginBase):
 
    def __init__(self):
 
        pass
 

	
 
    @hybrid_property
 
    def name(self):
 
        return "rhodecode"
 
        return "internal"
 

	
 
    def settings(self):
 
        return []
 

	
 
    def user_activation_state(self):
 
        def_user_perms = User.get_default_user().AuthUser.permissions['global']
 
        return 'hg.register.auto_activate' in def_user_perms
 

	
 
    def accepts(self, user, accepts_empty=True):
 
        """
 
        Custom accepts for this auth that doesn't accept empty users. We
 
        know that user exisits in database.
 
        """
 
        return super(RhodeCodeAuthPlugin, self).accepts(user,
 
                                                        accepts_empty=False)
 

	
 
    def auth(self, userobj, username, password, settings, **kwargs):
 
        if not userobj:
 
            log.debug('userobj was:%s skipping' % (userobj, ))
 
            return None
 
        if userobj.extern_type != self.name:
 
            log.warn("userobj:%s extern_type mismatch got:`%s` expected:`%s`"
 
                     % (userobj, userobj.extern_type, self.name))
 
            return None
 

	
 
        user_attrs = {
 
            "username": userobj.username,
 
            "firstname": userobj.firstname,
 
            "lastname": userobj.lastname,
 
            "groups": [],
 
            "email": userobj.email,
 
            "admin": userobj.admin,
 
            "active": userobj.active,
 
            "active_from_extern": userobj.active,
 
            "extern_name": userobj.user_id,
 
            'extern_type': userobj.extern_type,
 
        }
 

	
 
        log.debug(formatted_json(user_attrs))
 
        if userobj.active:
 
            from kallithea.lib import auth
 
            password_match = auth.RhodeCodeCrypto.hash_check(password, userobj.password)
 
            if userobj.username == User.DEFAULT_USER and userobj.active:
 
                log.info('user %s authenticated correctly as anonymous user' %
 
                         username)
 
                return user_attrs
 

	
 
            elif userobj.username == username and password_match:
kallithea/lib/db_manage.py
Show inline comments
 
@@ -329,98 +329,98 @@ class DbManage(object):
 
        hooks5.ui_value = 'python:kallithea.lib.hooks.log_pull_action'
 
        self.sa.add(hooks5)
 

	
 
        hooks6 = Ui()
 
        hooks6.ui_section = 'hooks'
 
        hooks6.ui_key = Ui.HOOK_PRE_PULL
 
        hooks6.ui_value = 'python:kallithea.lib.hooks.pre_pull'
 
        self.sa.add(hooks6)
 

	
 
        # enable largefiles
 
        largefiles = Ui()
 
        largefiles.ui_section = 'extensions'
 
        largefiles.ui_key = 'largefiles'
 
        largefiles.ui_value = ''
 
        self.sa.add(largefiles)
 

	
 
        # set default largefiles cache dir, defaults to
 
        # /repo location/.cache/largefiles
 
        largefiles = Ui()
 
        largefiles.ui_section = 'largefiles'
 
        largefiles.ui_key = 'usercache'
 
        largefiles.ui_value = os.path.join(repo_store_path, '.cache',
 
                                           'largefiles')
 
        self.sa.add(largefiles)
 

	
 
        # enable hgsubversion disabled by default
 
        hgsubversion = Ui()
 
        hgsubversion.ui_section = 'extensions'
 
        hgsubversion.ui_key = 'hgsubversion'
 
        hgsubversion.ui_value = ''
 
        hgsubversion.ui_active = False
 
        self.sa.add(hgsubversion)
 

	
 
        # enable hggit disabled by default
 
        hggit = Ui()
 
        hggit.ui_section = 'extensions'
 
        hggit.ui_key = 'hggit'
 
        hggit.ui_value = ''
 
        hggit.ui_active = False
 
        self.sa.add(hggit)
 

	
 
    def create_auth_plugin_options(self, skip_existing=False):
 
        """
 
        Create default auth plugin settings, and make it active
 

	
 
        :param skip_existing:
 
        """
 

	
 
        for k, v, t in [('auth_plugins', 'kallithea.lib.auth_modules.auth_rhodecode', 'list'),
 
                     ('auth_rhodecode_enabled', 'True', 'bool')]:
 
        for k, v, t in [('auth_plugins', 'kallithea.lib.auth_modules.auth_internal', 'list'),
 
                     ('auth_internal_enabled', 'True', 'bool')]:
 
            if skip_existing and Setting.get_by_name(k) != None:
 
                log.debug('Skipping option %s' % k)
 
                continue
 
            setting = Setting(k, v, t)
 
            self.sa.add(setting)
 

	
 
    def create_default_options(self, skip_existing=False):
 
        """Creates default settings"""
 

	
 
        for k, v, t in [
 
            ('default_repo_enable_locking',  False, 'bool'),
 
            ('default_repo_enable_downloads', False, 'bool'),
 
            ('default_repo_enable_statistics', False, 'bool'),
 
            ('default_repo_private', False, 'bool'),
 
            ('default_repo_type', 'hg', 'unicode')]:
 

	
 
            if skip_existing and Setting.get_by_name(k) is not None:
 
                log.debug('Skipping option %s' % k)
 
                continue
 
            setting = Setting(k, v, t)
 
            self.sa.add(setting)
 

	
 
    def fixup_groups(self):
 
        def_usr = User.get_default_user()
 
        for g in RepoGroup.query().all():
 
            g.group_name = g.get_new_name(g.name)
 
            self.sa.add(g)
 
            # get default perm
 
            default = UserRepoGroupToPerm.query()\
 
                .filter(UserRepoGroupToPerm.group == g)\
 
                .filter(UserRepoGroupToPerm.user == def_usr)\
 
                .scalar()
 

	
 
            if default is None:
 
                log.debug('missing default permission for group %s adding' % g)
 
                perm_obj = RepoGroupModel()._create_default_perms(g)
 
                self.sa.add(perm_obj)
 

	
 
    def reset_permissions(self, username):
 
        """
 
        Resets permissions to default state, usefull when old systems had
 
        bad permissions, we must clean them up
 

	
 
        :param username:
 
        """
 
        default_user = User.get_by_username(username)
 
        if not default_user:
 
            return
 
@@ -496,92 +496,92 @@ class DbManage(object):
 
    def create_settings(self, path):
 

	
 
        self.create_ui_settings(path)
 

	
 
        ui_config = [
 
            ('web', 'push_ssl', 'false'),
 
            ('web', 'allow_archive', 'gz zip bz2'),
 
            ('web', 'allow_push', '*'),
 
            ('web', 'baseurl', '/'),
 
            ('paths', '/', path),
 
            #('phases', 'publish', 'false')
 
        ]
 
        for section, key, value in ui_config:
 
            ui_conf = Ui()
 
            setattr(ui_conf, 'ui_section', section)
 
            setattr(ui_conf, 'ui_key', key)
 
            setattr(ui_conf, 'ui_value', value)
 
            self.sa.add(ui_conf)
 

	
 
        settings = [
 
            ('realm', 'RhodeCode', 'unicode'),
 
            ('title', '', 'unicode'),
 
            ('ga_code', '', 'unicode'),
 
            ('show_public_icon', True, 'bool'),
 
            ('show_private_icon', True, 'bool'),
 
            ('stylify_metatags', False, 'bool'),
 
            ('dashboard_items', 100, 'int'),
 
            ('admin_grid_items', 25, 'int'),
 
            ('show_version', True, 'bool'),
 
            ('use_gravatar', True, 'bool'),
 
            ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'),
 
            ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'),
 
            ('update_url', Setting.DEFAULT_UPDATE_URL, 'unicode'),
 
        ]
 
        for key, val, type_ in settings:
 
            sett = Setting(key, val, type_)
 
            self.sa.add(sett)
 

	
 
        self.create_auth_plugin_options()
 
        self.create_default_options()
 

	
 
        log.info('created ui config')
 

	
 
    def create_user(self, username, password, email='', admin=False):
 
        log.info('creating user %s' % username)
 
        UserModel().create_or_update(username, password, email,
 
                                     firstname='RhodeCode', lastname='Admin',
 
                                     active=True, admin=admin,
 
                                     extern_type="rhodecode")
 
                                     extern_type="internal")
 

	
 
    def create_default_user(self):
 
        log.info('creating default user')
 
        # create default user for handling default permissions.
 
        user = UserModel().create_or_update(username=User.DEFAULT_USER,
 
                                            password=str(uuid.uuid1())[:20],
 
                                            email='anonymous@kallithea-scm.org',
 
                                            firstname='Anonymous',
 
                                            lastname='User')
 
        # based on configuration options activate/deactive this user which
 
        # controlls anonymous access
 
        if self.cli_args.get('public_access') is False:
 
            log.info('Public access disabled')
 
            user.active = False
 
            Session().add(user)
 
            Session().commit()
 

	
 
    def create_permissions(self):
 
        """
 
        Creates all permissions defined in the system
 
        """
 
        # module.(access|create|change|delete)_[name]
 
        # module.(none|read|write|admin)
 
        log.info('creating permissions')
 
        PermissionModel(self.sa).create_permissions()
 

	
 
    def populate_default_permissions(self):
 
        """
 
        Populate default permissions. It will create only the default
 
        permissions that are missing, and not alter already defined ones
 
        """
 
        log.info('creating default user permissions')
 
        PermissionModel(self.sa).create_default_permissions(user=User.DEFAULT_USER)
 

	
 
    @staticmethod
 
    def check_waitress():
 
        """
 
        Function executed at the end of setup
 
        """
 
        if not __py_version__ >= (2, 6):
 
            notify('Python2.5 detected, please switch '
 
                   'egg:waitress#main -> egg:Paste#http '
 
                   'in your .ini file')
kallithea/lib/dbmigrate/versions/016_version_2_0_0.py
Show inline comments
 
@@ -18,52 +18,52 @@ log = logging.getLogger(__name__)
 

	
 

	
 
def upgrade(migrate_engine):
 
    """
 
    Upgrade operations go here.
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 
    _reset_base(migrate_engine)
 
    from kallithea.lib.dbmigrate.schema import db_2_0_0
 
    tbl = db_2_0_0.User.__table__
 

	
 
    extern_type = Column("extern_type",
 
                         String(255, convert_unicode=False, assert_unicode=None),
 
                         nullable=True, unique=None, default=None)
 
    extern_type.create(table=tbl)
 

	
 
    extern_name = Column("extern_name", String(255, convert_unicode=False, assert_unicode=None),
 
                         nullable=True, unique=None, default=None)
 
    extern_name.create(table=tbl)
 

	
 
    created_on = Column('created_on', DateTime(timezone=False),
 
                        nullable=True, default=datetime.datetime.now)
 
    created_on.create(table=tbl)
 

	
 
    # issue fixups
 
    fixups(db_2_0_0, meta.Session)
 

	
 

	
 
def downgrade(migrate_engine):
 
    meta = MetaData()
 
    meta.bind = migrate_engine
 

	
 

	
 
def fixups(models, _SESSION):
 
    notify('Fixing default created on')
 

	
 
    for usr in models.User.get_all():
 
        usr.created_on = datetime.datetime.now()
 
        _SESSION().add(usr)
 
        _SESSION().commit()
 

	
 
    notify('Migrating LDAP attribute to extern')
 
    for usr in models.User.get_all():
 
        ldap_dn = usr.ldap_dn
 
        if ldap_dn:
 
            usr.extern_name = ldap_dn
 
            usr.extern_type = 'ldap'
 
        else:
 
            usr.extern_name = 'rhodecode'
 
            usr.extern_type = 'rhodecode'
 
            usr.extern_name = 'internal'
 
            usr.extern_type = 'internal'
 
        _SESSION().add(usr)
 
        _SESSION().commit()
kallithea/lib/dbmigrate/versions/018_version_2_0_0.py
Show inline comments
 
import logging
 
import datetime
 

	
 
from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relation, backref, class_mapper, joinedload
 
from sqlalchemy.orm.session import Session
 
from sqlalchemy.ext.declarative import declarative_base
 

	
 
from kallithea.lib.dbmigrate.migrate import *
 
from kallithea.lib.dbmigrate.migrate.changeset import *
 
from kallithea.lib.utils2 import str2bool
 

	
 
from kallithea.model.meta import Base
 
from kallithea.model import meta
 
from kallithea.lib.dbmigrate.versions import _reset_base, notify
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def upgrade(migrate_engine):
 
    """
 
    Upgrade operations go here.
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 
    _reset_base(migrate_engine)
 
    from kallithea.lib.dbmigrate.schema import db_2_0_0
 

	
 
    # issue fixups
 
    fixups(db_2_0_0, meta.Session)
 

	
 

	
 
def downgrade(migrate_engine):
 
    meta = MetaData()
 
    meta.bind = migrate_engine
 

	
 

	
 
def fixups(models, _SESSION):
 
    notify('Fixing default auth modules')
 
    plugins = 'kallithea.lib.auth_modules.auth_rhodecode'
 
    plugins = 'kallithea.lib.auth_modules.auth_internal'
 
    opts = []
 
    ldap_enabled = str2bool(getattr(
 
        models.Setting.get_by_name('ldap_active'),
 
        'app_settings_value', False))
 
    if ldap_enabled:
 
        plugins += ',kallithea.lib.auth_modules.auth_ldap'
 
        opts.append(('auth_ldap_enabled', 'True', 'bool'))
 

	
 
    opts.append(('auth_plugins', plugins, 'list'),)
 
    opts.append(('auth_rhodecode_enabled', 'True', 'bool'))
 
    opts.append(('auth_internal_enabled', 'True', 'bool'))
 

	
 
    for name, default, type_ in opts:
 
        setting = models.Setting.get_by_name(name)
 
        if not setting:
 
            # if we don't have this option create it
 
            setting = models.Setting(name, default, type_)
 

	
 
        _SESSION().add(setting)
 
        _SESSION().commit()
 

	
 
    #copy over the LDAP settings
 
    old_ldap = [('ldap_active', 'false', 'bool'), ('ldap_host', '', 'unicode'),
 
                ('ldap_port', '389', 'int'), ('ldap_tls_kind', 'PLAIN', 'unicode'),
 
                ('ldap_tls_reqcert', '', 'unicode'), ('ldap_dn_user', '', 'unicode'),
 
                ('ldap_dn_pass', '', 'unicode'), ('ldap_base_dn', '', 'unicode'),
 
                ('ldap_filter', '', 'unicode'), ('ldap_search_scope', '', 'unicode'),
 
                ('ldap_attr_login', '', 'unicode'), ('ldap_attr_firstname', '', 'unicode'),
 
                ('ldap_attr_lastname', '', 'unicode'), ('ldap_attr_email', '', 'unicode')]
 
    for k, v, t in old_ldap:
 
        old_setting = models.Setting.get_by_name(k)
 
        name = 'auth_%s' % k
 
        setting = models.Setting.get_by_name(name)
 
        if not setting:
 
            # if we don't have this option create it
 
            setting = models.Setting(name, old_setting.app_settings_value, t)
 

	
 
        _SESSION().add(setting)
 
        _SESSION().commit()
kallithea/lib/dbmigrate/versions/020_version_2_0_1.py
Show inline comments
 
import logging
 
import datetime
 

	
 
from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relation, backref, class_mapper, joinedload
 
from sqlalchemy.orm.session import Session
 
from sqlalchemy.ext.declarative import declarative_base
 

	
 
from kallithea.lib.dbmigrate.migrate import *
 
from kallithea.lib.dbmigrate.migrate.changeset import *
 
from kallithea.lib.utils2 import str2bool
 

	
 
from kallithea.model.meta import Base
 
from kallithea.model import meta
 
from kallithea.lib.dbmigrate.versions import _reset_base, notify
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def upgrade(migrate_engine):
 
    """
 
    Upgrade operations go here.
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 
    _reset_base(migrate_engine)
 
    from kallithea.lib.dbmigrate.schema import db_2_0_1
 

	
 
    # issue fixups
 
    fixups(db_2_0_1, meta.Session)
 

	
 

	
 
def downgrade(migrate_engine):
 
    meta = MetaData()
 
    meta.bind = migrate_engine
 

	
 

	
 
def fixups(models, _SESSION):
 
    #fix all empty extern type users to default 'rhodecode'
 
    #fix all empty extern type users to default 'internal'
 
    for usr in models.User.query().all():
 
        if not usr.extern_name:
 
            usr.extern_name = 'rhodecode'
 
            usr.extern_type = 'rhodecode'
 
            usr.extern_name = 'internal'
 
            usr.extern_type = 'internal'
 
            _SESSION().add(usr)
 
            _SESSION().commit()
kallithea/model/user.py
Show inline comments
 
@@ -140,98 +140,98 @@ class UserModel(BaseModel):
 
        check_allowed_create_user(user_data, cur_user)
 

	
 
        log.debug('Checking for %s account in RhodeCode database' % username)
 
        user = User.get_by_username(username, case_insensitive=True)
 
        if user is None:
 
            log.debug('creating new user %s' % username)
 
            new_user = User()
 
            edit = False
 
        else:
 
            log.debug('updating user %s' % username)
 
            new_user = user
 
            edit = True
 

	
 
        try:
 
            new_user.username = username
 
            new_user.admin = admin
 
            new_user.email = email
 
            new_user.active = active
 
            new_user.extern_name = safe_unicode(extern_name) if extern_name else None
 
            new_user.extern_type = safe_unicode(extern_type) if extern_type else None
 
            new_user.name = firstname
 
            new_user.lastname = lastname
 

	
 
            if not edit:
 
                new_user.api_key = generate_api_key(username)
 

	
 
            # set password only if creating an user or password is changed
 
            password_change = new_user.password and not check_password(password,
 
                                                            new_user.password)
 
            if not edit or password_change:
 
                reason = 'new password' if edit else 'new user'
 
                log.debug('Updating password reason=>%s' % (reason,))
 
                new_user.password = get_crypt_password(password) if password else None
 

	
 
            self.sa.add(new_user)
 

	
 
            if not edit:
 
                log_create_user(new_user.get_dict(), cur_user)
 
            return new_user
 
        except (DatabaseError,):
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def create_registration(self, form_data):
 
        from kallithea.model.notification import NotificationModel
 

	
 
        try:
 
            form_data['admin'] = False
 
            form_data['extern_name'] = 'rhodecode'
 
            form_data['extern_type'] = 'rhodecode'
 
            form_data['extern_name'] = 'internal'
 
            form_data['extern_type'] = 'internal'
 
            new_user = self.create(form_data)
 

	
 
            self.sa.add(new_user)
 
            self.sa.flush()
 

	
 
            # notification to admins
 
            subject = _('New user registration')
 
            body = ('New user registration\n'
 
                    '---------------------\n'
 
                    '- Username: %s\n'
 
                    '- Full Name: %s\n'
 
                    '- Email: %s\n')
 
            body = body % (new_user.username, new_user.full_name, new_user.email)
 
            edit_url = url('edit_user', id=new_user.user_id, qualified=True)
 
            kw = {'registered_user_url': edit_url}
 
            NotificationModel().create(created_by=new_user, subject=subject,
 
                                       body=body, recipients=None,
 
                                       type_=Notification.TYPE_REGISTRATION,
 
                                       email_kwargs=kw)
 

	
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def update(self, user_id, form_data, skip_attrs=[]):
 
        from kallithea.lib.auth import get_crypt_password
 
        try:
 
            user = self.get(user_id, cache=False)
 
            if user.username == User.DEFAULT_USER:
 
                raise DefaultUserException(
 
                                _("You can't Edit this user since it's "
 
                                  "crucial for entire application"))
 

	
 
            for k, v in form_data.items():
 
                if k in skip_attrs:
 
                    continue
 
                if k == 'new_password' and v:
 
                    user.password = get_crypt_password(v)
 
                else:
 
                    # old legacy thing orm models store firstname as name,
 
                    # need proper refactor to username
 
                    if k == 'firstname':
 
                        k = 'name'
 
                    setattr(user, k, v)
 
            self.sa.add(user)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
kallithea/templates/admin/my_account/my_account_profile.html
Show inline comments
 
${h.form(url('my_account'), method='post')}
 
    <div class="form">
 

	
 
         <div class="field">
 
           <div class="gravatar_box">
 
               <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div>
 
                <p>
 
                %if c.visual.use_gravatar:
 
                <strong>${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong>
 
                <br/>${_('Using')} ${c.user.email}
 
                %else:
 
                <strong>${_('Avatars are disabled')}</strong>
 
                <br/>${c.user.email or _('Missing email, please update your user email address.')}
 
                    [${_('current IP')}: ${c.perm_user.ip_addr or "?"}]
 
                %endif
 
               </p>
 
           </div>
 
         </div>
 

	
 
        <% readonly = None %>
 
        <% disabled = "" %>
 
        <div class="fields">
 
           %if c.extern_type != 'rhodecode':
 
           %if c.extern_type != 'internal':
 
                <% readonly = "readonly" %>
 
                <% disabled = " disabled" %>
 
                <strong>${_('Your user is in an external Source of Record; some details cannot be managed here')}.</strong>
 
           %endif
 
             <div class="field">
 
                <div class="label">
 
                    <label for="username">${_('Username')}:</label>
 
                </div>
 
                <div class="input">
 
                  ${h.text('username',class_='medium%s' % disabled, readonly=readonly)}
 
                  ${h.hidden('extern_name', c.extern_name)}
 
                  ${h.hidden('extern_type', c.extern_type)}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="name">${_('First Name')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('firstname',class_="medium")}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="lastname">${_('Last Name')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('lastname',class_="medium")}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="email">${_('Email')}:</label>
 
                </div>
 
                <div class="input">
 
                    ## we should be able to edit email !
 
                    ${h.text('email',class_="medium")}
 
                </div>
 
             </div>
 

	
 
            <div class="buttons">
 
              ${h.submit('save',_('Save'),class_="btn")}
 
              ${h.reset('reset',_('Reset'),class_="btn")}
 
            </div>
 
        </div>
kallithea/templates/admin/users/user_edit_profile.html
Show inline comments
 
${h.form(url('update_user', id=c.user.user_id),method='put')}
 
<div class="form">
 
        <div class="field">
 
           <div class="gravatar_box">
 
               <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div>
 
                <p>
 
                %if c.visual.use_gravatar:
 
                <strong>${_('Change avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong>
 
                <br/>${_('Using')} ${c.user.email}
 
                %else:
 
                <strong>${_('Avatars are disabled')}</strong>
 
                <br/>${c.user.email or _('Missing email, please update this user email address.')}
 
                        ##show current ip just if we show ourself
 
                        %if c.authuser.username == c.user.username:
 
                            [${_('current IP')}: ${c.perm_user.ip_addr or "?"}]
 
                        %endif
 
                %endif
 
           </div>
 
        </div>
 
        <% readonly = None %>
 
        <% disabled = "" %>
 
        <div class="fields">
 
            %if c.extern_type != 'rhodecode':
 
            %if c.extern_type != 'internal':
 
             <div class="field">
 
               <% readonly = "readonly" %>
 
               <% disabled = " disabled" %>
 
               <strong>${_('This user is in an external Source of Record (%s); some details cannot be managed here.' % c.extern_type)}.</strong>
 
             </div>
 
            %endif
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="username">${_('Username')}:</label>
 
                </div>
 
                <div class="input">
 
                  ${h.text('username',class_='medium%s' % disabled, readonly=readonly)}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="email">${_('Email')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('email',class_='medium')}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="extern_type">${_('Source of Record')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('extern_type',class_='medium disabled',readonly="readonly")}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="extern_name">${_('Name in Source of Record')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('extern_name',class_='medium disabled',readonly="readonly")}
 
                </div>
 
             </div>
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="new_password">${_('New password')}:</label>
 
                </div>
 
                <div class="input">
kallithea/tests/api/api_base.py
Show inline comments
 
@@ -573,97 +573,97 @@ class BaseTestApi(object):
 
    def test_api_create_user(self):
 
        username = 'test_new_api_user'
 
        email = username + "@foo.com"
 

	
 
        id_, params = _build_data(self.apikey, 'create_user',
 
                                  username=username,
 
                                  email=email,
 
                                  password='trololo')
 
        response = api_call(self, params)
 

	
 
        usr = UserModel().get_by_username(username)
 
        ret = dict(
 
            msg='created new user `%s`' % username,
 
            user=jsonify(usr.get_api_data())
 
        )
 

	
 
        try:
 
            expected = ret
 
            self._compare_ok(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_user(usr.user_id)
 

	
 
    def test_api_create_user_without_password(self):
 
        username = 'test_new_api_user_passwordless'
 
        email = username + "@foo.com"
 

	
 
        id_, params = _build_data(self.apikey, 'create_user',
 
                                  username=username,
 
                                  email=email)
 
        response = api_call(self, params)
 

	
 
        usr = UserModel().get_by_username(username)
 
        ret = dict(
 
            msg='created new user `%s`' % username,
 
            user=jsonify(usr.get_api_data())
 
        )
 
        try:
 
            expected = ret
 
            self._compare_ok(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_user(usr.user_id)
 

	
 
    def test_api_create_user_with_extern_name(self):
 
        username = 'test_new_api_user_passwordless'
 
        email = username + "@foo.com"
 

	
 
        id_, params = _build_data(self.apikey, 'create_user',
 
                                  username=username,
 
                                  email=email, extern_name='rhodecode')
 
                                  email=email, extern_name='internal')
 
        response = api_call(self, params)
 

	
 
        usr = UserModel().get_by_username(username)
 
        ret = dict(
 
            msg='created new user `%s`' % username,
 
            user=jsonify(usr.get_api_data())
 
        )
 
        try:
 
            expected = ret
 
            self._compare_ok(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_user(usr.user_id)
 

	
 
    @mock.patch.object(UserModel, 'create_or_update', crash)
 
    def test_api_create_user_when_exception_happened(self):
 

	
 
        username = 'test_new_api_user'
 
        email = username + "@foo.com"
 

	
 
        id_, params = _build_data(self.apikey, 'create_user',
 
                                  username=username,
 
                                  email=email,
 
                                  password='trololo')
 
        response = api_call(self, params)
 
        expected = 'failed to create user `%s`' % username
 
        self._compare_error(id_, expected, given=response.body)
 

	
 
    def test_api_delete_user(self):
 
        usr = UserModel().create_or_update(username=u'test_user',
 
                                           password=u'qweqwe',
 
                                           email=u'u232@example.com',
 
                                           firstname=u'u1', lastname=u'u1')
 
        Session().commit()
 
        username = usr.username
 
        email = usr.email
 
        usr_id = usr.user_id
 
        ## DELETE THIS USER NOW
 

	
 
        id_, params = _build_data(self.apikey, 'delete_user',
 
                                  userid=username, )
 
        response = api_call(self, params)
 

	
 
        ret = {'msg': 'deleted user ID:%s %s' % (usr_id, username),
 
               'user': None}
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    @mock.patch.object(UserModel, 'delete', crash)
kallithea/tests/fixture.py
Show inline comments
 
@@ -65,97 +65,97 @@ class Fixture(object):
 

	
 
        return context()
 

	
 
    def _get_repo_create_params(self, **custom):
 
        defs = dict(
 
            repo_name=None,
 
            repo_type='hg',
 
            clone_uri='',
 
            repo_group='-1',
 
            repo_description='DESC',
 
            repo_private=False,
 
            repo_landing_rev='rev:tip',
 
            repo_copy_permissions=False,
 
            repo_state=Repository.STATE_CREATED,
 
        )
 
        defs.update(custom)
 
        if 'repo_name_full' not in custom:
 
            defs.update({'repo_name_full': defs['repo_name']})
 

	
 
        # fix the repo name if passed as repo_name_full
 
        if defs['repo_name']:
 
            defs['repo_name'] = defs['repo_name'].split('/')[-1]
 

	
 
        return defs
 

	
 
    def _get_group_create_params(self, **custom):
 
        defs = dict(
 
            group_name=None,
 
            group_description='DESC',
 
            group_parent_id=None,
 
            perms_updates=[],
 
            perms_new=[],
 
            enable_locking=False,
 
            recursive=False
 
        )
 
        defs.update(custom)
 

	
 
        return defs
 

	
 
    def _get_user_create_params(self, name, **custom):
 
        defs = dict(
 
            username=name,
 
            password='qweqwe',
 
            email='%s+test@example.com' % name,
 
            firstname='TestUser',
 
            lastname='Test',
 
            active=True,
 
            admin=False,
 
            extern_type='rhodecode',
 
            extern_type='internal',
 
            extern_name=None
 
        )
 
        defs.update(custom)
 

	
 
        return defs
 

	
 
    def _get_user_group_create_params(self, name, **custom):
 
        defs = dict(
 
            users_group_name=name,
 
            user_group_description='DESC',
 
            users_group_active=True,
 
            user_group_data={},
 
        )
 
        defs.update(custom)
 

	
 
        return defs
 

	
 
    def create_repo(self, name, **kwargs):
 
        if 'skip_if_exists' in kwargs:
 
            del kwargs['skip_if_exists']
 
            r = Repository.get_by_repo_name(name)
 
            if r:
 
                return r
 

	
 
        if isinstance(kwargs.get('repo_group'), RepoGroup):
 
            kwargs['repo_group'] = kwargs['repo_group'].group_id
 

	
 
        form_data = self._get_repo_create_params(repo_name=name, **kwargs)
 
        cur_user = kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN)
 
        RepoModel().create(form_data, cur_user)
 
        Session().commit()
 
        return Repository.get_by_repo_name(name)
 

	
 
    def create_fork(self, repo_to_fork, fork_name, **kwargs):
 
        repo_to_fork = Repository.get_by_repo_name(repo_to_fork)
 

	
 
        form_data = self._get_repo_create_params(repo_name=fork_name,
 
                                            fork_parent_id=repo_to_fork,
 
                                            repo_type=repo_to_fork.repo_type,
 
                                            **kwargs)
 
        form_data['update_after_clone'] = False
 

	
 
        #TODO: fix it !!
 
        form_data['description'] = form_data['repo_description']
 
        form_data['private'] = form_data['repo_private']
 
        form_data['landing_rev'] = form_data['repo_landing_rev']
 

	
 
        owner = kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN)
kallithea/tests/functional/test_admin_auth_settings.py
Show inline comments
 
from kallithea.tests import *
 
from kallithea.model.db import Setting
 

	
 

	
 
class TestAuthSettingsController(TestController):
 
    def _enable_plugins(self, plugins_list):
 
        test_url = url(controller='admin/auth_settings',
 
                       action='auth_settings')
 
        params={'auth_plugins': plugins_list,}
 

	
 
        for plugin in plugins_list.split(','):
 
            enable = plugin.partition('kallithea.lib.auth_modules.')[-1]
 
            params.update({'%s_enabled' % enable: True})
 
        response = self.app.post(url=test_url, params=params)
 
        return params
 
        #self.checkSessionFlash(response, 'Auth settings updated successfully')
 

	
 
    def test_index(self):
 
        self.log_user()
 
        response = self.app.get(url(controller='admin/auth_settings',
 
                                    action='index'))
 
        response.mustcontain('Authentication Plugins')
 

	
 
    def test_ldap_save_settings(self):
 
        self.log_user()
 
        if ldap_lib_installed:
 
            raise SkipTest('skipping due to missing ldap lib')
 

	
 
        params = self._enable_plugins('kallithea.lib.auth_modules.auth_rhodecode,kallithea.lib.auth_modules.auth_ldap')
 
        params = self._enable_plugins('kallithea.lib.auth_modules.auth_internal,kallithea.lib.auth_modules.auth_ldap')
 
        params.update({'auth_ldap_host': u'dc.example.com',
 
                       'auth_ldap_port': '999',
 
                       'auth_ldap_tls_kind': 'PLAIN',
 
                       'auth_ldap_tls_reqcert': 'NEVER',
 
                       'auth_ldap_dn_user': 'test_user',
 
                       'auth_ldap_dn_pass': 'test_pass',
 
                       'auth_ldap_base_dn': 'test_base_dn',
 
                       'auth_ldap_filter': 'test_filter',
 
                       'auth_ldap_search_scope': 'BASE',
 
                       'auth_ldap_attr_login': 'test_attr_login',
 
                       'auth_ldap_attr_firstname': 'ima',
 
                       'auth_ldap_attr_lastname': 'tester',
 
                       'auth_ldap_attr_email': 'test@example.com'})
 

	
 
        test_url = url(controller='admin/auth_settings',
 
                       action='auth_settings')
 

	
 
        response = self.app.post(url=test_url, params=params)
 
        self.checkSessionFlash(response, 'Auth settings updated successfully')
 

	
 
        new_settings = Setting.get_auth_settings()
 
        self.assertEqual(new_settings['auth_ldap_host'], u'dc.example.com',
 
                         'fail db write compare')
 

	
 
    def test_ldap_error_form_wrong_port_number(self):
 
        self.log_user()
 
        if ldap_lib_installed:
 
            raise SkipTest('skipping due to missing ldap lib')
 

	
 
        params = self._enable_plugins('kallithea.lib.auth_modules.auth_rhodecode,kallithea.lib.auth_modules.auth_ldap')
 
        params = self._enable_plugins('kallithea.lib.auth_modules.auth_internal,kallithea.lib.auth_modules.auth_ldap')
 
        params.update({'auth_ldap_host': '',
 
                       'auth_ldap_port': 'i-should-be-number',  # bad port num
 
                       'auth_ldap_tls_kind': 'PLAIN',
 
                       'auth_ldap_tls_reqcert': 'NEVER',
 
                       'auth_ldap_dn_user': '',
 
                       'auth_ldap_dn_pass': '',
 
                       'auth_ldap_base_dn': '',
 
                       'auth_ldap_filter': '',
 
                       'auth_ldap_search_scope': 'BASE',
 
                       'auth_ldap_attr_login': '',
 
                       'auth_ldap_attr_firstname': '',
 
                       'auth_ldap_attr_lastname': '',
 
                       'auth_ldap_attr_email': ''})
 
        test_url = url(controller='admin/auth_settings',
 
                       action='auth_settings')
 

	
 
        response = self.app.post(url=test_url, params=params)
 

	
 
        response.mustcontain("""<span class="error-message">"""
 
                             """Please enter a number</span>""")
 

	
 
    def test_ldap_error_form(self):
 
        self.log_user()
 
        if ldap_lib_installed:
 
            raise SkipTest('skipping due to missing ldap lib')
 

	
 
        params = self._enable_plugins('kallithea.lib.auth_modules.auth_rhodecode,kallithea.lib.auth_modules.auth_ldap')
 
        params = self._enable_plugins('kallithea.lib.auth_modules.auth_internal,kallithea.lib.auth_modules.auth_ldap')
 
        params.update({'auth_ldap_host': 'Host',
 
                       'auth_ldap_port': '123',
 
                       'auth_ldap_tls_kind': 'PLAIN',
 
                       'auth_ldap_tls_reqcert': 'NEVER',
 
                       'auth_ldap_dn_user': '',
 
                       'auth_ldap_dn_pass': '',
 
                       'auth_ldap_base_dn': '',
 
                       'auth_ldap_filter': '',
 
                       'auth_ldap_search_scope': 'BASE',
 
                       'auth_ldap_attr_login': '',  # <----- missing required input
 
                       'auth_ldap_attr_firstname': '',
 
                       'auth_ldap_attr_lastname': '',
 
                       'auth_ldap_attr_email': ''})
 

	
 
        test_url = url(controller='admin/auth_settings',
 
                       action='auth_settings')
 

	
 
        response = self.app.post(url=test_url, params=params)
 

	
 
        response.mustcontain("""<span class="error-message">The LDAP Login"""
 
                             """ attribute of the CN must be specified""")
 

	
 
    def test_ldap_login(self):
 
        pass
 

	
 
    def test_ldap_login_incorrect(self):
 
        pass
kallithea/tests/functional/test_admin_users.py
Show inline comments
 
@@ -11,177 +11,177 @@
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from sqlalchemy.orm.exc import NoResultFound
 

	
 
from kallithea.tests import *
 
from kallithea.tests.fixture import Fixture
 
from kallithea.model.db import User, Permission, UserIpMap, UserApiKeys
 
from kallithea.lib.auth import check_password
 
from kallithea.model.user import UserModel
 
from kallithea.model import validators
 
from kallithea.lib import helpers as h
 
from kallithea.model.meta import Session
 

	
 
fixture = Fixture()
 

	
 

	
 
class TestAdminUsersController(TestController):
 
    test_user_1 = 'testme'
 

	
 
    @classmethod
 
    def teardown_class(cls):
 
        if User.get_by_username(cls.test_user_1):
 
            UserModel().delete(cls.test_user_1)
 
            Session().commit()
 

	
 
    def test_index(self):
 
        self.log_user()
 
        response = self.app.get(url('users'))
 
        # Test response...
 

	
 
    def test_create(self):
 
        self.log_user()
 
        username = 'newtestuser'
 
        password = 'test12'
 
        password_confirmation = password
 
        name = 'name'
 
        lastname = 'lastname'
 
        email = 'mail@mail.com'
 

	
 
        response = self.app.post(url('users'),
 
            {'username': username,
 
             'password': password,
 
             'password_confirmation': password_confirmation,
 
             'firstname': name,
 
             'active': True,
 
             'lastname': lastname,
 
             'extern_name': 'rhodecode',
 
             'extern_type': 'rhodecode',
 
             'extern_name': 'internal',
 
             'extern_type': 'internal',
 
             'email': email})
 

	
 
        self.checkSessionFlash(response, '''Created user %s''' % (username))
 

	
 
        new_user = Session().query(User).\
 
            filter(User.username == username).one()
 

	
 
        self.assertEqual(new_user.username, username)
 
        self.assertEqual(check_password(password, new_user.password), True)
 
        self.assertEqual(new_user.name, name)
 
        self.assertEqual(new_user.lastname, lastname)
 
        self.assertEqual(new_user.email, email)
 

	
 
        response.follow()
 
        response = response.follow()
 
        response.mustcontain("""newtestuser""")
 

	
 
    def test_create_err(self):
 
        self.log_user()
 
        username = 'new_user'
 
        password = ''
 
        name = 'name'
 
        lastname = 'lastname'
 
        email = 'errmail.com'
 

	
 
        response = self.app.post(url('users'), {'username': username,
 
                                               'password': password,
 
                                               'name': name,
 
                                               'active': False,
 
                                               'lastname': lastname,
 
                                               'email': email})
 

	
 
        msg = validators.ValidUsername(False, {})._messages['system_invalid_username']
 
        msg = h.html_escape(msg % {'username': 'new_user'})
 
        response.mustcontain("""<span class="error-message">%s</span>""" % msg)
 
        response.mustcontain("""<span class="error-message">Please enter a value</span>""")
 
        response.mustcontain("""<span class="error-message">An email address must contain a single @</span>""")
 

	
 
        def get_user():
 
            Session().query(User).filter(User.username == username).one()
 

	
 
        self.assertRaises(NoResultFound, get_user), 'found user in database'
 

	
 
    def test_new(self):
 
        self.log_user()
 
        response = self.app.get(url('new_user'))
 

	
 
    @parameterized.expand(
 
        [('firstname', {'firstname': 'new_username'}),
 
         ('lastname', {'lastname': 'new_username'}),
 
         ('admin', {'admin': True}),
 
         ('admin', {'admin': False}),
 
         ('extern_type', {'extern_type': 'ldap'}),
 
         ('extern_type', {'extern_type': None}),
 
         ('extern_name', {'extern_name': 'test'}),
 
         ('extern_name', {'extern_name': None}),
 
         ('active', {'active': False}),
 
         ('active', {'active': True}),
 
         ('email', {'email': 'some@email.com'}),
 
        # ('new_password', {'new_password': 'foobar123',
 
        #                   'password_confirmation': 'foobar123'})
 
        ])
 
    def test_update(self, name, attrs):
 
        self.log_user()
 
        usr = fixture.create_user(self.test_user_1, password='qweqwe',
 
                                  email='testme@example.com',
 
                                  extern_type='rhodecode',
 
                                  extern_type='internal',
 
                                  extern_name=self.test_user_1,
 
                                  skip_if_exists=True)
 
        Session().commit()
 
        params = usr.get_api_data()
 
        params.update({'password_confirmation': ''})
 
        params.update({'new_password': ''})
 
        params.update(attrs)
 
        if name == 'email':
 
            params['emails'] = [attrs['email']]
 
        if name == 'extern_type':
 
            #cannot update this via form, expected value is original one
 
            params['extern_type'] = "rhodecode"
 
            params['extern_type'] = "internal"
 
        if name == 'extern_name':
 
            #cannot update this via form, expected value is original one
 
            params['extern_name'] = self.test_user_1
 
            # special case since this user is not
 
                                          # logged in yet his data is not filled
 
                                          # so we use creation data
 

	
 
        response = self.app.put(url('user', id=usr.user_id), params)
 
        self.checkSessionFlash(response, 'User updated successfully')
 

	
 
        updated_user = User.get_by_username(self.test_user_1)
 
        updated_params = updated_user.get_api_data()
 
        updated_params.update({'password_confirmation': ''})
 
        updated_params.update({'new_password': ''})
 

	
 
        self.assertEqual(params, updated_params)
 

	
 
    def test_delete(self):
 
        self.log_user()
 
        username = 'newtestuserdeleteme'
 

	
 
        fixture.create_user(name=username)
 

	
 
        new_user = Session().query(User)\
 
            .filter(User.username == username).one()
 
        response = self.app.delete(url('user', id=new_user.user_id))
 

	
 
        self.checkSessionFlash(response, 'Successfully deleted user')
 

	
 
    def test_show(self):
 
        response = self.app.get(url('user', id=1))
 

	
 
    def test_edit(self):
 
        self.log_user()
 
        user = User.get_by_username(TEST_USER_ADMIN_LOGIN)
 
        response = self.app.get(url('edit_user', id=user.user_id))
 

	
 
    def test_add_perm_create_repo(self):
 
        self.log_user()
 
        perm_none = Permission.get_by_key('hg.create.none')
 
        perm_create = Permission.get_by_key('hg.create.repository')
 

	
 
        user = UserModel().create_or_update(username='dummy', password='qwe',
 
                                            email='dummy', firstname='a',
 
                                            lastname='b')
 
        Session().commit()
 
        uid = user.user_id
 

	
kallithea/tests/functional/test_my_account.py
Show inline comments
 
@@ -64,125 +64,125 @@ class TestMyAccountController(TestContro
 
        response = self.app.get(url('my_account_emails'))
 
        response.mustcontain('No additional emails specified')
 
        response = self.app.post(url('my_account_emails'),)
 
        self.checkSessionFlash(response, 'Please enter an email address')
 

	
 
    def test_my_account_my_emails_add_remove(self):
 
        self.log_user()
 
        response = self.app.get(url('my_account_emails'))
 
        response.mustcontain('No additional emails specified')
 

	
 
        response = self.app.post(url('my_account_emails'),
 
                                 {'new_email': 'foo@barz.com'})
 

	
 
        response = self.app.get(url('my_account_emails'))
 

	
 
        from kallithea.model.db import UserEmailMap
 
        email_id = UserEmailMap.query()\
 
            .filter(UserEmailMap.user == User.get_by_username(TEST_USER_ADMIN_LOGIN))\
 
            .filter(UserEmailMap.email == 'foo@barz.com').one().email_id
 

	
 
        response.mustcontain('foo@barz.com')
 
        response.mustcontain('<input id="del_email_id" name="del_email_id" type="hidden" value="%s" />' % email_id)
 

	
 
        response = self.app.post(url('my_account_emails'),
 
                                 {'del_email_id': email_id, '_method': 'delete'})
 
        self.checkSessionFlash(response, 'Removed email from user')
 
        response = self.app.get(url('my_account_emails'))
 
        response.mustcontain('No additional emails specified')
 

	
 

	
 
    @parameterized.expand(
 
        [('firstname', {'firstname': 'new_username'}),
 
         ('lastname', {'lastname': 'new_username'}),
 
         ('admin', {'admin': True}),
 
         ('admin', {'admin': False}),
 
         ('extern_type', {'extern_type': 'ldap'}),
 
         ('extern_type', {'extern_type': None}),
 
         #('extern_name', {'extern_name': 'test'}),
 
         #('extern_name', {'extern_name': None}),
 
         ('active', {'active': False}),
 
         ('active', {'active': True}),
 
         ('email', {'email': 'some@email.com'}),
 
        # ('new_password', {'new_password': 'foobar123',
 
        #                   'password_confirmation': 'foobar123'})
 
        ])
 
    def test_my_account_update(self, name, attrs):
 
        usr = fixture.create_user(self.test_user_1, password='qweqwe',
 
                                  email='testme@example.com',
 
                                  extern_type='rhodecode',
 
                                  extern_type='internal',
 
                                  extern_name=self.test_user_1,
 
                                  skip_if_exists=True)
 
        params = usr.get_api_data()  # current user data
 
        user_id = usr.user_id
 
        self.log_user(username=self.test_user_1, password='qweqwe')
 

	
 
        params.update({'password_confirmation': ''})
 
        params.update({'new_password': ''})
 
        params.update({'extern_type': 'rhodecode'})
 
        params.update({'extern_type': 'internal'})
 
        params.update({'extern_name': self.test_user_1})
 

	
 
        params.update(attrs)
 
        response = self.app.post(url('my_account'), params)
 

	
 
        self.checkSessionFlash(response,
 
                               'Your account was updated successfully')
 

	
 
        updated_user = User.get_by_username(self.test_user_1)
 
        updated_params = updated_user.get_api_data()
 
        updated_params.update({'password_confirmation': ''})
 
        updated_params.update({'new_password': ''})
 

	
 
        params['last_login'] = updated_params['last_login']
 
        if name == 'email':
 
            params['emails'] = [attrs['email']]
 
        if name == 'extern_type':
 
            #cannot update this via form, expected value is original one
 
            params['extern_type'] = "rhodecode"
 
            params['extern_type'] = "internal"
 
        if name == 'extern_name':
 
            #cannot update this via form, expected value is original one
 
            params['extern_name'] = str(user_id)
 
        if name == 'active':
 
            #my account cannot deactivate account
 
            params['active'] = True
 
        if name == 'admin':
 
            #my account cannot make you an admin !
 
            params['admin'] = False
 

	
 
        self.assertEqual(params, updated_params)
 

	
 
    def test_my_account_update_err_email_exists(self):
 
        self.log_user()
 

	
 
        new_email = 'test_regular@mail.com'  # already exisitn email
 
        response = self.app.post(url('my_account'),
 
                                params=dict(
 
                                    username='test_admin',
 
                                    new_password='test12',
 
                                    password_confirmation='test122',
 
                                    firstname='NewName',
 
                                    lastname='NewLastname',
 
                                    email=new_email,)
 
                                )
 

	
 
        response.mustcontain('This e-mail address is already taken')
 

	
 
    def test_my_account_update_err(self):
 
        self.log_user('test_regular2', 'test12')
 

	
 
        new_email = 'newmail.pl'
 
        response = self.app.post(url('my_account'),
 
                                 params=dict(
 
                                            username='test_admin',
 
                                            new_password='test12',
 
                                            password_confirmation='test122',
 
                                            firstname='NewName',
 
                                            lastname='NewLastname',
 
                                            email=new_email,))
 

	
 
        response.mustcontain('An email address must contain a single @')
 
        from kallithea.model import validators
 
        msg = validators.ValidUsername(edit=False, old_data={})\
 
                ._messages['username_exists']
 
        msg = h.html_escape(msg % {'username': 'test_admin'})
 
        response.mustcontain(u"%s" % msg)
 

	
0 comments (0 inline, 0 general)