def create(cls, users_group, repository, permission): n = cls() n.users_group = users_group n.repository = repository n.permission = permission Session.add(n) return n
def repo_public_journal(self, repo_name): """ Set's this repository to be visible in public journal, in other words assing default user to follow this repo :param repo_name: """ cur_token = request.POST.get('auth_token') token = get_token() if cur_token == token: try: repo_id = Repository.get_by_repo_name(repo_name).repo_id user_id = User.get_by_username('default').user_id self.scm_model.toggle_following_repo(repo_id, user_id) h.flash(_('Updated repository visibility in public journal'), category='success') Session.commit() except: h.flash(_('An error occurred during setting this' ' repository in public journal'), category='error') else: h.flash(_('Token mismatch'), category='error') return redirect(url('edit_repo', repo_name=repo_name))
def update(self, repo_name): """ PUT /repos/repo_name: 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('repo', repo_name=ID), # method='put') # url('repo', repo_name=ID) self.__load_defaults() repo_model = RepoModel() changed_name = repo_name _form = RepoForm(edit=True, old_data={'repo_name': repo_name}, repo_groups=c.repo_groups_choices)() try: form_result = _form.to_python(dict(request.POST)) repo = repo_model.update(repo_name, form_result) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Repository %s updated successfully' % repo_name), category='success') changed_name = repo.repo_name action_logger(self.rhodecode_user, 'admin_updated_repo', changed_name, '', self.sa) Session.commit() except formencode.Invalid, errors: defaults = self.__load_data(repo_name) defaults.update(errors.value) return htmlfill.render( render('admin/repos/repo_edit.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def update(self, repo_name): repo_model = RepoModel() changed_name = repo_name self.__load_defaults() _form = RepoSettingsForm(edit=True, old_data={'repo_name': repo_name}, repo_groups=c.repo_groups_choices)() try: form_result = _form.to_python(dict(request.POST)) repo_model.update(repo_name, form_result) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('Repository %s updated successfully' % repo_name), category='success') changed_name = form_result['repo_name_full'] action_logger(self.rhodecode_user, 'user_updated_repo', changed_name, '', self.sa) Session.commit() except formencode.Invalid, errors: c.repo_info = repo_model.get_by_repo_name(repo_name) c.users_array = repo_model.get_users_js() errors.value.update({'user': c.repo_info.user.username}) return htmlfill.render( render('settings/repo_settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def delete(self, repo_name): """DELETE /repos/repo_name: 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('repo_settings_delete', repo_name=ID), # method='delete') # url('repo_settings_delete', repo_name=ID) repo_model = RepoModel() repo = repo_model.get_by_repo_name(repo_name) if not repo: h.flash(_('%s repository is not mapped to db perhaps' ' it was moved or renamed from the filesystem' ' please run the application again' ' in order to rescan repositories') % repo_name, category='error') return redirect(url('home')) try: action_logger(self.rhodecode_user, 'user_deleted_repo', repo_name, '', self.sa) repo_model.delete(repo) invalidate_cache('get_repo_cached_%s' % repo_name) h.flash(_('deleted repository %s') % repo_name, category='success') Session.commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of %s') % repo_name, category='error') return redirect(url('home'))
def my_account_update(self): """PUT /_admin/my_account_update: 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('admin_settings_my_account_update'), # method='put') # url('admin_settings_my_account_update', id=ID) user_model = UserModel() uid = self.rhodecode_user.user_id _form = UserForm(edit=True, old_data={'user_id': uid, 'email': self.rhodecode_user.email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) user_model.update_my_account(uid, form_result) h.flash(_('Your account was updated successfully'), category='success') Session.commit() except formencode.Invalid, errors: c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name))\ .all() c.user_repos = ScmModel().get_repos(all_repos) return htmlfill.render( render('admin/users/user_edit_my_account.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def test_delete(self): self.log_user() cur_user = self._get_logged_user() u1 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', name='u1', lastname='u1') u2 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', name='u2', lastname='u2') # make notifications notification = NotificationModel().create(created_by=cur_user, subject=u'test', body=u'hi there', recipients=[cur_user, u1, u2]) Session.commit() u1 = User.get(u1.user_id) u2 = User.get(u2.user_id) # check DB get_notif = lambda un:[x.notification for x in un] self.assertEqual(get_notif(cur_user.notifications), [notification]) self.assertEqual(get_notif(u1.notifications), [notification]) self.assertEqual(get_notif(u2.notifications), [notification]) cur_usr_id = cur_user.user_id response = self.app.delete(url('notification', notification_id= notification.notification_id)) cur_user = User.get(cur_usr_id) self.assertEqual(cur_user.notifications, [])
def create(self): """POST /repos_groups: Create a new item""" # url('repos_groups') self.__load_defaults() repos_group_form = ReposGroupForm(available_groups = c.repo_groups_choices)() try: form_result = repos_group_form.to_python(dict(request.POST)) ReposGroupModel().create( group_name=form_result['group_name'], group_description=form_result['group_description'], parent=form_result['group_parent_id'] ) Session.commit() h.flash(_('created repos group %s') \ % form_result['group_name'], category='success') #TODO: in futureaction_logger(, '', '', '', self.sa) except formencode.Invalid, errors: return htmlfill.render( render('admin/repos_groups/repos_groups_add.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def update_perm(self, id): """PUT /users_perm/id: Update an existing item""" # url('user_perm', id=ID, method='put') grant_perm = request.POST.get('create_repo_perm', False) user_model = UserModel() if grant_perm: perm = Permission.get_by_key('hg.create.none') user_model.revoke_perm(id, perm) perm = Permission.get_by_key('hg.create.repository') user_model.grant_perm(id, perm) h.flash(_("Granted 'repository create' permission to user"), category='success') Session.commit() else: perm = Permission.get_by_key('hg.create.repository') user_model.revoke_perm(id, perm) perm = Permission.get_by_key('hg.create.none') user_model.grant_perm(id, perm) h.flash(_("Revoked 'repository create' permission to user"), category='success') Session.commit() return redirect(url('edit_user', id=id))
def revoke_users_group_permission(self, apiuser, repo_name, group_name): """ Revoke permission for users group on given repository :param repo_name: :param group_name: """ try: repo = Repository.get_by_repo_name(repo_name) if repo is None: raise JSONRPCError('unknown repository %s' % repo) user_group = UsersGroup.get_by_group_name(group_name) if user_group is None: raise JSONRPCError('unknown users group %s' % user_group) RepoModel().revoke_users_group_permission(repo=repo_name, group_name=group_name) Session.commit() return dict( msg='Revoked perm for group: %s in repo: %s' % ( group_name, repo_name ) ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError( 'failed to edit permission %(repo)s for %(usersgr)s' % dict( usersgr=group_name, repo=repo_name ) )
def remove_user_from_users_group(self, apiuser, group_name, username): """ Remove user from a group :param apiuser :param group_name :param username """ try: users_group = UsersGroup.get_by_group_name(group_name) if not users_group: raise JSONRPCError('unknown users group %s' % group_name) user = User.get_by_username(username) if user is None: raise JSONRPCError('unknown user %s' % username) success = UsersGroupModel().remove_user_from_group(users_group, user) msg = 'removed member %s from users group %s' % (username, group_name) msg = msg if success else "User wasn't in group" Session.commit() return dict(success=success, msg=msg) except Exception: log.error(traceback.format_exc()) raise JSONRPCError('failed to remove user from group')
def grant_user_permission(self, apiuser, repo_name, username, perm): """ Grant permission for user on given repository, or update existing one if found :param repo_name: :param username: :param perm: """ try: repo = Repository.get_by_repo_name(repo_name) if repo is None: raise JSONRPCError('unknown repository %s' % repo) user = User.get_by_username(username) if user is None: raise JSONRPCError('unknown user %s' % username) RepoModel().grant_user_permission(repo=repo, user=user, perm=perm) Session.commit() return dict( msg='Granted perm: %s for user: %s in repo: %s' % ( perm, username, repo_name ) ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError( 'failed to edit permission %(repo)s for %(user)s' % dict( user=username, repo=repo_name ) )
def update_user(self, apiuser, userid, username, password, email, firstname, lastname, active, admin, ldap_dn): """ Updates given user :param apiuser: :param username: :param password: :param email: :param name: :param lastname: :param active: :param admin: :param ldap_dn: """ if not UserModel().get_user(userid): raise JSONRPCError("user %s does not exist" % username) try: usr = UserModel().create_or_update( username, password, email, firstname, lastname, active, admin, ldap_dn ) Session.commit() return dict( id=usr.user_id, msg='updated user %s' % username ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError('failed to update user %s' % username)
def add_user_to_users_group(self, apiuser, group_name, username): """" Add a user to a users group :param apiuser: :param group_name: :param username: """ try: users_group = UsersGroup.get_by_group_name(group_name) if not users_group: raise JSONRPCError('unknown users group %s' % group_name) user = User.get_by_username(username) if user is None: raise JSONRPCError('unknown user %s' % username) ugm = UsersGroupModel().add_user_to_group(users_group, user) success = True if ugm != True else False msg = 'added member %s to users group %s' % (username, group_name) msg = msg if success else 'User is already in that group' Session.commit() return dict( id=ugm.users_group_member_id if ugm != True else None, success=success, msg=msg ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError('failed to add users group member')
def add_user_to_group(group, user): ugm = UsersGroupMember() ugm.users_group = group ugm.user = user Session.add(ugm) Session.commit() return ugm
def test_propagated_permission_from_users_group_lower_weight(self): # make group self.ug1 = UsersGroupModel().create('G1') # add user to group UsersGroupModel().add_user_to_group(self.ug1, self.u1) # set permission to lower new_perm_h = 'repository.write' RepoModel().grant_user_permission(repo=HG_REPO, user=self.u1, perm=new_perm_h) Session.commit() u1_auth = AuthUser(user_id=self.u1.user_id) self.assertEqual(u1_auth.permissions['repositories'][HG_REPO], new_perm_h) # grant perm for group this should NOT override permission from user # since it's lower than granted new_perm_l = 'repository.read' RepoModel().grant_users_group_permission(repo=HG_REPO, group_name=self.ug1, perm=new_perm_l) # check perms u1_auth = AuthUser(user_id=self.u1.user_id) perms = { 'repositories_groups': {}, 'global': set([u'hg.create.repository', u'repository.read', u'hg.register.manual_activate']), 'repositories': {u'vcs_test_hg': u'repository.write'} } self.assertEqual(u1_auth.permissions['repositories'][HG_REPO], new_perm_h) self.assertEqual(u1_auth.permissions['repositories_groups'], perms['repositories_groups'])
def register(self): c.auto_active = False for perm in User.get_by_username('default').user_perms: if perm.permission.permission_name == 'hg.register.auto_activate': c.auto_active = True break if request.POST: register_form = RegisterForm()() try: form_result = register_form.to_python(dict(request.POST)) form_result['active'] = c.auto_active UserModel().create_registration(form_result) h.flash(_('You have successfully registered into rhodecode'), category='success') Session.commit() return redirect(url('login_home')) except formencode.Invalid, errors: return htmlfill.render( render('/register.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def test_notification_counter(self): self._clean_notifications() self.assertEqual([], Notification.query().all()) self.assertEqual([], UserNotification.query().all()) NotificationModel().create(created_by=self.u1, subject=u'title', body=u'hi there_delete', recipients=[self.u3, self.u1]) Session.commit() self.assertEqual(NotificationModel() .get_unread_cnt_for_user(self.u1), 1) self.assertEqual(NotificationModel() .get_unread_cnt_for_user(self.u2), 0) self.assertEqual(NotificationModel() .get_unread_cnt_for_user(self.u3), 1) notification = NotificationModel().create(created_by=self.u1, subject=u'title', body=u'hi there3', recipients=[self.u3, self.u1, self.u2]) Session.commit() self.assertEqual(NotificationModel() .get_unread_cnt_for_user(self.u1), 2) self.assertEqual(NotificationModel() .get_unread_cnt_for_user(self.u2), 1) self.assertEqual(NotificationModel() .get_unread_cnt_for_user(self.u3), 2)
def update(self, id): """PUT /repos_groups/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('repos_group', id=ID), # method='put') # url('repos_group', id=ID) self.__load_defaults() c.repos_group = RepoGroup.get(id) repos_group_form = ReposGroupForm( edit=True, old_data=c.repos_group.get_dict(), available_groups=c.repo_groups_choices )() try: form_result = repos_group_form.to_python(dict(request.POST)) ReposGroupModel().update(id, form_result) Session.commit() h.flash(_('updated repos group %s') \ % form_result['group_name'], category='success') #TODO: in futureaction_logger(, '', '', '', self.sa) except formencode.Invalid, errors: return htmlfill.render( render('admin/repos_groups/repos_groups_edit.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def delete(self, id): """DELETE /repos_groups/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('repos_group', id=ID), # method='delete') # url('repos_group', id=ID) gr = RepoGroup.get(id) repos = gr.repositories.all() if repos: h.flash(_('This group contains %s repositores and cannot be ' 'deleted' % len(repos)), category='error') return redirect(url('repos_groups')) try: ReposGroupModel().delete(id) Session.commit() h.flash(_('removed repos group %s' % gr.group_name), category='success') #TODO: in future action_logger(, '', '', '', self.sa) except IntegrityError, e: if e.message.find('groups_group_parent_id_fkey') != -1: log.error(traceback.format_exc()) h.flash(_('Cannot delete this group it still contains ' 'subgroups'), category='warning') else: log.error(traceback.format_exc()) h.flash(_('error occurred during deletion of repos ' 'group %s' % gr.group_name), category='error')
def update(self, id): """PUT /permissions/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('permission', id=ID), # method='put') # url('permission', id=ID) permission_model = PermissionModel() _form = DefaultPermissionsForm([x[0] for x in self.perms_choices], [x[0] for x in self.register_choices], [x[0] for x in self.create_choices])() try: form_result = _form.to_python(dict(request.POST)) form_result.update({'perm_user_name': id}) permission_model.update(form_result) Session.commit() h.flash(_('Default permissions updated successfully'), category='success') except formencode.Invalid, errors: c.perms_choices = self.perms_choices c.register_choices = self.register_choices c.create_choices = self.create_choices defaults = errors.value return htmlfill.render( render('admin/permissions/permissions.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def toggle_following(self): cur_token = request.POST.get('auth_token') token = h.get_token() if cur_token == token: user_id = request.POST.get('follows_user_id') if user_id: try: self.scm_model.toggle_following_user(user_id, self.rhodecode_user.user_id) Session.commit() return 'ok' except: raise HTTPBadRequest() repo_id = request.POST.get('follows_repo_id') if repo_id: try: self.scm_model.toggle_following_repo(repo_id, self.rhodecode_user.user_id) Session.commit() return 'ok' except: raise HTTPBadRequest() log.debug('token mismatch %s vs %s' % (cur_token, token)) raise HTTPBadRequest()
def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session.add(self) Session.commit() log.debug("updated user %s lastlogin" % self.username)
def tearDown(self): if self.r2_id: RepoModel().delete(self.r2_id) if self.r1_id: RepoModel().delete(self.r1_id) Session().commit() Session.remove()
def tearDown(self): perm = Permission.query().all() for p in perm: UserModel().revoke_perm(self.u1, p) UserModel().delete(self.u1) Session.commit()
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() c.user = user_model.get(id) _form = UserForm(edit=True, old_data={'user_id': id, 'email': c.user.email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) user_model.update(id, form_result) h.flash(_('User updated successfully'), category='success') Session.commit() except formencode.Invalid, errors: e = errors.error_dict or {} perm = Permission.get_by_key('hg.create.repository') e.update({'create_repo_perm': user_model.has_perm(id, perm)}) return htmlfill.render( render('admin/users/user_edit.html'), defaults=errors.value, errors=e, prefix_error=False, encoding="UTF-8")
def create_or_update_hook(cls, key, val): new_ui = cls.get_by_key(key).scalar() or cls() new_ui.ui_section = 'hooks' new_ui.ui_active = True new_ui.ui_key = key new_ui.ui_value = val Session.add(new_ui)
def delete_comment(self, repo_name, comment_id): co = ChangesetComment.get(comment_id) owner = lambda: co.author.user_id == c.rhodecode_user.user_id if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner: ChangesetCommentsModel().delete(comment=co) Session.commit() return True else: raise HTTPForbidden()
def revoke_perm(cls, users_group_id, perm): if not isinstance(perm, Permission): raise Exception("perm needs to be an instance of Permission class") try: cls.query().filter(cls.users_group_id == users_group_id).filter(cls.permission == perm).delete() Session.commit() except: Session.rollback()
def set_valid(cls, key): """ Mark this cache key as active and currently cached :param key: """ inv_obj = cls.get_by_key(key) inv_obj.cache_active = True Session.add(inv_obj) Session.commit()
def login_container_auth(username): user = User.get_by_username(username) if user is None: user_attrs = { 'name': username, 'lastname': None, 'email': None, 'active': 'hg.register.auto_activate' in User\ .get_by_username('default').AuthUser.permissions['global'] } user = UserModel().create_for_container_auth(username, user_attrs) if not user: return None log.info('User %s was created by container authentication' % username) if not user.active: return None user.update_lastlogin() Session().commit() log.debug('User %s is now logged in by container authentication', user.username) return user
def test_create_git_non_ascii(self): self.log_user() non_ascii = "ąęł" repo_name = "%s%s" % (NEW_GIT_REPO, non_ascii) repo_name_unicode = repo_name.decode('utf8') description = 'description for newly created repo' + non_ascii description_unicode = description.decode('utf8') private = False response = self.app.post( url('repos'), fixture._get_repo_create_params(repo_private=False, repo_type='git', repo_name=repo_name, repo_description=description)) self.checkSessionFlash( response, u'Created repository <a href="/%s">%s</a>' % (urllib.quote(repo_name), repo_name_unicode)) #test if the repo was created in the database new_repo = Session().query(Repository)\ .filter(Repository.repo_name == repo_name_unicode).one() self.assertEqual(new_repo.repo_name, repo_name_unicode) self.assertEqual(new_repo.description, description_unicode) #test if repository is visible in the list ? response = response.follow() response.mustcontain(repo_name) #test if repository was created on filesystem try: vcs.get_repo(os.path.join(TESTS_TMP_PATH, repo_name)) except Exception: self.fail('no repo %s in filesystem' % repo_name)
def create_test_database(test_path, config): """ Makes a fresh database. """ from rhodecode.lib.db_manage import DbManage # PART ONE create db dbconf = config['sqlalchemy.db1.url'] log.debug('making test db %s', dbconf) dbmanage = DbManage(log_sql=False, dbconf=dbconf, root=config['here'], tests=True, cli_args={'force_ask': True}) dbmanage.create_tables(override=True) dbmanage.set_db_version() # for tests dynamically set new root paths based on generated content dbmanage.create_settings(dbmanage.config_prompt(test_path)) dbmanage.create_default_user() dbmanage.create_test_admin_and_users() dbmanage.create_permissions() dbmanage.populate_default_permissions() Session().commit()
def revoke_users_group_permission(self, apiuser, repoid, usersgroupid): """ Revoke permission for user group on given repository :param apiuser: :param repoid: :param usersgroupid: """ repo = get_repo_or_error(repoid) users_group = get_users_group_or_error(usersgroupid) try: RepoModel().revoke_users_group_permission(repo=repo, group_name=users_group) Session().commit() return dict(msg='Revoked perm for user group: `%s` in repo: `%s`' % (users_group.users_group_name, repo.repo_name), success=True) except Exception: log.error(traceback.format_exc()) raise JSONRPCError( 'failed to edit permission for user group: `%s` in ' 'repo: `%s`' % (users_group.users_group_name, repo.repo_name))
def test_default_perms_set(self): u1_auth = AuthUser(user_id=self.u1.user_id) perms = { 'repositories_groups': {}, 'global': set([ u'hg.create.repository', u'repository.read', u'hg.register.manual_activate' ]), 'repositories': { u'vcs_test_hg': u'repository.read' } } self.assertEqual(u1_auth.permissions['repositories'][HG_REPO], perms['repositories'][HG_REPO]) new_perm = 'repository.write' RepoModel().grant_user_permission(repo=HG_REPO, user=self.u1, perm=new_perm) Session().commit() u1_auth = AuthUser(user_id=self.u1.user_id) self.assertEqual(u1_auth.permissions['repositories'][HG_REPO], new_perm)
def add_user_to_users_group(self, apiuser, usersgroupid, userid): """" Add a user to a user group :param apiuser: :param usersgroupid: :param userid: """ user = get_user_or_error(userid) users_group = get_users_group_or_error(usersgroupid) try: ugm = UserGroupModel().add_user_to_group(users_group, user) success = True if ugm != True else False msg = 'added member `%s` to user group `%s`' % ( user.username, users_group.users_group_name) msg = msg if success else 'User is already in that group' Session().commit() return dict(success=success, msg=msg) except Exception: log.error(traceback.format_exc()) raise JSONRPCError('failed to add member to user group `%s`' % (users_group.users_group_name))
def show(self, notification_id, format='html'): """GET /_admin/notifications/id: Show a specific item""" # url('notification', notification_id=ID) c.user = self.rhodecode_user no = Notification.get(notification_id) owner = any(un.user.user_id == c.rhodecode_user.user_id for un in no.notifications_to_users) if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner): unotification = NotificationModel()\ .get_user_notification(c.user.user_id, no) # if this association to user is not valid, we don't want to show # this message if unotification: if not unotification.read: unotification.mark_as_read() Session().commit() c.notification = no return render('admin/notifications/show_notification.html') return abort(403)
def test_push_on_locked_repo_by_other_user_hg(self): #clone some temp DEST = _get_tmp_dir() clone_url = _construct_url(HG_REPO, dest=DEST) stdout, stderr = Command('/tmp').execute('hg clone', clone_url) #lock repo r = Repository.get_by_repo_name(HG_REPO) # let this user actually push ! RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN, perm='repository.write') Session().commit() Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id) #push fails repo is locked by other user ! stdout, stderr = _add_files_and_push('hg', DEST, user=TEST_USER_REGULAR_LOGIN, passwd=TEST_USER_REGULAR_PASS) msg = ( """abort: HTTP Error 423: Repository `%s` locked by user `%s`""" % (HG_REPO, TEST_USER_ADMIN_LOGIN)) assert msg in stderr
def setUp(self): self.u1 = UserModel().create_or_update(username=u'u1', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') self.u2 = UserModel().create_or_update(username=u'u2', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u2', lastname=u'u2') self.u3 = UserModel().create_or_update(username=u'u3', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u3', lastname=u'u3') self.anon = User.get_default_user() self.a1 = UserModel().create_or_update(username=u'a1', password=u'qweqwe', email=u'*****@*****.**', firstname=u'a1', lastname=u'a1', admin=True) Session().commit()
def delete(cls, user_group_id): try: # check if this group is not assigned to repo assigned_groups = UserGroupRepoToPerm.query()\ .filter(UserGroupRepoToPerm.users_group_id == user_group_id).all() if assigned_groups: raise UserGroupAssignedException( 'UserGroup assigned to %s' % assigned_groups) users_group = cls.get(user_group_id, cache=False) Session.delete(users_group) Session.commit() except: log.error(traceback.format_exc()) Session.rollback() raise
class DbManage(object): def __init__(self, log_sql, dbconf, root, tests=False, SESSION=None, cli_args={}): self.dbname = dbconf.split('/')[-1] self.tests = tests self.root = root self.dburi = dbconf self.log_sql = log_sql self.db_exists = False self.cli_args = cli_args self.init_db(SESSION=SESSION) self.ask_ok = self.get_ask_ok_func(self.cli_args.get('force_ask')) def get_ask_ok_func(self, param): if param not in [None]: # return a function lambda that has a default set to param return lambda *args, **kwargs: param else: from rhodecode.lib.utils import ask_ok return ask_ok def init_db(self, SESSION=None): if SESSION: self.sa = SESSION else: # init new sessions engine = create_engine(self.dburi, echo=self.log_sql) init_model(engine) self.sa = Session() def create_tables(self, override=False): """ Create a auth database """ log.info("Existing database with the same name is going to be destroyed.") log.info("Setup command will run DROP ALL command on that database.") if self.tests: destroy = True else: destroy = self.ask_ok('Are you sure that you want to destroy the old database? [y/n]') if not destroy: log.info('Nothing done.') sys.exit(0) if destroy: Base.metadata.drop_all() checkfirst = not override Base.metadata.create_all(checkfirst=checkfirst) log.info('Created tables for %s' % self.dbname) def set_db_version(self): ver = DbMigrateVersion() ver.version = __dbversion__ ver.repository_id = 'rhodecode_db_migrations' ver.repository_path = 'versions' self.sa.add(ver) log.info('db version set to: %s' % __dbversion__) def run_pre_migration_tasks(self): """ Run various tasks before actually doing migrations """ # delete cache keys on each upgrade total = CacheKey.query().count() log.info("Deleting (%s) cache keys now...", total) CacheKey.delete_all_cache() def upgrade(self): """ Upgrades given database schema to given revision following all needed steps, to perform the upgrade """ from rhodecode.lib.dbmigrate.migrate.versioning import api from rhodecode.lib.dbmigrate.migrate.exceptions import \ DatabaseNotControlledError if 'sqlite' in self.dburi: print ( '********************** WARNING **********************\n' 'Make sure your version of sqlite is at least 3.7.X. \n' 'Earlier versions are known to fail on some migrations\n' '*****************************************************\n') upgrade = self.ask_ok( 'You are about to perform a database upgrade. Make ' 'sure you have backed up your database. ' 'Continue ? [y/n]') if not upgrade: log.info('No upgrade performed') sys.exit(0) repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))), 'rhodecode/lib/dbmigrate') db_uri = self.dburi try: curr_version = api.db_version(db_uri, repository_path) msg = ('Found current database under version ' 'control with version %s' % curr_version) except (RuntimeError, DatabaseNotControlledError): curr_version = 1 msg = ('Current database is not under version control. Setting ' 'as version %s' % curr_version) api.version_control(db_uri, repository_path, curr_version) notify(msg) self.run_pre_migration_tasks() if curr_version == __dbversion__: log.info('This database is already at the newest version') sys.exit(0) upgrade_steps = range(curr_version + 1, __dbversion__ + 1) notify('attempting to upgrade database from ' 'version %s to version %s' % (curr_version, __dbversion__)) # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE _step = None for step in upgrade_steps: notify('performing upgrade step %s' % step) time.sleep(0.5) api.upgrade(db_uri, repository_path, step) self.sa.rollback() notify('schema upgrade for step %s completed' % (step,)) _step = step notify('upgrade to version %s successful' % _step) def fix_repo_paths(self): """ Fixes an old RhodeCode version path into new one without a '*' """ paths = self.sa.query(RhodeCodeUi)\ .filter(RhodeCodeUi.ui_key == '/')\ .scalar() paths.ui_value = paths.ui_value.replace('*', '') try: self.sa.add(paths) self.sa.commit() except Exception: self.sa.rollback() raise def fix_default_user(self): """ Fixes an old default user with some 'nicer' default values, used mostly for anonymous access """ def_user = self.sa.query(User)\ .filter(User.username == User.DEFAULT_USER)\ .one() def_user.name = 'Anonymous' def_user.lastname = 'User' def_user.email = User.DEFAULT_USER_EMAIL try: self.sa.add(def_user) self.sa.commit() except Exception: self.sa.rollback() raise def fix_settings(self): """ Fixes rhodecode settings and adds ga_code key for google analytics """ hgsettings3 = RhodeCodeSetting('ga_code', '') try: self.sa.add(hgsettings3) self.sa.commit() except Exception: self.sa.rollback() raise def create_admin_and_prompt(self): # defaults defaults = self.cli_args username = defaults.get('username') password = defaults.get('password') email = defaults.get('email') if username is None: username = raw_input('Specify admin username:'******'Specify admin email:') api_key = self.cli_args.get('api_key') self.create_user(username, password, email, True, strict_creation_check=False, api_key=api_key) def _get_admin_password(self): password = getpass.getpass('Specify admin password ' '(min 6 chars):') confirm = getpass.getpass('Confirm password:'******'passwords mismatch') return False if len(password) < 6: log.error('password is too short - use at least 6 characters') return False return password def create_test_admin_and_users(self): log.info('creating admin and regular test users') from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \ TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \ TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \ TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \ TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, True) self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, TEST_USER_REGULAR_EMAIL, False) self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL, False) def create_ui_settings(self, repo_store_path): """ Creates ui settings, fills out hooks and disables dotencode """ settings_model = SettingsModel(sa=self.sa) # Build HOOKS hooks = [ (RhodeCodeUi.HOOK_REPO_SIZE, 'python:vcsserver.hooks.repo_size'), # HG (RhodeCodeUi.HOOK_PRE_PULL, 'python:vcsserver.hooks.pre_pull'), (RhodeCodeUi.HOOK_PULL, 'python:vcsserver.hooks.log_pull_action'), (RhodeCodeUi.HOOK_PRE_PUSH, 'python:vcsserver.hooks.pre_push'), (RhodeCodeUi.HOOK_PUSH, 'python:vcsserver.hooks.log_push_action'), ] for key, value in hooks: hook_obj = settings_model.get_ui_by_key(key) hooks2 = hook_obj if hook_obj else RhodeCodeUi() hooks2.ui_section = 'hooks' hooks2.ui_key = key hooks2.ui_value = value self.sa.add(hooks2) # enable largefiles largefiles = RhodeCodeUi() 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 = RhodeCodeUi() 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 = RhodeCodeUi() 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 = RhodeCodeUi() hggit.ui_section = 'extensions' hggit.ui_key = 'hggit' hggit.ui_value = '' hggit.ui_active = False self.sa.add(hggit) # set svn branch defaults branches = ["/branches/*", "/trunk"] tags = ["/tags/*"] for branch in branches: settings_model.create_ui_section_value( RhodeCodeUi.SVN_BRANCH_ID, branch) for tag in tags: settings_model.create_ui_section_value(RhodeCodeUi.SVN_TAG_ID, tag) 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', 'egg:rhodecode-enterprise-ce#rhodecode', 'list'), ('auth_rhodecode_enabled', 'True', 'bool')]: if (skip_existing and SettingsModel().get_setting_by_name(k) is not None): log.debug('Skipping option %s' % k) continue setting = RhodeCodeSetting(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 SettingsModel().get_setting_by_name(k) is not None): log.debug('Skipping option %s' % k) continue setting = RhodeCodeSetting(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, useful 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 u2p = UserToPerm.query()\ .filter(UserToPerm.user == default_user).all() fixed = False if len(u2p) != len(Permission.DEFAULT_USER_PERMISSIONS): for p in u2p: Session().delete(p) fixed = True self.populate_default_permissions() return fixed def update_repo_info(self): RepoModel.update_repoinfo() def config_prompt(self, test_repo_path='', retries=3): defaults = self.cli_args _path = defaults.get('repos_location') if retries == 3: log.info('Setting up repositories config') if _path is not None: path = _path elif not self.tests and not test_repo_path: path = raw_input( 'Enter a valid absolute path to store repositories. ' 'All repositories in that path will be added automatically:' ) else: path = test_repo_path path_ok = True # check proper dir if not os.path.isdir(path): path_ok = False log.error('Given path %s is not a valid directory' % (path,)) elif not os.path.isabs(path): path_ok = False log.error('Given path %s is not an absolute path' % (path,)) # check if path is at least readable. if not os.access(path, os.R_OK): path_ok = False log.error('Given path %s is not readable' % (path,)) # check write access, warn user about non writeable paths elif not os.access(path, os.W_OK) and path_ok: log.warning('No write permission to given path %s' % (path,)) q = ('Given path %s is not writeable, do you want to ' 'continue with read only mode ? [y/n]' % (path,)) if not self.ask_ok(q): log.error('Canceled by user') sys.exit(-1) if retries == 0: sys.exit('max retries reached') if not path_ok: retries -= 1 return self.config_prompt(test_repo_path, retries) real_path = os.path.normpath(os.path.realpath(path)) if real_path != os.path.normpath(path): q = ('Path looks like a symlink, RhodeCode Enterprise will store ' 'given path as %s ? [y/n]') % (real_path,) if not self.ask_ok(q): log.error('Canceled by user') sys.exit(-1) return real_path 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', 'true') ] for section, key, value in ui_config: ui_conf = RhodeCodeUi() setattr(ui_conf, 'ui_section', section) setattr(ui_conf, 'ui_key', key) setattr(ui_conf, 'ui_value', value) self.sa.add(ui_conf) # rhodecode app settings settings = [ ('realm', 'RhodeCode', 'unicode'), ('title', '', 'unicode'), ('pre_code', '', 'unicode'), ('post_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', False, 'bool'), ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'), ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'), ('support_url', '', 'unicode'), ('update_url', RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode'), ('show_revision_number', True, 'bool'), ('show_sha_length', 12, 'int'), ] for key, val, type_ in settings: sett = RhodeCodeSetting(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, strict_creation_check=True, api_key=None): log.info('creating user %s' % username) user = UserModel().create_or_update( username, password, email, firstname='RhodeCode', lastname='Admin', active=True, admin=admin, extern_type="rhodecode", strict_creation_check=strict_creation_check) if api_key: log.info('setting a provided api key for the user %s', username) user.api_key = api_key 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=User.DEFAULT_USER_EMAIL, firstname='Anonymous', lastname='User', strict_creation_check=False) # 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_user_permissions(user=User.DEFAULT_USER)
def teardown_method(self, method): for n in Notification.query().all(): inst = Notification.get(n.notification_id) Session().delete(inst) Session().commit()
def test_repo_in_group_permissions(self): self.g1 = _make_group('group1', skip_if_exists=True) self.g2 = _make_group('group2', skip_if_exists=True) Session.commit() # both perms should be read ! u1_auth = AuthUser(user_id=self.u1.user_id) self.assertEqual(u1_auth.permissions['repositories_groups'], { u'group1': u'group.read', u'group2': u'group.read' }) a1_auth = AuthUser(user_id=self.anon.user_id) self.assertEqual(a1_auth.permissions['repositories_groups'], { u'group1': u'group.read', u'group2': u'group.read' }) #Change perms to none for both groups ReposGroupModel().grant_user_permission(repos_group=self.g1, user=self.anon, perm='group.none') ReposGroupModel().grant_user_permission(repos_group=self.g2, user=self.anon, perm='group.none') u1_auth = AuthUser(user_id=self.u1.user_id) self.assertEqual(u1_auth.permissions['repositories_groups'], { u'group1': u'group.none', u'group2': u'group.none' }) a1_auth = AuthUser(user_id=self.anon.user_id) self.assertEqual(a1_auth.permissions['repositories_groups'], { u'group1': u'group.none', u'group2': u'group.none' }) # add repo to group form_data = { 'repo_name': HG_REPO, 'repo_name_full': RepoGroup.url_sep().join([self.g1.group_name, HG_REPO]), 'repo_type': 'hg', 'clone_uri': '', 'repo_group': self.g1.group_id, 'description': 'desc', 'private': False } self.test_repo = RepoModel().create(form_data, cur_user=self.u1) Session.commit() u1_auth = AuthUser(user_id=self.u1.user_id) self.assertEqual(u1_auth.permissions['repositories_groups'], { u'group1': u'group.none', u'group2': u'group.none' }) a1_auth = AuthUser(user_id=self.anon.user_id) self.assertEqual(a1_auth.permissions['repositories_groups'], { u'group1': u'group.none', u'group2': u'group.none' }) #grant permission for u2 ! ReposGroupModel().grant_user_permission(repos_group=self.g1, user=self.u2, perm='group.read') ReposGroupModel().grant_user_permission(repos_group=self.g2, user=self.u2, perm='group.read') Session.commit() self.assertNotEqual(self.u1, self.u2) #u1 and anon should have not change perms while u2 should ! u1_auth = AuthUser(user_id=self.u1.user_id) self.assertEqual(u1_auth.permissions['repositories_groups'], { u'group1': u'group.none', u'group2': u'group.none' }) u2_auth = AuthUser(user_id=self.u2.user_id) self.assertEqual(u2_auth.permissions['repositories_groups'], { u'group1': u'group.read', u'group2': u'group.read' }) a1_auth = AuthUser(user_id=self.anon.user_id) self.assertEqual(a1_auth.permissions['repositories_groups'], { u'group1': u'group.none', u'group2': u'group.none' })
def _clean_notifications(self): for n in Notification.query().all(): Session.delete(n) Session.commit() self.assertEqual(Notification.query().all(), [])
other_repo = _form['other_repo'] other_ref = 'rev:ancestor:%s' % _form[ 'ancestor_rev'] # could be calculated from other_ref ... revisions = [x for x in reversed(_form['revisions'])] reviewers = _form['review_members'] title = _form['pullrequest_title'] if not title: title = '%s#%s to %s' % (org_repo, org_ref.split(':', 2)[1], other_repo) description = _form['pullrequest_desc'] try: pull_request = PullRequestModel().create( self.rhodecode_user.user_id, org_repo, org_ref, other_repo, other_ref, revisions, reviewers, title, description) Session().commit() h.flash(_('Successfully opened new pull request'), category='success') except Exception: h.flash(_('Error occurred during sending pull request'), category='error') log.error(traceback.format_exc()) return redirect(url('pullrequest_home', repo_name=repo_name)) return redirect( url('pullrequest_show', repo_name=other_repo, pull_request_id=pull_request.pull_request_id)) @LoginRequired() @NotAnonymous()
def get_server_info(self, environ=None): import platform import rhodecode import pkg_resources from rhodecode.model.meta import Base as sql_base, Session from sqlalchemy.engine import url from rhodecode.lib.base import get_server_ip_addr, get_server_port from rhodecode.lib.vcs.backends.git import discover_git_version from rhodecode.model.gist import GIST_STORE_LOC try: # cygwin cannot have yet psutil support. import psutil except ImportError: psutil = None environ = environ or {} _NA = 'NOT AVAILABLE' _memory = _NA _uptime = _NA _boot_time = _NA _cpu = _NA _disk = dict(percent=0, used=0, total=0, error='') _load = {'1_min': _NA, '5_min': _NA, '15_min': _NA} model = VcsSettingsModel() storage_path = model.get_repos_location() gist_storage_path = os.path.join(storage_path, GIST_STORE_LOC) archive_storage_path = rhodecode.CONFIG.get('archive_cache_dir', '') search_index_storage_path = rhodecode.CONFIG.get('search.location', '') if psutil: # disk storage try: _disk = dict(psutil.disk_usage(storage_path)._asdict()) except Exception as e: log.exception('Failed to fetch disk info') _disk = {'percent': 0, 'used': 0, 'total': 0, 'error': str(e)} # memory _memory = dict(psutil.virtual_memory()._asdict()) _memory['percent2'] = psutil._common.usage_percent( (_memory['total'] - _memory['free']), _memory['total'], 1) # load averages if hasattr(psutil.os, 'getloadavg'): _load = dict( zip(['1_min', '5_min', '15_min'], psutil.os.getloadavg())) _uptime = time.time() - psutil.boot_time() _boot_time = psutil.boot_time() _cpu = psutil.cpu_percent(0.5) mods = dict([(p.project_name, p.version) for p in pkg_resources.working_set]) def get_storage_size(storage_path): sizes = [] for file_ in os.listdir(storage_path): storage_file = os.path.join(storage_path, file_) if os.path.isfile(storage_file): try: sizes.append(os.path.getsize(storage_file)) except OSError: log.exception('Failed to get size of storage file %s', storage_file) pass return sum(sizes) # archive cache storage _disk_archive = {'percent': 0, 'used': 0, 'total': 0} try: archive_storage_path_exists = os.path.isdir(archive_storage_path) if archive_storage_path and archive_storage_path_exists: used = get_storage_size(archive_storage_path) _disk_archive.update({ 'used': used, 'total': used, }) except Exception as e: log.exception('failed to fetch archive cache storage') _disk_archive['error'] = str(e) # search index storage _disk_index = {'percent': 0, 'used': 0, 'total': 0} try: search_index_storage_path_exists = os.path.isdir( search_index_storage_path) if search_index_storage_path_exists: used = get_storage_size(search_index_storage_path) _disk_index.update({ 'percent': 100, 'used': used, 'total': used, }) except Exception as e: log.exception('failed to fetch search index storage') _disk_index['error'] = str(e) # gist storage _disk_gist = {'percent': 0, 'used': 0, 'total': 0, 'items': 0} try: items_count = 0 used = 0 for root, dirs, files in os.walk(safe_str(gist_storage_path)): if root == gist_storage_path: items_count = len(dirs) for f in files: try: used += os.path.getsize(os.path.join(root, f)) except OSError: pass _disk_gist.update({ 'percent': 100, 'used': used, 'total': used, 'items': items_count }) except Exception as e: log.exception('failed to fetch gist storage items') _disk_gist['error'] = str(e) # GIT info git_ver = discover_git_version() # SVN info # TODO: johbo: Add discover_svn_version to replace this code. try: import svn.core svn_ver = svn.core.SVN_VERSION except ImportError: svn_ver = None # DB stuff db_info = url.make_url(rhodecode.CONFIG['sqlalchemy.db1.url']) db_type = db_info.__to_string__() try: engine = sql_base.metadata.bind db_server_info = engine.dialect._get_server_version_info( Session.connection(bind=engine)) db_version = '%s %s' % (db_info.drivername, '.'.join( map(str, db_server_info))) except Exception: log.exception('failed to fetch db version') db_version = '%s %s' % (db_info.drivername, '?') db_migrate = DbMigrateVersion.query().filter( DbMigrateVersion.repository_id == 'rhodecode_db_migrations').one() db_migrate_version = db_migrate.version info = { 'py_version': ' '.join(platform._sys_version()), 'py_path': sys.executable, 'py_modules': sorted(mods.items(), key=lambda k: k[0].lower()), 'platform': safe_unicode(platform.platform()), 'storage': storage_path, 'archive_storage': archive_storage_path, 'index_storage': search_index_storage_path, 'gist_storage': gist_storage_path, 'db_type': db_type, 'db_version': db_version, 'db_migrate_version': db_migrate_version, 'rhodecode_version': rhodecode.__version__, 'rhodecode_config_ini': rhodecode.CONFIG.get('__file__'), 'server_ip': '%s:%s' % (get_server_ip_addr( environ, log_errors=False), get_server_port(environ)), 'server_id': rhodecode.CONFIG.get('instance_id'), 'git_version': safe_unicode(git_ver), 'hg_version': mods.get('mercurial'), 'svn_version': svn_ver, 'uptime': _uptime, 'boot_time': _boot_time, 'load': _load, 'cpu': _cpu, 'memory': _memory, 'disk': _disk, 'disk_archive': _disk_archive, 'disk_gist': _disk_gist, 'disk_index': _disk_index, } return info
def authenticate(username, password): """ Authentication function used for access control, firstly checks for db authentication then if ldap is enabled for ldap authentication, also creates ldap user if not in database :param username: username :param password: password """ user_model = UserModel() user = User.get_by_username(username) log.debug('Authenticating user using RhodeCode account') if user is not None and not user.ldap_dn: if user.active: if user.username == 'default' and user.active: log.info('user %s authenticated correctly as anonymous user' % username) return True elif user.username == username and check_password( password, user.password): log.info('user %s authenticated correctly' % username) return True else: log.warning('user %s tried auth but is disabled' % username) else: log.debug('Regular authentication failed') user_obj = User.get_by_username(username, case_insensitive=True) if user_obj is not None and not user_obj.ldap_dn: log.debug('this user already exists as non ldap') return False ldap_settings = RhodeCodeSetting.get_ldap_settings() #====================================================================== # FALLBACK TO LDAP AUTH IF ENABLE #====================================================================== if str2bool(ldap_settings.get('ldap_active')): log.debug("Authenticating user using ldap") kwargs = { 'server': ldap_settings.get('ldap_host', ''), 'base_dn': ldap_settings.get('ldap_base_dn', ''), 'port': ldap_settings.get('ldap_port'), 'bind_dn': ldap_settings.get('ldap_dn_user'), 'bind_pass': ldap_settings.get('ldap_dn_pass'), 'tls_kind': ldap_settings.get('ldap_tls_kind'), 'tls_reqcert': ldap_settings.get('ldap_tls_reqcert'), 'ldap_filter': ldap_settings.get('ldap_filter'), 'search_scope': ldap_settings.get('ldap_search_scope'), 'attr_login': ldap_settings.get('ldap_attr_login'), 'ldap_version': 3, } log.debug('Checking for ldap authentication') try: aldap = AuthLdap(**kwargs) (user_dn, ldap_attrs) = aldap.authenticate_ldap(username, password) log.debug('Got ldap DN response %s' % user_dn) get_ldap_attr = lambda k: ldap_attrs.get(ldap_settings\ .get(k), [''])[0] user_attrs = { 'name': safe_unicode(get_ldap_attr('ldap_attr_firstname')), 'lastname': safe_unicode(get_ldap_attr('ldap_attr_lastname')), 'email': get_ldap_attr('ldap_attr_email'), 'active': 'hg.extern_activate.auto' in User.get_default_user()\ .AuthUser.permissions['global'] } # don't store LDAP password since we don't need it. Override # with some random generated password _password = PasswordGenerator().gen_password(length=8) # create this user on the fly if it doesn't exist in rhodecode # database if user_model.create_ldap(username, _password, user_dn, user_attrs): log.info('created new ldap user %s' % username) Session().commit() return True except (LdapUsernameError, LdapPasswordError, LdapImportError): pass except (Exception, ): log.error(traceback.format_exc()) pass return False
def _authenticate(self, userobj, username, passwd, settings, **kwargs): # at this point _authenticate calls plugin's `auth()` function auth = super(RhodeCodeExternalAuthPlugin, self)._authenticate(userobj, username, passwd, settings, **kwargs) if auth: # maybe plugin will clean the username ? # we should use the return value username = auth['username'] # if external source tells us that user is not active, we should # skip rest of the process. 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 cur_user = User.get_by_username(username, case_insensitive=True) is_user_existing = cur_user is not None if is_user_existing: log.debug('Syncing user `%s` from ' '`%s` plugin', username, self.name) else: log.debug( 'Creating non existing user `%s` from ' '`%s` plugin', username, self.name) if self.allows_creating_users: log.debug('Plugin `%s` allows to ' 'create new users', self.name) else: log.debug('Plugin `%s` does not allow to ' 'create new users', self.name) user_parameters = { 'username': username, 'email': auth["email"], 'firstname': auth["firstname"], 'lastname': auth["lastname"], 'active': auth["active"], 'admin': auth["admin"], 'extern_name': auth["extern_name"], 'extern_type': self.name, 'plugin': self, 'allow_to_create_user': self.allows_creating_users, } if not is_user_existing: 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=16) user_parameters['password'] = passwd else: # Since the password is required by create_or_update method of # UserModel, we need to set it explicitly. # The create_or_update method is smart and recognises the # password hashes as well. user_parameters['password'] = cur_user.password # we either create or update users, we also pass the flag # that controls if this method can actually do that. # raises NotAllowedToCreateUserError if it cannot, and we try to. user = UserModel().create_or_update(**user_parameters) 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 tearDown(self): Session().delete(self.u1) Session().commit()
def test_enable_repository_read_on_group(self): self.log_user() users_group_name = TEST_USER_GROUP + 'another2' response = self.app.post(url('users_groups'), { 'users_group_name': users_group_name, 'active': True }) response.follow() ug = UserGroup.get_by_group_name(users_group_name) self.checkSessionFlash(response, 'Created user group %s' % users_group_name) ## ENABLE REPO CREATE ON A GROUP response = self.app.put(url('users_group_perm', id=ug.users_group_id), {'create_repo_perm': True}) response.follow() ug = UserGroup.get_by_group_name(users_group_name) p = Permission.get_by_key('hg.create.repository') p2 = Permission.get_by_key('hg.usergroup.create.false') p3 = Permission.get_by_key('hg.fork.none') # check if user has this perms, they should be here since # defaults are on perms = UserGroupToPerm.query()\ .filter(UserGroupToPerm.users_group == ug).all() self.assertEqual( sorted([[ x.users_group_id, x.permission_id, ] for x in perms]), sorted([[ug.users_group_id, p.permission_id], [ug.users_group_id, p2.permission_id], [ug.users_group_id, p3.permission_id]])) ## DISABLE REPO CREATE ON A GROUP response = self.app.put(url('users_group_perm', id=ug.users_group_id), {}) response.follow() ug = UserGroup.get_by_group_name(users_group_name) p = Permission.get_by_key('hg.create.none') p2 = Permission.get_by_key('hg.usergroup.create.false') p3 = Permission.get_by_key('hg.fork.none') # check if user has this perms, they should be here since # defaults are on perms = UserGroupToPerm.query()\ .filter(UserGroupToPerm.users_group == ug).all() self.assertEqual( sorted([[ x.users_group_id, x.permission_id, ] for x in perms]), sorted([[ug.users_group_id, p.permission_id], [ug.users_group_id, p2.permission_id], [ug.users_group_id, p3.permission_id]])) # DELETE ! ug = UserGroup.get_by_group_name(users_group_name) ugid = ug.users_group_id response = self.app.delete(url('users_group', id=ug.users_group_id)) response = response.follow() gr = Session().query(UserGroup)\ .filter(UserGroup.users_group_name == users_group_name).scalar() self.assertEqual(gr, None) p = Permission.get_by_key('hg.create.repository') perms = UserGroupToPerm.query()\ .filter(UserGroupToPerm.users_group_id == ugid).all() perms = [[ x.users_group_id, x.permission_id, ] for x in perms] self.assertEqual(perms, [])
def __init__(self, methodName='runTest'): Session.remove() super(TestUser, self).__init__(methodName=methodName)
def _delete_all_user_groups(): for gr in UserGroupModel.get_all(): fixture.destroy_user_group(gr) Session().commit()
def test_add_perm(self): perm = Permission.query().all()[0] UserModel().grant_perm(self.u1, perm) Session.commit() self.assertEqual(UserModel().has_perm(self.u1, perm), True)
def test_create_group(self): g = fixture.create_group('newGroup') Session().commit() self.assertEqual(g.full_path, 'newGroup') self.assertTrue(self.__check_path('newGroup'))
def test_create_same_name_group(self): self.assertRaises(IntegrityError, lambda: _make_group('newGroup')) Session.rollback()
def tearDown(self): for n in Notification.query().all(): inst = Notification.get(n.notification_id) Session().delete(inst) Session().commit()
def tearDown(self): Session.remove()
def test_create_group(self): g = fixture.create_repo_group('newGroup') Session().commit() assert g.full_path == 'newGroup' assert self.__check_path('newGroup')
def test_create_same_name_group(self): with pytest.raises(IntegrityError): fixture.create_repo_group('newGroup') Session().rollback()
def comment(self, repo_name, pull_request_id): pull_request = PullRequest.get_or_404(pull_request_id) if pull_request.is_closed(): raise HTTPForbidden() status = request.POST.get('changeset_status') change_status = request.POST.get('change_changeset_status') text = request.POST.get('text') close_pr = request.POST.get('save_close') allowed_to_change_status = self._get_is_allowed_change_status( pull_request) if status and change_status and allowed_to_change_status: _def = (_('Status change -> %s') % ChangesetStatus.get_status_lbl(status)) if close_pr: _def = _('Closing with') + ' ' + _def text = text or _def comm = ChangesetCommentsModel().create( text=text, repo=c.rhodecode_db_repo.repo_id, user=c.rhodecode_user.user_id, pull_request=pull_request_id, f_path=request.POST.get('f_path'), line_no=request.POST.get('line'), status_change=(ChangesetStatus.get_status_lbl(status) if status and change_status and allowed_to_change_status else None), closing_pr=close_pr) action_logger(self.rhodecode_user, 'user_commented_pull_request:%s' % pull_request_id, c.rhodecode_db_repo, self.ip_addr, self.sa) if allowed_to_change_status: # get status if set ! if status and change_status: ChangesetStatusModel().set_status(c.rhodecode_db_repo.repo_id, status, c.rhodecode_user.user_id, comm, pull_request=pull_request_id) if close_pr: if status in ['rejected', 'approved']: PullRequestModel().close_pull_request(pull_request_id) action_logger( self.rhodecode_user, 'user_closed_pull_request:%s' % pull_request_id, c.rhodecode_db_repo, self.ip_addr, self.sa) else: h.flash(_('Closing pull request on other statuses than ' 'rejected or approved forbidden'), category='warning') Session().commit() if not request.environ.get('HTTP_X_PARTIAL_XHR'): return redirect( h.url('pullrequest_show', repo_name=repo_name, pull_request_id=pull_request_id)) data = { 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))), } if comm: c.co = comm data.update(comm.get_dict()) data.update({ 'rendered_text': render('changeset/changeset_comment_block.html') }) return data