Example #1
0
 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
Example #2
0
    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))
Example #3
0
 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")
Example #4
0
    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")
Example #5
0
    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'))
Example #6
0
    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, [])
Example #8
0
    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")
Example #9
0
    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))
Example #10
0
    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
                )
            )
Example #11
0
    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')
Example #12
0
    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
                )
            )
Example #13
0
    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)
Example #14
0
    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')
Example #15
0
 def add_user_to_group(group, user):
     ugm = UsersGroupMember()
     ugm.users_group = group
     ugm.user = user
     Session.add(ugm)
     Session.commit()
     return ugm
Example #16
0
    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'])
Example #17
0
    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")
Example #18
0
    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)
Example #19
0
    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")
Example #20
0
    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')
Example #21
0
    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")
Example #22
0
    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()
Example #23
0
    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)
Example #24
0
 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()
Example #25
0
    def tearDown(self):
        perm = Permission.query().all()
        for p in perm:
            UserModel().revoke_perm(self.u1, p)

        UserModel().delete(self.u1)
        Session.commit()
Example #26
0
    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")
Example #27
0
    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)
Example #28
0
 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()
Example #29
0
    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()
Example #30
0
    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()
Example #31
0
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
Example #32
0
    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)
Example #33
0
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()
Example #34
0
    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))
Example #35
0
    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)
Example #36
0
    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))
Example #37
0
    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)
Example #38
0
    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
Example #39
0
 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()
Example #40
0
    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
Example #41
0
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)
Example #42
0
 def teardown_method(self, method):
     for n in Notification.query().all():
         inst = Notification.get(n.notification_id)
         Session().delete(inst)
     Session().commit()
Example #43
0
    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'
        })
Example #44
0
    def _clean_notifications(self):
        for n in Notification.query().all():
            Session.delete(n)

        Session.commit()
        self.assertEqual(Notification.query().all(), [])
Example #45
0
        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()
Example #46
0
    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
Example #47
0
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
Example #48
0
    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
Example #49
0
 def tearDown(self):
     Session().delete(self.u1)
     Session().commit()
Example #50
0
    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, [])
Example #51
0
 def __init__(self, methodName='runTest'):
     Session.remove()
     super(TestUser, self).__init__(methodName=methodName)
Example #52
0
def _delete_all_user_groups():
    for gr in UserGroupModel.get_all():
        fixture.destroy_user_group(gr)
    Session().commit()
Example #53
0
 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)
Example #54
0
    def test_create_group(self):
        g = fixture.create_group('newGroup')
        Session().commit()
        self.assertEqual(g.full_path, 'newGroup')

        self.assertTrue(self.__check_path('newGroup'))
Example #55
0
 def test_create_same_name_group(self):
     self.assertRaises(IntegrityError, lambda: _make_group('newGroup'))
     Session.rollback()
Example #56
0
 def tearDown(self):
     for n in Notification.query().all():
         inst = Notification.get(n.notification_id)
         Session().delete(inst)
     Session().commit()
Example #57
0
 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()
Example #60
0
    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