Mercurial > kallithea
changeset 5343:39bac9410169
auth: make the auth module decide which fields are editable by admin and user
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Fri, 31 Jul 2015 15:44:07 +0200 |
parents | 40cfdd004bf6 |
children | 0a0595b15c6c |
files | kallithea/controllers/admin/my_account.py kallithea/controllers/admin/users.py kallithea/lib/auth_modules/__init__.py kallithea/lib/auth_modules/auth_container.py kallithea/lib/auth_modules/auth_crowd.py kallithea/lib/auth_modules/auth_internal.py kallithea/lib/auth_modules/auth_ldap.py kallithea/lib/auth_modules/auth_pam.py kallithea/templates/admin/my_account/my_account_profile.html kallithea/templates/admin/users/user_edit_profile.html |
diffstat | 10 files changed, 51 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/controllers/admin/my_account.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/controllers/admin/my_account.py Fri Jul 31 15:44:07 2015 +0200 @@ -37,6 +37,7 @@ from kallithea import EXTERN_TYPE_INTERNAL from kallithea.lib import helpers as h +from kallithea.lib import auth_modules from kallithea.lib.auth import LoginRequired, NotAnonymous, AuthUser from kallithea.lib.base import BaseController, render from kallithea.lib.utils2 import generate_api_key, safe_int @@ -100,6 +101,8 @@ self.__load_data() c.perm_user = AuthUser(user_id=self.authuser.user_id) c.ip_addr = self.ip_addr + managed_fields = auth_modules.get_managed_fields(c.user) + c.readonly = lambda n: 'readonly' if n in managed_fields else None defaults = c.user.get_dict() update = False @@ -115,12 +118,8 @@ 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.user.extern_type != EXTERN_TYPE_INTERNAL: - # forbid updating username for external accounts - # TODO: also skip username (and email etc) if self registration not enabled - skip_attrs.append('username') + 'new_password', 'password_confirmation', + ] + managed_fields UserModel().update(self.authuser.user_id, form_result, skip_attrs=skip_attrs)
--- a/kallithea/controllers/admin/users.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/controllers/admin/users.py Fri Jul 31 15:44:07 2015 +0200 @@ -42,7 +42,6 @@ from kallithea.lib import helpers as h from kallithea.lib.auth import LoginRequired, HasPermissionAllDecorator, \ AuthUser -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 @@ -175,11 +174,8 @@ 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.user.extern_type != kallithea.EXTERN_TYPE_INTERNAL: - # forbid updating username for external accounts - skip_attrs.append('username') + skip_attrs = ['extern_type', 'extern_name', + ] + auth_modules.get_managed_fields(c.user) user_model.update(id, form_result, skip_attrs=skip_attrs) usr = form_result['username'] @@ -249,6 +245,8 @@ c.active = 'profile' c.perm_user = AuthUser(user_id=id) c.ip_addr = self.ip_addr + managed_fields = auth_modules.get_managed_fields(c.user) + c.readonly = lambda n: 'readonly' if n in managed_fields else None defaults = c.user.get_dict() return htmlfill.render(
--- a/kallithea/lib/auth_modules/__init__.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/lib/auth_modules/__init__.py Fri Jul 31 15:44:07 2015 +0200 @@ -416,3 +416,16 @@ log.warning("User `%s` failed to authenticate against %s" % (username, plugin.__module__)) return None + +def get_managed_fields(user): + """return list of fields that are managed by the user's auth source, usually some of + 'username', 'firstname', 'lastname', 'email', 'active', 'password' + """ + auth_plugins = Setting.get_auth_plugins() + for module in auth_plugins: + log.debug('testing %s (%s) with auth plugin %s', user, user.extern_type, module) + plugin = loadplugin(module) + if plugin.name == user.extern_type: + return plugin.get_managed_fields() + log.error('no auth plugin %s found for %s', user.extern_type, user) + return [] # TODO: Fail badly instead of allowing everything to be edited?
--- a/kallithea/lib/auth_modules/auth_container.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/lib/auth_modules/auth_container.py Fri Jul 31 15:44:07 2015 +0200 @@ -190,3 +190,6 @@ log.info('user `%s` authenticated correctly' % user_data['username']) return user_data + + def get_managed_fields(self): + return ['username', 'password']
--- a/kallithea/lib/auth_modules/auth_crowd.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/lib/auth_modules/auth_crowd.py Fri Jul 31 15:44:07 2015 +0200 @@ -229,7 +229,7 @@ 'email': crowd_user["email"] or email, 'admin': admin, 'active': active, - 'active_from_extern': crowd_user.get('active'), + 'active_from_extern': crowd_user.get('active'), # ??? 'extern_name': crowd_user["name"], } @@ -240,3 +240,6 @@ log.debug("Final crowd user object: \n%s" % (formatted_json(user_data))) log.info('user %s authenticated correctly' % user_data['username']) return user_data + + def get_managed_fields(self): + return ['username', 'firstname', 'lastname', 'email', 'password']
--- a/kallithea/lib/auth_modules/auth_internal.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/lib/auth_modules/auth_internal.py Fri Jul 31 15:44:07 2015 +0200 @@ -97,3 +97,7 @@ else: log.warning('user %s tried auth but is disabled' % username) return None + + def get_managed_fields(self): + # Note: 'username' should only be editable (at least for user) if self registration is enabled + return []
--- a/kallithea/lib/auth_modules/auth_ldap.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/lib/auth_modules/auth_ldap.py Fri Jul 31 15:44:07 2015 +0200 @@ -359,3 +359,6 @@ except (Exception,): log.error(traceback.format_exc()) return None + + def get_managed_fields(self): + return ['username', 'firstname', 'lastname', 'email', 'password']
--- a/kallithea/lib/auth_modules/auth_pam.py Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/lib/auth_modules/auth_pam.py Fri Jul 31 15:44:07 2015 +0200 @@ -136,3 +136,6 @@ log.debug("pamuser: \n%s" % formatted_json(user_data)) log.info('user %s authenticated correctly' % user_data['username']) return user_data + + def get_managed_fields(self): + return ['username', 'password']
--- a/kallithea/templates/admin/my_account/my_account_profile.html Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/templates/admin/my_account/my_account_profile.html Fri Jul 31 15:44:07 2015 +0200 @@ -19,10 +19,8 @@ </div> </div> - <% readonly = None %> <div class="fields"> %if c.user.extern_type != c.EXTERN_TYPE_INTERNAL: - <% readonly = "readonly" %> <strong>${_('Your user is in an external Source of Record; some details cannot be managed here')}.</strong> %endif <div class="field"> @@ -30,7 +28,7 @@ <label for="username">${_('Username')}:</label> </div> <div class="input"> - ${h.text('username',class_='medium', readonly=readonly)} + ${h.text('username',class_='medium', readonly=c.readonly('username'))} </div> </div> @@ -39,7 +37,7 @@ <label for="name">${_('First Name')}:</label> </div> <div class="input"> - ${h.text('firstname',class_="medium")} + ${h.text('firstname',class_="medium", readonly=c.readonly('firstname'))} </div> </div> @@ -48,7 +46,7 @@ <label for="lastname">${_('Last Name')}:</label> </div> <div class="input"> - ${h.text('lastname',class_="medium")} + ${h.text('lastname',class_="medium", readonly=c.readonly('lastname'))} </div> </div> @@ -57,8 +55,7 @@ <label for="email">${_('Email')}:</label> </div> <div class="input"> - ## we should be able to edit email ! - ${h.text('email',class_="medium")} + ${h.text('email',class_="medium", readonly=c.readonly('email'))} </div> </div>
--- a/kallithea/templates/admin/users/user_edit_profile.html Fri Jul 31 15:44:07 2015 +0200 +++ b/kallithea/templates/admin/users/user_edit_profile.html Fri Jul 31 15:44:07 2015 +0200 @@ -17,11 +17,9 @@ %endif </div> </div> - <% readonly = None %> <div class="fields"> %if c.user.extern_type != c.EXTERN_TYPE_INTERNAL: <div class="field"> - <% readonly = "readonly" %> <strong>${_('This user is in an external Source of Record (%s); some details cannot be managed here.' % c.user.extern_type)}.</strong> </div> %endif @@ -31,7 +29,7 @@ <label for="username">${_('Username')}:</label> </div> <div class="input"> - ${h.text('username',class_='medium', readonly=readonly)} + ${h.text('username',class_='medium', readonly=c.readonly('username'))} </div> </div> @@ -40,7 +38,7 @@ <label for="email">${_('Email')}:</label> </div> <div class="input"> - ${h.text('email',class_='medium')} + ${h.text('email',class_='medium', readonly=c.readonly('email'))} </div> </div> @@ -67,7 +65,7 @@ <label for="new_password">${_('New password')}:</label> </div> <div class="input"> - ${h.password('new_password',class_='medium',readonly=readonly)} + ${h.password('new_password',class_='medium',readonly=c.readonly('password'))} </div> </div> @@ -76,7 +74,7 @@ <label for="password_confirmation">${_('New password confirmation')}:</label> </div> <div class="input"> - ${h.password('password_confirmation',class_="medium",readonly=readonly)} + ${h.password('password_confirmation',class_="medium",readonly=c.readonly('password'))} </div> </div> @@ -85,7 +83,7 @@ <label for="firstname">${_('First Name')}:</label> </div> <div class="input"> - ${h.text('firstname',class_='medium')} + ${h.text('firstname',class_='medium', readonly=c.readonly('firstname'))} </div> </div> @@ -94,7 +92,7 @@ <label for="lastname">${_('Last Name')}:</label> </div> <div class="input"> - ${h.text('lastname',class_='medium')} + ${h.text('lastname',class_='medium', readonly=c.readonly('lastname'))} </div> </div> @@ -103,7 +101,7 @@ <label for="active">${_('Active')}:</label> </div> <div class="checkboxes"> - ${h.checkbox('active',value=True)} + ${h.checkbox('active',value=True, readonly=c.readonly('active'))} </div> </div> @@ -112,7 +110,7 @@ <label for="admin">${_('Admin')}:</label> </div> <div class="checkboxes"> - ${h.checkbox('admin',value=True)} + ${h.checkbox('admin',value=True, readonly=c.readonly('admin'))} </div> </div>