Пример #1
0
def test_user_public_key(make_session, session, users):
    make_session.return_value = session

    # good key
    username = '******'
    good_key = ('ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCUQeasspT/etEJR2WUoR+h2sMOQYbJgr0Q'
            'E+J8p97gEhmz107KWZ+3mbOwyIFzfWBcJZCEg9wy5Paj+YxbGONqbpXAhPdVQ2TLgxr41bNXvbcR'
            'AxZC+Q12UZywR4Klb2kungKz4qkcmSZzouaKK12UxzGB3xQ0N+3osKFj3xA1+B6HqrVreU19XdVo'
            'AJh0xLZwhw17/NDM+dAcEdMZ9V89KyjwjraXtOVfFhQF0EDF0ame8d6UkayGrAiXC2He0P2Cja+J'
            '371P27AlNLHFJij8WGxvcGGSeAxMLoVSDOOllLCYH5UieV8mNpX1kNe2LeA58ciZb0AXHaipSmCH'
            'gh/ some-comment')
    call_main('user', 'add_public_key', username, good_key)

    user = User.get(session, name=username)
    keys = user.my_public_keys()
    assert len(keys) == 1
    assert keys[0].public_key == good_key

    # bad key
    username = '******'
    bad_key = 'ssh-rsa AAAblahblahkey some-comment'
    call_main('user', 'add_public_key', username, good_key)

    user = User.get(session, name=username)
    keys = user.my_public_keys()
    assert len(keys) == 1
    assert keys[0].public_key == good_key
Пример #2
0
def users(session):
    users = {
        username: User.get_or_create(session, username=username)[0]
        for username in ("gary", "zay", "zorkian", "oliver", "testuser", "figurehead", "zebu")
    }
    users["role"] = User.get_or_create(session, username="******", role_user=True)[0]
    session.commit()
    return users
Пример #3
0
 def run(self, session, **kwargs):
     if kwargs.get('group'):
         Group.get_or_create(session, groupname=groupname)
         session.commit()
     elif kwargs.get('key') == 'valuewith=':
         User.get_or_create(session, username=other_username)
         session.commit()
     else:
         User.get_or_create(session, username=username)
         session.commit()
Пример #4
0
def users(session):
    users = {
        username: User.get_or_create(session, username=username)[0]
        for username in ("gary", "zay", "zorkian", "oliver", "testuser",
                         "figurehead", "zebu")
    }
    users["role"] = User.get_or_create(session,
                                       username="******",
                                       role_user=True)[0]
    session.commit()
    return users
Пример #5
0
def users(session):
    users = {
        username: User.get_or_create(session, username=username)[0]
        for username in ("gary", "zay", "zorkian", "testuser")
    }
    session.commit()
    return users
Пример #6
0
    def post(self, user_id=None, name=None, key_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if (user.name != self.current_user.name) and not self.current_user.user_admin:
            return self.forbidden()

        key = self.session.query(PublicKey).filter_by(id=key_id, user_id=user.id).scalar()
        if not key:
            return self.notfound()

        key.delete(self.session)
        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "delete_public_key",
            "Deleted public key: {}".format(key.fingerprint),
            on_user_id=user.id,
        )

        email_context = {"actioner": self.current_user.name, "changed_user": user.name, "action": "removed"}
        send_email(self.session, [user.name], "Public SSH key removed", "ssh_keys_changed", settings, email_context)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #7
0
def users(session):
    users = {
        username: User.get_or_create(session, username=username)[0]
        for username in ("gary", "zay", "zorkian", "oliver", "testuser")
    }
    session.commit()
    return users
