def __init__(self, user_id=None, dbuser=None, is_external_auth=False): self.is_external_auth = is_external_auth # container auth - don't show logout option # These attributes will be overridden below if the requested user is # found or anonymous access (using the default user) is enabled. self.user_id = None self.username = None self.api_key = None self.name = '' self.lastname = '' self.email = '' self.admin = False # Look up database user, if necessary. if user_id is not None: assert dbuser is None log.debug('Auth User lookup by USER ID %s', user_id) dbuser = UserModel().get(user_id) assert dbuser is not None else: assert dbuser is not None log.debug('Auth User lookup by database user %s', dbuser) log.debug('filling %s data', dbuser) self.is_anonymous = dbuser.is_default_user if dbuser.is_default_user and not dbuser.active: self.username = '******' self.is_default_user = False else: # copy non-confidential database fields from a `db.User` to this `AuthUser`. for k, v in dbuser.get_dict().items(): assert k not in ['api_keys', 'permissions'] setattr(self, k, v) self.is_default_user = dbuser.is_default_user log.debug('Auth User is now %s', self)
def test_create_and_remove(self): usr = UserModel().create_or_update(username=u'test_user', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') Session().commit() assert User.get_by_username(u'test_user') == usr assert User.get_by_username(u'test_USER', case_insensitive=True) == usr # User.get_by_username without explicit request for case insensitivty # will use database case sensitivity. The following will thus return # None on for example PostgreSQL but find test_user on MySQL - we are # fine with leaving that as undefined as long as it doesn't crash. User.get_by_username(u'test_USER', case_insensitive=False) # make user group user_group = fixture.create_user_group(u'some_example_group') Session().commit() UserGroupModel().add_user_to_group(user_group, usr) Session().commit() assert UserGroup.get(user_group.users_group_id) == user_group assert UserGroupMember.query().count() == 1 UserModel().delete(usr.user_id) Session().commit() assert UserGroupMember.query().all() == []
def test_inactive_user_group_does_not_affect_global_permissions_inverse( self): # Issue #138: Inactive User Groups affecting permissions # Add user to inactive user group, set specific permissions on user # group and disable inherit-from-default. User permissions should still # inherit from default. self.ug1 = fixture.create_user_group(u'G1') self.ug1.inherit_default_permissions = False user_group_model = UserGroupModel() user_group_model.add_user_to_group(self.ug1, self.u1) user_group_model.update(self.ug1, {'users_group_active': False}) # disable fork and create on user group user_group_model.revoke_perm(self.ug1, perm='hg.create.repository') user_group_model.grant_perm(self.ug1, perm='hg.create.none') user_group_model.revoke_perm(self.ug1, perm='hg.fork.repository') user_group_model.grant_perm(self.ug1, perm='hg.fork.none') user_model = UserModel() # enable fork and create on default user usr = '******' user_model.revoke_perm(usr, 'hg.create.none') user_model.grant_perm(usr, 'hg.create.repository') user_model.revoke_perm(usr, 'hg.fork.none') user_model.grant_perm(usr, 'hg.fork.repository') Session().commit() u1_auth = AuthUser(user_id=self.u1.user_id) assert u1_auth.permissions['global'] == set([ 'hg.create.repository', 'hg.fork.repository', 'hg.register.manual_activate', 'hg.extern_activate.auto', 'repository.read', 'group.read', 'usergroup.read', 'hg.create.write_on_repogroup.true' ])
def setup_method(self, method): Session.remove() u1 = UserModel().create_or_update(username=u'u1', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') Session().commit() self.u1 = u1.user_id u2 = UserModel().create_or_update(username=u'u2', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u2', lastname=u'u3') Session().commit() self.u2 = u2.user_id u3 = UserModel().create_or_update(username=u'u3', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u3', lastname=u'u3') Session().commit() self.u3 = u3.user_id self.remove_all_notifications() assert [] == Notification.query().all() assert [] == UserNotification.query().all()
def create(self): c.default_extern_type = User.DEFAULT_AUTH_TYPE c.default_extern_name = '' user_model = UserModel() user_form = UserForm()() try: form_result = user_form.to_python(dict(request.POST)) user = user_model.create(form_result) action_logger(request.authuser, 'admin_created_user:%s' % user.username, None, request.ip_addr) h.flash(_('Created user %s') % user.username, category='success') Session().commit() except formencode.Invalid as errors: return htmlfill.render( render('admin/users/user_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except UserCreationError as 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') raise HTTPFound(location=url('edit_user', id=user.user_id))
def test_ip_restriction_hg(self, webserver): user_model = UserModel() try: user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32') Session().commit() clone_url = webserver.repo_url(HG_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute('hg clone', clone_url, _get_tmp_dir(), ignoreReturnCode=True) assert 'abort: HTTP Error 403: Forbidden' in stderr finally: #release IP restrictions for ip in UserIpMap.query(): UserIpMap.delete(ip.ip_id) Session().commit() # IP permissions are cached, need to wait for the cache in the server process to expire time.sleep(1.5) clone_url = webserver.repo_url(HG_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute('hg clone', clone_url, _get_tmp_dir()) assert 'requesting all changes' in stdout assert 'adding changesets' in stdout assert 'adding manifests' in stdout assert 'adding file changes' in stdout assert stderr == ''
def test_extra_email_map(self): usr = UserModel().create_or_update(username=u'test_user', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') Session().commit() m = UserEmailMap() m.email = u'*****@*****.**' m.user = usr Session().add(m) Session().commit() u = User.get_by_email(email='*****@*****.**') self.assertEqual(usr.user_id, u.user_id) self.assertEqual(usr.username, u.username) u = User.get_by_email(email='*****@*****.**') self.assertEqual(usr.user_id, u.user_id) self.assertEqual(usr.username, u.username) u = User.get_by_email(email='*****@*****.**') self.assertEqual(None, u) UserModel().delete(usr.user_id) Session().commit()
def test_extra_email_map(self): usr = UserModel().create_or_update(username=u'test_user', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') Session().commit() m = UserEmailMap() m.email = u'*****@*****.**' m.user = usr Session().add(m) Session().commit() u = User.get_by_email(email='*****@*****.**') assert usr.user_id == u.user_id assert usr.username == u.username u = User.get_by_email(email='*****@*****.**') assert usr.user_id == u.user_id assert usr.username == u.username u = User.get_by_email(email='*****@*****.**') assert usr.user_id == u.user_id assert usr.username == u.username u = User.get_by_email(email='*****@*****.**') assert None == u u = User.get_by_email(email='*****@*****.**') assert None == u u = User.get_by_email(email='*****@*****.**') assert None == u UserModel().delete(usr.user_id) Session().commit()
def my_account_emails_delete(self): email_id = request.POST.get('del_email_id') user_model = UserModel() user_model.delete_extra_email(self.authuser.user_id, email_id) Session().commit() h.flash(_("Removed email from user"), category='success') return redirect(url('my_account_emails'))
def test_ip_restriction_git(self, webserver): user_model = UserModel() try: user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32') Session().commit() clone_url = webserver.repo_url(GIT_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute( 'git clone', clone_url, _get_tmp_dir(), ignoreReturnCode=True) # The message apparently changed in Git 1.8.3, so match it loosely. assert re.search(r'\b403\b', stderr) finally: #release IP restrictions for ip in UserIpMap.query(): UserIpMap.delete(ip.ip_id) Session().commit() # IP permissions are cached, need to wait for the cache in the server process to expire time.sleep(1.5) clone_url = webserver.repo_url(GIT_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute( 'git clone', clone_url, _get_tmp_dir()) assert 'Cloning into' in stdout + stderr assert stderr == '' or stdout == ''
def test_ip_restriction_hg(self, webserver): user_model = UserModel() try: user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32') Session().commit() clone_url = webserver.repo_url(HG_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute( 'hg clone', clone_url, _get_tmp_dir(), ignoreReturnCode=True) assert 'abort: HTTP Error 403: Forbidden' in stderr finally: #release IP restrictions for ip in UserIpMap.query(): UserIpMap.delete(ip.ip_id) Session().commit() # IP permissions are cached, need to wait for the cache in the server process to expire time.sleep(1.5) clone_url = webserver.repo_url(HG_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute( 'hg clone', clone_url, _get_tmp_dir()) assert 'requesting all changes' in stdout assert 'adding changesets' in stdout assert 'adding manifests' in stdout assert 'adding file changes' in stdout assert stderr == ''
def my_account_emails_delete(self): email_id = request.POST.get('del_email_id') user_model = UserModel() user_model.delete_extra_email(self.authuser.user_id, email_id) Session().commit() h.flash(_("Removed email from user"), category='success') raise HTTPFound(location=url('my_account_emails'))
def test_delete_ips(self, auto_clear_ip_permissions): self.log_user() default_user_id = User.get_default_user().user_id ## first add new_ip = '127.0.0.0/24' with test_context(self.app): user_model = UserModel() ip_obj = user_model.add_extra_ip(default_user_id, new_ip) Session().commit() ## double check that add worked # IP permissions are cached, need to invalidate this cache explicitly invalidate_all_caches() self.app.get(url('admin_permissions_ips'), status=302) # REMOTE_ADDR must match 127.0.0.0/24 response = self.app.get(url('admin_permissions_ips'), extra_environ={'REMOTE_ADDR': '127.0.0.1'}) response.mustcontain('127.0.0.0/24') response.mustcontain('127.0.0.0 - 127.0.0.255') ## now delete response = self.app.post(url('edit_user_ips_delete', id=default_user_id), params=dict(del_ip_id=ip_obj.ip_id, _authentication_token=self.authentication_token()), extra_environ={'REMOTE_ADDR': '127.0.0.1'}) # IP permissions are cached, need to invalidate this cache explicitly invalidate_all_caches() response = self.app.get(url('admin_permissions_ips')) response.mustcontain('All IP addresses are allowed') response.mustcontain(no=['127.0.0.0/24']) response.mustcontain(no=['127.0.0.0 - 127.0.0.255'])
def test_inactive_user_group_does_not_affect_global_permissions(self): # Add user to inactive user group, set specific permissions on user # group and and verify it really is inactive. self.ug1 = fixture.create_user_group('G1') user_group_model = UserGroupModel() user_group_model.add_user_to_group(self.ug1, self.u1) user_group_model.update(self.ug1, {'users_group_active': False}) # enable fork and create on user group user_group_model.revoke_perm(self.ug1, perm='hg.create.none') user_group_model.grant_perm(self.ug1, perm='hg.create.repository') user_group_model.revoke_perm(self.ug1, perm='hg.fork.none') user_group_model.grant_perm(self.ug1, perm='hg.fork.repository') user_model = UserModel() # disable fork and create on default user usr = '******' user_model.revoke_perm(usr, 'hg.create.repository') user_model.grant_perm(usr, 'hg.create.none') user_model.revoke_perm(usr, 'hg.fork.repository') user_model.grant_perm(usr, 'hg.fork.none') Session().commit() u1_auth = AuthUser(user_id=self.u1.user_id) assert u1_auth.permissions['global'] == set([ 'hg.create.none', 'hg.fork.none', 'hg.register.manual_activate', 'hg.extern_activate.auto', 'repository.read', 'group.read', 'usergroup.read', 'hg.create.write_on_repogroup.true' ])
def create(self): """POST /users: Create a new item""" # url('users') c.default_extern_type = auth_internal.KallitheaAuthPlugin.name c.default_extern_name = auth_internal.KallitheaAuthPlugin.name user_model = UserModel() user_form = UserForm()() try: form_result = user_form.to_python(dict(request.POST)) user = 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(h.literal(_('Created user %s') % h.link_to(h.escape(usr), url('edit_user', id=user.user_id))), category='success') Session().commit() except formencode.Invalid as errors: return htmlfill.render( render('admin/users/user_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except UserCreationError as 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') raise HTTPFound(location=url('users'))
def setup_method(self, method): Session.remove() u1 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u1', lastname='u1') Session().commit() self.u1 = u1.user_id u2 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u2', lastname='u3') Session().commit() self.u2 = u2.user_id u3 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u3', lastname='u3') Session().commit() self.u3 = u3.user_id
def __init__(self, methodName='runTest'): Session.remove() self.u1 = UserModel().create_or_update(username=u'u1', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') Session().commit() self.u1 = self.u1.user_id self.u2 = UserModel().create_or_update(username=u'u2', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u2', lastname=u'u3') Session().commit() self.u2 = self.u2.user_id self.u3 = UserModel().create_or_update(username=u'u3', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u3', lastname=u'u3') Session().commit() self.u3 = self.u3.user_id super(TestNotifications, self).__init__(methodName=methodName)
def test_delete_ips(self, auto_clear_ip_permissions): self.log_user() default_user_id = User.get_default_user().user_id ## first add new_ip = '127.0.0.0/24' with test_context(self.app): user_model = UserModel() ip_obj = user_model.add_extra_ip(default_user_id, new_ip) Session().commit() ## double check that add worked # IP permissions are cached, need to invalidate this cache explicitly invalidate_all_caches() self.app.get(url('admin_permissions_ips'), status=302) # REMOTE_ADDR must match 127.0.0.0/24 response = self.app.get(url('admin_permissions_ips'), extra_environ={'REMOTE_ADDR': '127.0.0.1'}) response.mustcontain('127.0.0.0/24') response.mustcontain('127.0.0.0 - 127.0.0.255') ## now delete response = self.app.post( url('edit_user_ips_delete', id=default_user_id), params=dict(del_ip_id=ip_obj.ip_id, _authentication_token=self.authentication_token()), extra_environ={'REMOTE_ADDR': '127.0.0.1'}) # IP permissions are cached, need to invalidate this cache explicitly invalidate_all_caches() response = self.app.get(url('admin_permissions_ips')) response.mustcontain('All IP addresses are allowed') response.mustcontain(no=['127.0.0.0/24']) response.mustcontain(no=['127.0.0.0 - 127.0.0.255'])
def delete_email(self, id): user = self._get_user_or_raise_if_default(id) email_id = request.POST.get('del_email_id') user_model = UserModel() user_model.delete_extra_email(id, email_id) Session().commit() h.flash(_("Removed email from user"), category='success') raise HTTPFound(location=url('edit_user_emails', id=id))
def teardown_method(self, method): perm = Permission.query().all() for p in perm: UserModel().revoke_perm(self.u1, p) UserModel().delete(self.u1) Session().commit() Session.remove()
def delete_email(self, id): """DELETE /user_emails_delete/id: Delete an existing item""" # url('user_emails_delete', id=ID, method='delete') email_id = request.POST.get('del_email_id') user_model = UserModel() user_model.delete_extra_email(id, email_id) Session().commit() h.flash(_("Removed email from user"), category='success') return redirect(url('edit_user_emails', id=id))
def delete_email(self, id): """DELETE /user_emails_delete/id: Delete an existing item""" # url('user_emails_delete', id=ID, method='delete') user = self._get_user_or_raise_if_default(id) email_id = request.POST.get('del_email_id') user_model = UserModel() user_model.delete_extra_email(id, email_id) Session().commit() h.flash(_("Removed email from user"), category='success') raise HTTPFound(location=url('edit_user_emails', id=id))
def test_revoke_perm(self): perm = Permission.query().all()[0] UserModel().grant_perm(self.u1, perm) Session().commit() self.assertEqual(UserModel().has_perm(self.u1, perm), True) #revoke UserModel().revoke_perm(self.u1, perm) Session().commit() self.assertEqual(UserModel().has_perm(self.u1, perm), False)
def delete_ip(self, id): ip_id = request.POST.get('del_ip_id') user_model = UserModel() user_model.delete_extra_ip(id, ip_id) Session().commit() h.flash(_("Removed IP address from user whitelist"), category='success') if 'default_user' in request.POST: raise HTTPFound(location=url('admin_permissions_ips')) raise HTTPFound(location=url('edit_user_ips', id=id))
def test_revoke_perm(self): perm = Permission.query().all()[0] UserModel().grant_perm(self.u1, perm) Session().commit() assert UserModel().has_perm(self.u1, perm) == True #revoke UserModel().revoke_perm(self.u1, perm) Session().commit() assert UserModel().has_perm(self.u1, perm) == False
def test_inactive_user_group_does_not_affect_global_permissions_inverse(self): # Issue #138: Inactive User Groups affecting permissions # Add user to inactive user group, set specific permissions on user # group and disable inherit-from-default. User permissions should still # inherit from default. self.ug1 = fixture.create_user_group(u'G1') self.ug1.inherit_default_permissions = False user_group_model = UserGroupModel() user_group_model.add_user_to_group(self.ug1, self.u1) user_group_model.update(self.ug1, {'users_group_active': False}) # disable fork and create on user group user_group_model.revoke_perm(self.ug1, perm='hg.create.repository') user_group_model.grant_perm(self.ug1, perm='hg.create.none') user_group_model.revoke_perm(self.ug1, perm='hg.fork.repository') user_group_model.grant_perm(self.ug1, perm='hg.fork.none') user_model = UserModel() # enable fork and create on default user usr = '******' user_model.revoke_perm(usr, 'hg.create.none') user_model.grant_perm(usr, 'hg.create.repository') user_model.revoke_perm(usr, 'hg.fork.none') user_model.grant_perm(usr, 'hg.fork.repository') Session().commit() u1_auth = AuthUser(user_id=self.u1.user_id) self.assertEqual(u1_auth.permissions['global'], set(['hg.create.repository', 'hg.fork.repository', 'hg.register.manual_activate', 'hg.extern_activate.auto', 'repository.read', 'group.read', 'usergroup.read', 'hg.create.write_on_repogroup.true']))
def delete_ip(self, id): """DELETE /user_ips_delete/id: Delete an existing item""" # url('user_ips_delete', id=ID, method='delete') ip_id = request.POST.get('del_ip_id') user_model = UserModel() user_model.delete_extra_ip(id, ip_id) Session().commit() h.flash(_("Removed ip address from user whitelist"), category='success') if 'default_user' in request.POST: return redirect(url('admin_permissions_ips')) return redirect(url('edit_user_ips', id=id))
def add_ip(self, id): """POST /user_ips:Add an existing item""" # url('user_ips', id=ID, method='put') ip = request.POST.get('new_ip') user_model = UserModel() try: user_model.add_extra_ip(id, ip) Session().commit() h.flash(_("Added ip %s to user whitelist") % ip, category='success') except formencode.Invalid, error: msg = error.error_dict['ip'] h.flash(msg, category='error')
def add_email(self, id): """POST /user_emails:Add an existing item""" # url('user_emails', id=ID, method='put') email = request.POST.get('new_email') user_model = UserModel() try: user_model.add_extra_email(id, email) Session().commit() h.flash(_("Added email %s to user") % email, category='success') except formencode.Invalid, error: msg = error.error_dict['email'] h.flash(msg, category='error')
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_NAME, password=str(uuid.uuid1())[:20], email='*****@*****.**', firstname='Anonymous', lastname='User') # based on configuration options activate/deactivate this user which # controls anonymous access if self.cli_args.get('public_access') is False: log.info('Public access disabled') user.active = False Session().commit()
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='*****@*****.**', firstname=u'Anonymous', lastname=u'User') # based on configuration options activate/deactivate this user which # controls anonymous access if self.cli_args.get('public_access') is False: log.info('Public access disabled') user.active = False Session().commit()
def test_inherit_sad_permissions_from_default_user(self): user_model = UserModel() # disable fork and create on default user usr = '******' user_model.revoke_perm(usr, 'hg.create.repository') user_model.grant_perm(usr, 'hg.create.none') user_model.revoke_perm(usr, 'hg.fork.repository') user_model.grant_perm(usr, 'hg.fork.none') Session().commit() u1_auth = AuthUser(user_id=self.u1.user_id) # this user will have inherited permissions from default user assert u1_auth.permissions['global'] == set([ 'hg.create.none', 'hg.fork.none', 'hg.register.manual_activate', 'hg.extern_activate.auto', 'repository.read', 'group.read', 'usergroup.read', 'hg.create.write_on_repogroup.true' ])
def test_delete_ip(self, auto_clear_ip_permissions): self.log_user() user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN) user_id = user.user_id ip = '127.0.0.1/32' ip_range = '127.0.0.1 - 127.0.0.1' with test_context(self.app): new_ip = UserModel().add_extra_ip(user_id, ip) Session().commit() new_ip_id = new_ip.ip_id response = self.app.get(base.url('edit_user_ips', id=user_id)) response.mustcontain(ip) response.mustcontain(ip_range) self.app.post( base.url('edit_user_ips_delete', id=user_id), params=dict( del_ip_id=new_ip_id, _session_csrf_secret_token=self.session_csrf_secret_token())) response = self.app.get(base.url('edit_user_ips', id=user_id)) response.mustcontain('All IP addresses are allowed') response.mustcontain(no=[ip]) response.mustcontain(no=[ip_range])
def my_account_password(self): c.active = 'password' self.__load_data() managed_fields = auth_modules.get_managed_fields(c.user) c.can_change_password = '******' not in managed_fields if request.POST and c.can_change_password: _form = PasswordChangeForm(request.authuser.username)() try: form_result = _form.to_python(request.POST) UserModel().update(request.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", force_defaults=False) except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during update of user password'), category='error') return render('admin/my_account/my_account.html')
def test_additional_email_as_main(self): usr = UserModel().create_or_update(username=u'test_user', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') Session().commit() with pytest.raises(AttributeError): m = UserEmailMap() m.email = u'*****@*****.**' m.user = usr Session().add(m) Session().commit() UserModel().delete(usr.user_id) Session().commit()
def test_no_permissions_to_fork(self): usr = self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)['user_id'] user_model = UserModel() user_model.revoke_perm(usr, 'hg.fork.repository') user_model.grant_perm(usr, 'hg.fork.none') u = UserModel().get(usr) u.inherit_default_permissions = False Session().commit() # try create a fork repo_name = self.REPO self.app.post(url(controller='forks', action='fork_create', repo_name=repo_name), {}, status=403)
def add_email(self, id): user = self._get_user_or_raise_if_default(id) email = request.POST.get('new_email') user_model = UserModel() try: user_model.add_extra_email(id, email) Session().commit() h.flash(_("Added email %s to user") % email, category='success') except formencode.Invalid as error: msg = error.error_dict['email'] h.flash(msg, category='error') except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during email saving'), category='error') raise HTTPFound(location=url('edit_user_emails', id=id))
def tearDown(self): if hasattr(self, 'test_repo'): RepoModel().delete(repo=self.test_repo) UserModel().delete(self.u1) UserModel().delete(self.u2) UserModel().delete(self.u3) UserModel().delete(self.a1) if hasattr(self, 'g1'): RepoGroupModel().delete(self.g1.group_id) if hasattr(self, 'g2'): RepoGroupModel().delete(self.g2.group_id) if hasattr(self, 'ug1'): UserGroupModel().delete(self.ug1, force=True) Session().commit()
def auto_clear_ip_permissions(): """Fixture that provides nothing but clearing IP permissions upon test exit. This clearing is needed to avoid other test failing to make fake http accesses.""" yield # cleanup user_model = UserModel() user_ids = [] user_ids.append(User.get_default_user().user_id) user_ids.append(User.get_by_username(TEST_USER_REGULAR_LOGIN).user_id) for user_id in user_ids: for ip in UserIpMap.query().filter(UserIpMap.user_id == user_id): user_model.delete_extra_ip(user_id, ip.ip_id) # IP permissions are cached, need to invalidate this cache explicitly invalidate_all_caches()
def edit_perms(self, id): c.user = self._get_user_or_raise_if_default(id) c.active = 'perms' c.perm_user = AuthUser(dbuser=c.user) umodel = UserModel() defaults = c.user.get_dict() defaults.update({ 'create_repo_perm': umodel.has_perm(c.user, 'hg.create.repository'), 'create_user_group_perm': umodel.has_perm(c.user, 'hg.usergroup.create.true'), 'fork_repo_perm': umodel.has_perm(c.user, 'hg.fork.repository'), }) return htmlfill.render( render('admin/users/user_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def add_ip(self, id): ip = request.POST.get('new_ip') user_model = UserModel() try: user_model.add_extra_ip(id, ip) Session().commit() h.flash(_("Added IP address %s to user whitelist") % ip, category='success') except formencode.Invalid as error: msg = error.error_dict['ip'] h.flash(msg, category='error') except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred while adding IP address'), category='error') if 'default_user' in request.POST: raise HTTPFound(location=url('admin_permissions_ips')) raise HTTPFound(location=url('edit_user_ips', id=id))
def __init__(self, user_id=None, dbuser=None, authenticating_api_key=None, is_external_auth=False): self.is_authenticated = False self.is_external_auth = is_external_auth self.authenticating_api_key = authenticating_api_key user_model = UserModel() self._default_user = User.get_default_user(cache=True) # These attributes will be overridden by fill_data, below, unless the # requested user cannot be found and the default anonymous user is # not enabled. self.user_id = None self.username = None self.api_key = None self.name = '' self.lastname = '' self.email = '' self.admin = False self.inherit_default_permissions = False # Look up database user, if necessary. if user_id is not None: log.debug('Auth User lookup by USER ID %s', user_id) dbuser = user_model.get(user_id) else: # Note: dbuser is allowed to be None. log.debug('Auth User lookup by database user %s', dbuser) is_user_loaded = self._fill_data(dbuser) # If user cannot be found, try falling back to anonymous. if not is_user_loaded: is_user_loaded = self._fill_data(self._default_user) self.is_default_user = (self.user_id == self._default_user.user_id) self.is_anonymous = not is_user_loaded or self.is_default_user if not self.username: self.username = '******' log.debug('Auth User is now %s', self)
def test_ip_restriction_git(self): user_model = UserModel() try: user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32') Session().commit() clone_url = _construct_url(GIT_REPO) stdout, stderr = Command('/tmp').execute('git clone', clone_url) msg = ("""The requested URL returned error: 403""") assert msg in stderr finally: #release IP restrictions for ip in UserIpMap.getAll(): UserIpMap.delete(ip.ip_id) Session().commit() time.sleep(2) clone_url = _construct_url(GIT_REPO) stdout, stderr = Command('/tmp').execute('git clone', clone_url) assert 'Cloning into' in stdout + stderr assert stderr == '' or stdout == ''
def test_inherited_permissions_from_default_on_user_disabled(self): user_model = UserModel() # disable fork and create on default user usr = '******' user_model.revoke_perm(usr, 'hg.create.repository') user_model.grant_perm(usr, 'hg.create.none') user_model.revoke_perm(usr, 'hg.fork.repository') user_model.grant_perm(usr, 'hg.fork.none') # make sure inherit flag is turned on self.u1.inherit_default_permissions = True Session().commit() u1_auth = AuthUser(user_id=self.u1.user_id) # this user will have inherited permissions from default user assert u1_auth.permissions['global'] == set(['hg.create.none', 'hg.fork.none', 'hg.register.manual_activate', 'hg.extern_activate.auto', 'repository.read', 'group.read', 'usergroup.read', 'hg.create.write_on_repogroup.true'])
def edit_perms(self, id): c.user = User.get_or_404(id) if c.user.username == User.DEFAULT_USER: h.flash(_("You can't edit this user"), category='warning') return redirect(url('users')) c.active = 'perms' c.perm_user = AuthUser(user_id=id, ip_addr=self.ip_addr) umodel = UserModel() defaults = c.user.get_dict() defaults.update({ 'create_repo_perm': umodel.has_perm(c.user, 'hg.create.repository'), 'create_user_group_perm': umodel.has_perm(c.user, 'hg.usergroup.create.true'), 'fork_repo_perm': umodel.has_perm(c.user, 'hg.fork.repository'), }) return htmlfill.render( render('admin/users/user_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def create(self): """POST /users: Create a new item""" # url('users') c.default_extern_type = auth_modules.auth_internal.KallitheaAuthPlugin.name user_model = UserModel() user_form = UserForm()() try: form_result = user_form.to_python(dict(request.POST)) user = 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(h.literal(_('Created user %s') % h.link_to(h.escape(usr), url('edit_user', id=user.user_id))), 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", force_defaults=False)
def test_ip_restriction_git(self, webserver): user_model = UserModel() try: user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32') Session().commit() clone_url = webserver.repo_url(GIT_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute('git clone', clone_url, _get_tmp_dir(), ignoreReturnCode=True) # The message apparently changed in Git 1.8.3, so match it loosely. assert re.search(r'\b403\b', stderr) finally: #release IP restrictions for ip in UserIpMap.query(): UserIpMap.delete(ip.ip_id) Session().commit() # IP permissions are cached, need to wait for the cache in the server process to expire time.sleep(1.5) clone_url = webserver.repo_url(GIT_REPO) stdout, stderr = Command(TESTS_TMP_PATH).execute('git clone', clone_url, _get_tmp_dir()) assert 'Cloning into' in stdout + stderr assert stderr == '' or stdout == ''
def test_no_permissions_to_fork(self): usr = self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)['user_id'] user_model = UserModel() user_model.revoke_perm(usr, 'hg.fork.repository') user_model.grant_perm(usr, 'hg.fork.none') u = UserModel().get(usr) u.inherit_default_permissions = False Session().commit() # try create a fork repo_name = self.REPO self.app.post(url(controller='forks', action='fork_create', repo_name=repo_name), {'_authentication_token': self.authentication_token()}, status=403)
def test_ip_restriction_hg(self): user_model = UserModel() try: user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32') Session().commit() clone_url = _construct_url(HG_REPO) stdout, stderr = Command('/tmp').execute('hg clone', clone_url) assert 'abort: HTTP Error 403: Forbidden' in stderr finally: #release IP restrictions for ip in UserIpMap.getAll(): UserIpMap.delete(ip.ip_id) Session().commit() time.sleep(2) clone_url = _construct_url(HG_REPO) stdout, stderr = Command('/tmp').execute('hg clone', clone_url) assert 'requesting all changes' in stdout assert 'adding changesets' in stdout assert 'adding manifests' in stdout assert 'adding file changes' in stdout assert stderr == ''
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 != kallithea.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", force_defaults=False)
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) user_model = UserModel() user = user_model.get(id) _form = UserForm(edit=True, old_data={'user_id': id, 'email': user.email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) skip_attrs = ['extern_type', 'extern_name', ] + auth_modules.get_managed_fields(user) 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 as 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( self._render_edit_profile(user), defaults=defaults, errors=e, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during update of user %s') \ % form_result.get('username'), category='error') raise HTTPFound(location=url('edit_user', id=id))
def update(self, id): user_model = UserModel() user = user_model.get(id) _form = UserForm(edit=True, old_data={'user_id': id, 'email': user.email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) skip_attrs = ['extern_type', 'extern_name', ] + auth_modules.get_managed_fields(user) user_model.update(id, form_result, skip_attrs=skip_attrs) usr = form_result['username'] action_logger(request.authuser, 'admin_updated_user:%s' % usr, None, request.ip_addr) h.flash(_('User updated successfully'), category='success') Session().commit() except formencode.Invalid as 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'), }) return htmlfill.render( self._render_edit_profile(user), defaults=defaults, errors=e, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during update of user %s') \ % form_result.get('username'), category='error') raise HTTPFound(location=url('edit_user', id=id))
def propagate_data(self): user_model = UserModel() self.anonymous_user = User.get_default_user(cache=True) is_user_loaded = False # lookup by userid if self.user_id is not None and self.user_id != self.anonymous_user.user_id: log.debug('Auth User lookup by USER ID %s' % self.user_id) is_user_loaded = user_model.fill_data(self, user_id=self.user_id) # try go get user by api key elif self._api_key and self._api_key != self.anonymous_user.api_key: log.debug('Auth User lookup by API KEY %s' % self._api_key) is_user_loaded = user_model.fill_data(self, api_key=self._api_key) # lookup by username elif self.username: log.debug('Auth User lookup by USER NAME %s' % self.username) is_user_loaded = user_model.fill_data(self, username=self.username) else: log.debug('No data in %s that could been used to log in' % self) if not is_user_loaded: # if we cannot authenticate user try anonymous if self.anonymous_user.active: user_model.fill_data(self, user_id=self.anonymous_user.user_id) # then we set this user is logged in self.is_authenticated = True else: self.user_id = None self.username = None self.is_authenticated = False if not self.username: self.username = '******' log.debug('Auth User is now %s' % self)