Пример #8
0
    def get_current_user(self):
        username = self.request.headers.get(settings.user_auth_header)
        if not username:
            return

        # Users must be fully qualified
        if not re.match("^{}$".format(USERNAME_VALIDATION), username):
            raise InvalidUser()

        try:
            user, created = User.get_or_create(self.session, username=username)
            if created:
                logging.info("Created new user %s", username)
                self.session.commit()
                # Because the graph doesn't initialize until the updates table
                # is populated, we need to refresh the graph here in case this
                # is the first update.
                self.graph.update_from_db(self.session)
        except sqlalchemy.exc.OperationalError:
            # Failed to connect to database or create user, try to reconfigure the db. This invokes
            # the fetcher to try to see if our URL string has changed.
            Session.configure(bind=get_db_engine(get_database_url(settings)))
            raise DatabaseFailure()

        return user
Пример #9
0
    def get(self, user_id=None, name=None, token_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if (user.name != self.current_user.name) and not self.current_user.user_admin:
            return self.forbidden()
        token = UserToken.get(self.session, user=user, id=token_id)
        return self.render("user-token-disable.html", user=user, token=token)
Пример #10
0
    def get(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if (user.name != self.current_user.name) and not self.current_user.user_admin:
            return self.forbidden()

        self.render("public-key-add.html", form=PublicKeyForm(), user=user)
Пример #11
0
    def get(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if user.name != self.current_user.name:
            return self.forbidden()

        self.render("user-token-add.html", form=UserTokenForm(), user=user)
Пример #12
0
def user_command(args):
    session = make_session()

    if args.subcommand == "create":
        for username in args.username:
            user = User.get(session, name=username)
            if not user:
                logging.info("{}: No such user, creating...".format(username))
                user = User.get_or_create(session, username=username, role_user=args.role_user)
                session.commit()
            else:
                logging.info("{}: Already exists. Doing nothing.".format(username))

        return

    # "add_public_key" and "set_metadata"
    user = User.get(session, name=args.username)
    if not user:
        logging.error("{}: No such user. Doing nothing.".format(args.username))
        return

    # User must exist at this point.

    if args.subcommand == "set_metadata":
        print "Setting %s metadata: %s=%s" % (args.username, args.metadata_key, args.metadata_value)
        if args.metadata_value == "":
            args.metadata_value = None
        user.set_metadata(args.metadata_key, args.metadata_value)
        session.commit()
    elif args.subcommand == "add_public_key":
        print "Adding public key for user..."

        try:
            pubkey = public_key.add_public_key(session, user, args.public_key)
        except public_key.DuplicateKey:
            print "Key already in use."
            return
        except public_key.PublicKeyParseError:
            print "Public key appears to be invalid."
            return

        AuditLog.log(session, user.id, 'add_public_key',
                '(Administrative) Added public key: {}'.format(pubkey.fingerprint),
                on_user_id=user.id)
Пример #13
0
def test_public_key(session, users, http_client, base_url):
    user = users['*****@*****.**']
    assert not user.my_public_keys()

    good_key = ('ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCUQeasspT/etEJR2WUoR+h2sMOQYbJgr0Q'
            'E+J8p97gEhmz107KWZ+3mbOwyIFzfWBcJZCEg9wy5Paj+YxbGONqbpXAhPdVQ2TLgxr41bNXvbcR'
            'AxZC+Q12UZywR4Klb2kungKz4qkcmSZzouaKK12UxzGB3xQ0N+3osKFj3xA1+B6HqrVreU19XdVo'
            'AJh0xLZwhw17/NDM+dAcEdMZ9V89KyjwjraXtOVfFhQF0EDF0ame8d6UkayGrAiXC2He0P2Cja+J'
            '371P27AlNLHFJij8WGxvcGGSeAxMLoVSDOOllLCYH5UieV8mNpX1kNe2LeA58ciZb0AXHaipSmCH'
            'gh/ some-comment')

    bad_key = 'ssh-rsa AAAblahblahkey some-comment'

    # add it
    fe_url = url(base_url, '/users/{}/public-key/add'.format(user.username))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'public_key': good_key}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    # add bad key -- shouldn't add
    fe_url = url(base_url, '/users/{}/public-key/add'.format(user.username))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'public_key': bad_key}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    user = User.get(session, name=user.username)
    keys = user.my_public_keys()
    assert len(keys) == 1
    assert keys[0].public_key == good_key

    # delete it
    fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format(user.username, keys[0].id))
    resp = yield http_client.fetch(fe_url, method="POST", body='',
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    user = User.get(session, name=user.username)
    assert not user.my_public_keys()
Пример #14
0
    def get(self, user_id=None, name=None, key_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if (user.name != self.current_user.name) and not self.current_user.user_admin:
            return self.forbidden()

        key = self.session.query(PublicKey).filter_by(id=key_id, user_id=user.id).scalar()
        if not key:
            return self.notfound()

        self.render("public-key-delete.html", user=user, key=key)
Пример #15
0
def test_user_create(make_session, session, users):
    make_session.return_value = session

    # simple
    username = '******'
    call_main('user', 'create', username)
    assert User.get(session, name=username), 'non-existent user should be created'

    # check username
    bad_username = '******'
    call_main('user', 'create', bad_username)
    assert not User.get(session, name=bad_username), 'bad user should not be created'

    # bulk
    usernames = ['*****@*****.**', '*****@*****.**', '*****@*****.**']
    call_main('user', 'create', *usernames)
    users = [User.get(session, name=u) for u in usernames]
    assert all(users), 'all users created'

    usernames_with_one_bad = ['*****@*****.**', '*****@*****.**', 'not_valid_user']
    call_main('user', 'create', *usernames_with_one_bad)
    users = [User.get(session, name=u) for u in usernames_with_one_bad]
    assert not any(users), 'one bad seed means no users created'
Пример #16
0
    def get(self, user_id=None, name=None):
        self.handle_refresh()
        user = User.get(self.session, user_id, name)
        if user_id is not None:
            user = self.session.query(User).filter_by(id=user_id).scalar()
        else:
            user = self.session.query(User).filter_by(username=name).scalar()

        if not user:
            return self.notfound()

        can_control = user.name == self.current_user.name or self.current_user.user_admin
        can_disable = UserDisable.check_access(self.current_user, user)
        can_enable = UserEnable.check_access(self.current_user, user)

        if user.id == self.current_user.id:
            num_pending_group_requests = self.current_user.my_requests_aggregate().count()
            _, num_pending_perm_requests = get_requests_by_owner(self.session, self.current_user,
                    status='pending', limit=1, offset=0)
        else:
            num_pending_group_requests = None
            num_pending_perm_requests = None

        try:
            user_md = self.graph.get_user_details(user.name)
        except NoSuchUser:
            # Either user is probably very new, so they have no metadata yet, or
            # they're disabled, so we've excluded them from the in-memory graph.
            user_md = {}

        open_audits = user.my_open_audits()
        group_edge_list = group_biz.get_groups_by_user(self.session, user) if user.enabled else []
        groups = [{'name': g.name, 'type': 'Group', 'role': ge._role} for g, ge in group_edge_list]
        public_keys = user.my_public_keys()
        permissions = user_md.get('permissions', [])
        log_entries = user.my_log_entries()
        self.render("user.html",
                    user=user,
                    groups=groups,
                    public_keys=public_keys,
                    can_control=can_control,
                    permissions=permissions,
                    can_disable=can_disable,
                    can_enable=can_enable,
                    user_tokens=user.tokens,
                    log_entries=log_entries,
                    num_pending_group_requests=num_pending_group_requests,
                    num_pending_perm_requests=num_pending_perm_requests,
                    open_audits=open_audits,
                    )
Пример #17
0
    def post(self, user_id=None, name=None):

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if not self.check_access(self.current_user, user):
            return self.forbidden()

        user.disable()
        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, 'disable_user',
                     'Disabled user.', on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #18
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if (user.name != self.current_user.name) and not self.current_user.user_admin:
            return self.forbidden()

        form = PublicKeyForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "public-key-add.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        try:
            pubkey = public_key.add_public_key(self.session, user, form.data["public_key"])
        except public_key.PublicKeyParseError:
            form.public_key.errors.append(
                "Key failed to parse and is invalid."
            )
            return self.render(
                "public-key-add.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors),
            )
        except public_key.DuplicateKey:
            form.public_key.errors.append(
                "Key already in use. Public keys must be unique."
            )
            return self.render(
                "public-key-add.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(self.session, self.current_user.id, 'add_public_key',
                     'Added public key: {}'.format(pubkey.fingerprint),
                     on_user_id=user.id)

        email_context = {
                "actioner": self.current_user.name,
                "changed_user": user.name,
                "action": "added",
                }
        send_email(self.session, [user.name], 'Public SSH key added', 'ssh_keys_changed',
                settings, email_context)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #19
0
def test_oneoff(mock_make_session, mock_annex, mock_load_plugins, session):
    mock_make_session.return_value = session
    username = '******'
    other_username = '******'
    groupname = 'fake_group'

    class FakeOneOff(object):
        def configure(self, service_name):
            pass

        def run(self, session, **kwargs):
            if kwargs.get('group'):
                Group.get_or_create(session, groupname=groupname)
                session.commit()
            elif kwargs.get('key') == 'valuewith=':
                User.get_or_create(session, username=other_username)
                session.commit()
            else:
                User.get_or_create(session, username=username)
                session.commit()

    mock_annex.return_value = [FakeOneOff()]

    # dry_run
    call_main('oneoff', 'run', 'FakeOneOff')
    assert User.get(session, name=username) is None, 'default dry_run means no writes'
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, create a user
    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff')
    assert User.get(session, name=username) is not None, 'dry_run off means writes'
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, use kwarg to create a group
    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'group=1')
    assert User.get(session, name=username) is not None, 'dry_run off means writes'
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is not None, '"group" in arg so group created'

    # invalid format for argument should result in premature system exit
    with pytest.raises(SystemExit):
        call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'bad_arg')

    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'key=valuewith=')
    assert User.get(session, name=other_username) is not None, '"valuewith= in arg, create user2'
Пример #20
0
    def post(self, user_id=None, name=None, token_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if (user.name != self.current_user.name) and not self.current_user.user_admin:
            return self.forbidden()

        token = UserToken.get(self.session, user=user, id=token_id)
        token.disable()
        AuditLog.log(
            self.session,
            self.current_user.id,
            "disable_token",
            "Disabled token: {}".format(token.name),
            on_user_id=user.id,
        )
        self.session.commit()
        return self.render("user-token-disabled.html", token=token)
Пример #21
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if not self.check_access(self.current_user, user):
            return self.forbidden()

        form = UserEnableForm(self.request.arguments)
        if not form.validate():
            # TODO: add error message
            return self.redirect("/users/{}?refresh=yes".format(user.name))

        user.enable(self.current_user, preserve_membership=form.preserve_membership.data)
        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, 'enable_user',
                     'Enabled user.', on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #22
0
def group_command(args):
    session = make_session()
    group = session.query(Group).filter_by(groupname=args.groupname).scalar()
    if not group:
        logging.error("No such group %s".format(args.groupname))
        return

    for username in args.username:
        user = User.get(session, name=username)
        if not user:
            logging.error("no such user '{}'".format(username))
            return

        if args.subcommand == "add_member":
            if args.member:
                role = 'member'
            elif args.owner:
                role = 'owner'
            elif args.np_owner:
                role = 'np-owner'
            elif args.manager:
                role = 'manager'

            assert role

            logging.info("Adding {} as {} to group {}".format(username, role, args.groupname))
            group.add_member(user, user, "grouper-ctl join", status="actioned", role=role)
            AuditLog.log(
                session, user.id, 'join_group',
                '{} manually joined via grouper-ctl'.format(username),
                on_group_id=group.id)
            session.commit()

        elif args.subcommand == "remove_member":
            logging.info("Removing {} from group {}".format(username, args.groupname))
            group.revoke_member(user, user, "grouper-ctl remove")
            AuditLog.log(
                session, user.id, 'leave_group',
                '{} manually left via grouper-ctl'.format(username),
                on_group_id=group.id)
            session.commit()
Пример #23
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if user.name != self.current_user.name:
            return self.forbidden()

        form = UserTokenForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "user-token-add.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        try:
            token, secret = UserToken(name=form.data["name"], user=user).add(self.session)
            self.session.commit()
        except IntegrityError:
            self.session.rollback()
            form.name.errors.append(
                "Name already in use."
            )
            return self.render(
                "user-token-add.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(self.session, self.current_user.id, 'add_token',
                     'Added token: {}'.format(token.name),
                     on_user_id=user.id)

        email_context = {
                "actioner": self.current_user.name,
                "changed_user": user.name,
                "action": "added",
                }
        send_email(self.session, [user.name], 'User token created', 'user_tokens_changed',
                settings, email_context)
        return self.render("user-token-created.html", token=token, secret=secret)
Пример #24
0
def notify_edge_expiration(settings, session, edge):
    """Send notification that an edge has expired.

    Handles email notification and audit logging.

    Args:
        settings (Settings): Grouper Settings object for current run.
        session (Session): Object for db session.
        edge (GroupEdge): The expiring edge.
    """
    # TODO(herb): get around circular depdendencies; long term remove call to
    # send_async_email() from grouper.models
    from grouper.models import AuditLog, Group, OBJ_TYPES_IDX, User

    # TODO(rra): Arbitrarily use the first listed owner of the group from which membership expired
    # as the actor, since we have to provide an actor and we didn't record who set the expiration on
    # the edge originally.
    actor_id = next(edge.group.my_owners().itervalues()).id

    # Pull data about the edge and the affected user or group.
    group_name = edge.group.name
    if OBJ_TYPES_IDX[edge.member_type] == "User":
        user = User.get(session, pk=edge.member_pk)
        member_name = user.username
        recipients = [member_name]
        member_is_user = True
    else:
        subgroup = Group.get(session, pk=edge.member_pk)
        member_name = subgroup.groupname
        recipients = subgroup.my_owners_as_strings()
        member_is_user = False

    # Log to the audit log.  How depends on whether a user's membership has expired or a group's
    # membership has expired.
    audit_data = {
        "action": "expired_from_group",
        "actor_id": actor_id,
        "description": "{} expired out of the group".format(member_name),
    }
    if member_is_user:
        AuditLog.log(session, on_user_id=user.id, on_group_id=edge.group_id, **audit_data)
    else:
        # Make an audit log entry for both the subgroup and the parent group so that it will show up
        # in the FE view for both groups.
        AuditLog.log(session, on_group_id=edge.group_id, **audit_data)
        AuditLog.log(session, on_group_id=subgroup.id, **audit_data)

    # Send email notification to the affected people.
    email_context = {
        "group_name": group_name,
        "member_name": member_name,
        "member_is_user": member_is_user,
    }
    send_email(
        session=session,
        recipients=recipients,
        subject="Membership in {} expired".format(group_name),
        template="expiration",
        settings=settings,
        context=email_context,
    )
Пример #25
0
def test_permission_request_flow(session, standard_graph, groups, grantable_permissions,
        http_client, base_url):
    """Test that a permission request gets into the system correctly and
    notifications are sent correctly."""
    perm_grant, _, perm1, perm2 = grantable_permissions
    grant_permission(groups["all-teams"], perm_grant, argument="grantable.*")

    # REQUEST: 'grantable.one', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({"permission_name": "grantable.one", "argument": "some argument",
                "reason": "blah blah black sheep", "argument_type": "text"}),
            headers={'X-Grouper-User': username})
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "only one user (and no group) should receive notification for request"

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 1
    assert "grantable.one" not in perms, "requested permission shouldn't be granted immediately"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 0, "random user shouldn't have a request"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 1, "user in group with grant should have a request"

    # APPROVE grant: have '*****@*****.**' action this request as owner of
    # 'all-teams' which has the grant permission for the requested permission
    request_id = request_tuple.requests[0].id
    fe_url = url(base_url, "/permissions/requests/{}".format(request_id))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({"status": "actioned", "reason": "lgtm"}),
            headers={'X-Grouper-User': user.name})
    assert resp.code == 200

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 2
    assert "grantable.one" in perms, "requested permission shouldn't be granted immediately"

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "requester should receive email as well"

    # (re)REQUEST: 'grantable.one', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({"permission_name": "grantable.one", "argument": "some argument",
                "reason": "blah blah black sheep", "argument_type": "text"}),
            headers={'X-Grouper-User': username})
    assert resp.code == 200

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 0, "request for existing perm should fail"

    # REQUEST: 'grantable.two', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({"permission_name": "grantable.two", "argument": "some argument",
                "reason": "blah blah black sheep", "argument_type": "text"}),
            headers={'X-Grouper-User': username})
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "only one user (and no group) should receive notification for request"

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 2
    assert "grantable.two" not in perms, "requested permission shouldn't be granted immediately"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 0, "random user shouldn't have a request"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 1, "user in group with grant should have a request"

    # CANCEL request: have '*****@*****.**' cancel this request
    request_id = request_tuple.requests[0].id
    fe_url = url(base_url, "/permissions/requests/{}".format(request_id))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({"status": "cancelled", "reason": "heck no"}),
            headers={'X-Grouper-User': user.name})
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "rejection email should be sent"

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 2
    assert "grantable.two" not in perms, "no new permissions should be granted for this"
Пример #26
0
    def post(self, group_id=None, name=None, name2=None, member_type=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        if self.current_user.name == name2:
            return self.forbidden()

        members = group.my_members()
        my_role = self.current_user.my_role(members)
        if my_role not in ("manager", "owner", "np-owner"):
            return self.forbidden()

        member = members.get((member_type.capitalize(), name2), None)
        if not member:
            return self.notfound()

        if member.type == "Group":
            user_or_group = Group.get(self.session, member.id)
        else:
            user_or_group = User.get(self.session, member.id)
        if not user_or_group:
            return self.notfound()

        edge = GroupEdge.get(
            self.session,
            group_id=group.id,
            member_type=OBJ_TYPES[member.type],
            member_pk=member.id,
        )
        if not edge:
            return self.notfound()

        form = GroupEditMemberForm(self.request.arguments)
        form.role.choices = [["member", "Member"]]
        if my_role in ("owner", "np-owner"):
            form.role.choices.append(["manager", "Manager"])
            form.role.choices.append(["owner", "Owner"])
            form.role.choices.append(["np-owner", "No-Permissions Owner"])

        if not form.validate():
            return self.render(
                "group-edit-member.html", group=group, member=member, edge=edge, form=form,
                alerts=self.get_form_alerts(form.errors),
            )

        fail_message = 'This join is denied with this role at this time.'
        try:
            user_can_join = assert_can_join(group, user_or_group, role=form.data["role"])
        except UserNotAuditor as e:
            user_can_join = False
            fail_message = e
        if not user_can_join:
            return self.render(
                "group-edit-member.html", form=form, group=group, member=member, edge=edge,
                alerts=[
                    Alert('danger', fail_message, 'Audit Policy Enforcement')
                ]
            )

        expiration = None
        if form.data["expiration"]:
            expiration = datetime.strptime(form.data["expiration"], "%m/%d/%Y")

        group.edit_member(self.current_user, user_or_group, form.data["reason"],
                          role=form.data["role"], expiration=expiration)

        return self.redirect("/groups/{}?refresh=yes".format(group.name))