Beispiel #1
0
def test_user_status_changes(session, tmpdir, users, groups):  # noqa: F811
    username = "******"
    groupname = "team-sre"

    # add user to a group
    call_main(session, tmpdir, "group", "add_member", "--member", groupname, username)

    # disable the account
    call_main(session, tmpdir, "user", "disable", username)
    assert not User.get(session, name=username).enabled

    # double disabling is a no-op
    call_main(session, tmpdir, "user", "disable", username)
    assert not User.get(session, name=username).enabled

    # re-enable the account, preserving memberships
    call_main(session, tmpdir, "user", "enable", "--preserve-membership", username)
    assert User.get(session, name=username).enabled
    assert (u"User", username) in groups[groupname].my_members()

    # enabling an active account is a no-op
    call_main(session, tmpdir, "user", "enable", username)
    assert User.get(session, name=username).enabled

    # disable and re-enable without the --preserve-membership flag
    call_main(session, tmpdir, "user", "disable", username)
    call_main(session, tmpdir, "user", "enable", username)
    assert User.get(session, name=username).enabled
    assert (u"User", username) not in groups[groupname].my_members()
Beispiel #2
0
def test_add_service_account(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    fe_url = url(base_url, '/service/create')
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'name': '*****@*****.**', "description": "Hi", "canjoin": "canjoin"}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    assert User.get(session, name="*****@*****.**") is None
    assert Group.get(session, name="*****@*****.**") is None

    # Add account
    fe_url = url(base_url, '/service/create')
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'name': '*****@*****.**', "description": "Hi", "canjoin": "canjoin"}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_service_account(session, user=u)
    assert is_service_account(session, group=g)
    assert get_service_account(session, user=u).group.id == g.id
    assert get_service_account(session, group=g).user.id == u.id
    assert not is_service_account(session, user=user)
    assert not is_service_account(session, group=Group.get(session, name="team-sre"))
def test_sa_pubkeys(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin')

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_role_user(session, user=u)
    assert is_role_user(session, group=g)
    assert get_role_user(session, user=u).group.id == g.id
    assert get_role_user(session, group=g).user.id == u.id
    assert not is_role_user(session, user=user)
    assert not is_role_user(session, group=Group.get(session, name="team-sre"))

    assert not get_public_keys_of_user(session, user.id)

    with pytest.raises(HTTPError):
        # add it
        fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**"))
        resp = yield http_client.fetch(fe_url, method="POST",
                body=urlencode({'public_key': SSH_KEY_1}),
                headers={'X-Grouper-User': "******"})

    # add it
    fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'public_key': SSH_KEY_1}),
            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("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'public_key': SSH_KEY_BAD}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    sa = User.get(session, name="*****@*****.**")
    keys = get_public_keys_of_user(session, sa.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1

    with pytest.raises(HTTPError):
        # delete it
        fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format("*****@*****.**", keys[0].id))
        resp = yield http_client.fetch(fe_url, method="POST", body='',
                headers={'X-Grouper-User': "******"})

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

    sa = User.get(session, name="*****@*****.**")
    assert not get_public_keys_of_user(session, sa.id)
Beispiel #4
0
def create_role_user(session, actor, name, description, canjoin):
    # type (Session, User, str, str, str) -> None
    """DEPRECATED: Do not use in production code

    Creates a service account with the given name, description, and canjoin status

    Args:
        session: the database session
        actor: the user creating the service account
        name: the name of the service account
        description: description of the service account
        canjoin: the canjoin status for management of the service account

    Throws:
        IntegrityError: if a user or group with the given name already exists
    """
    user = User(username=name, role_user=True)
    group = Group(groupname=name, description=description, canjoin=canjoin)

    user.add(session)
    group.add(session)

    group.add_member(actor, actor, "Group Creator", "actioned", None, "np-owner")
    group.add_member(actor, user, "Service Account", "actioned", None, "member")
    session.commit()

    AuditLog.log(
        session,
        actor.id,
        "create_role_user",
        "Created new service account.",
        on_group_id=group.id,
        on_user_id=user.id,
    )
Beispiel #5
0
 def create_user(self, name):
     # type: (str) -> None
     """Create a user, does nothing if it already exists."""
     if User.get(self.session, name=name):
         return
     user = User(username=name)
     user.add(self.session)
def test_public_key(session, users, http_client, base_url):
    user = users['*****@*****.**']
    assert not get_public_keys_of_user(session, user.id)

    # 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': SSH_KEY_1}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    user = User.get(session, name=user.username)
    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1
    assert keys[0].fingerprint == 'e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35'
    assert keys[0].fingerprint_sha256 == 'MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU'
    assert keys[0].comment == 'some-comment'

    # 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 get_public_keys_of_user(session, user.id)
Beispiel #7
0
def test_public_key_admin(session, users, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]
    assert not get_public_keys_of_user(session, user.id)

    # 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": SSH_KEY_1}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1

    # have an admin 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": "******"}
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    assert not get_public_keys_of_user(session, user.id)
Beispiel #8
0
def test_public_key(session, users, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]
    assert not get_public_keys_of_user(session, user.id)

    # 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": SSH_KEY_ED25519}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_ED25519
    assert keys[0].fingerprint == "fa:d9:ca:40:bd:f7:64:37:a7:99:3a:8e:50:8a:c5:94"
    assert keys[0].fingerprint_sha256 == "ExrCZ0nqSJv+LqAEh8CWeKUxiAeZA+N0bKC18dK7Adg"
    assert keys[0].comment == "comment"

    # 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 get_public_keys_of_user(session, user.id)
Beispiel #9
0
def create_service_account(session, actor, name, description, machine_set, owner):
    # type: (Session, User, str, str, str, Group) -> ServiceAccount
    """Creates a service account and its underlying user.

    Also adds the service account to the list of accounts managed by the owning group.

    Throws:
        BadMachineSet: if some plugin rejected the machine set
        DuplicateServiceAccount: if a user with the given name already exists
    """
    user = User(username=name, is_service_account=True)
    service_account = ServiceAccount(user=user, description=description, machine_set=machine_set)

    if machine_set is not None:
        _check_machine_set(service_account, machine_set)

    try:
        user.add(session)
        service_account.add(session)
        session.flush()
    except IntegrityError:
        session.rollback()
        raise DuplicateServiceAccount("User {} already exists".format(name))

    # Counter is updated here and the session is committed, so we don't need an additional update
    # or commit for the account creation.
    add_service_account(session, owner, service_account)

    AuditLog.log(session, actor.id, "create_service_account", "Created new service account.",
                 on_group_id=owner.id, on_user_id=service_account.user_id)

    return service_account
Beispiel #10
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 = get_public_keys_of_user(session, user.id)
    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 = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == good_key
Beispiel #11
0
def test_user_status_changes(make_user_session, make_group_session, session, users, groups):
    make_user_session.return_value = session
    make_group_session.return_value = session

    username = '******'
    groupname = 'team-sre'

    # add user to a group
    call_main('group', 'add_member', '--member', groupname, username)

    # disable the account
    call_main('user', 'disable', username)
    assert not User.get(session, name=username).enabled

    # double disabling is a no-op
    call_main('user', 'disable', username)
    assert not User.get(session, name=username).enabled

    # re-enable the account, preserving memberships
    call_main('user', 'enable', '--preserve-membership', username)
    assert User.get(session, name=username).enabled
    assert (u'User', username) in groups[groupname].my_members()

    # enabling an active account is a no-op
    call_main('user', 'enable', username)
    assert User.get(session, name=username).enabled

    # disable and re-enable without the --preserve-membership flag
    call_main('user', 'disable', username)
    call_main('user', 'enable', username)
    assert User.get(session, name=username).enabled
    assert (u'User', username) not in groups[groupname].my_members()
Beispiel #12
0
def users(session):
    users = {
        username: User.get_or_create(session, username=username)[0]
        for username in ("*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**",
                "*****@*****.**", "*****@*****.**", "*****@*****.**")
    }
    users["*****@*****.**"] = User.get_or_create(session, username="******", role_user=True)[0]
    session.commit()
    return users
Beispiel #13
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()
Beispiel #14
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()
Beispiel #15
0
    def create_role_user(self, role_user, description="", join_policy=GroupJoinPolicy.CAN_ASK):
        # type: (str, str, GroupJoinPolicy) -> None
        """Create an old-style role user.

        This concept is obsolete and all code related to it will be deleted once all remaining
        legacy role users have been converted to service accounts.  This method should be used only
        for tests to maintain backward compatibility until that happens.
        """
        user = User(username=role_user, role_user=True)
        user.add(self.session)
        self.create_group(role_user, description, join_policy)
        self.add_user_to_group(role_user, role_user)
Beispiel #16
0
def test_user_public_key(make_session, session, users):
    make_session.return_value = session

    # good key
    username = '******'
    call_main('user', 'add_public_key', username, SSH_KEY_1)

    user = User.get(session, name=username)
    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1

    # duplicate key
    call_main('user', 'add_public_key', username, SSH_KEY_1)

    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1

    # bad key
    call_main('user', 'add_public_key', username, SSH_KEY_BAD)

    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1
Beispiel #17
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

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

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

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

        new_username = form.data["username"]
        if new_username == "":
            new_username = None
        set_user_metadata(self.session, user.id, USER_METADATA_GITHUB_USERNAME_KEY, new_username)

        AuditLog.log(
            self.session,
            self.current_user.id,
            "changed_github_username",
            "Changed GitHub username: {}".format(form.data["username"]),
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Beispiel #18
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
Beispiel #19
0
def get_role_user(session, user=None, group=None):
    # type: (Session, User, Group) -> RoleUser
    """
    Takes in a User or a Group and returns a dictionary that contains
    all of the service account components for the service account that
    the user/group is part of.

    Args:
        session: the database session
        user: a User object to check
        group: a Group object to check

    Throws:
        RoleUserNotFound: if the user or group is not part of a service account

    Returns:
        a dictionary with all components of the service account of the
            user or group passed in
    """
    if not is_role_user(session, user, group):
        raise RoleUserNotFound()

    if user:
        name = user.name
    else:
        assert group is not None
        name = group.name
    return RoleUser(User.get(session, name=name), Group.get(session, name=name))
Beispiel #20
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.session, self.current_user, user):
            return self.forbidden()

        form = UserShellForm(self.request.arguments)
        form.shell.choices = settings.shell
        if not form.validate():
            return self.render(
                "user-shell.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        user.set_metadata(USER_METADATA_SHELL_KEY, form.data["shell"])
        user.add(self.session)
        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, 'changed_shell',
                     'Changed shell: {}'.format(form.data["shell"]),
                     on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Beispiel #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.session, 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))

        if user.role_user:
            enable_service_account(self.session, actor=self.current_user,
                preserve_membership=form.preserve_membership.data, user=user)
        else:
            enable_user(self.session, user, 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))
Beispiel #22
0
    def role(self, role):
        prev_role = self._role
        self._role = GROUP_EDGE_ROLES.index(role)

        # Groups should always "member".
        if not (OBJ_TYPES_IDX[self.member_type] == "User"):
            return

        # If ownership status is unchanged, no notices need to be adjusted.
        if (self._role in OWNER_ROLE_INDICES) == (prev_role in OWNER_ROLE_INDICES):
            return

        recipient = User.get(self.session, pk=self.member_pk).username
        expiring_supergroups = self.group.my_expiring_groups()
        member_name = self.group.name

        if role in ["owner", "np-owner"]:
            # We're creating a new owner, who should find out when this group
            # they now own loses its membership in larger groups.
            for supergroup_name, expiration in expiring_supergroups:
                AsyncNotification.add_expiration(self.session,
                                                 expiration,
                                                 group_name=supergroup_name,
                                                 member_name=member_name,
                                                 recipients=[recipient],
                                                 member_is_user=False)
        else:
            # We're removing an owner, who should no longer find out when this
            # group they no longer own loses its membership in larger groups.
            for supergroup_name, _ in expiring_supergroups:
                AsyncNotification.cancel_expiration(self.session,
                                                    group_name=supergroup_name,
                                                    member_name=member_name,
                                                    recipients=[recipient])
Beispiel #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 not self.check_access(self.session, self.current_user, user):
            return self.forbidden()

        try:
            if user.role_user:
                disable_role_user(self.session, user=user)
            else:
                disable_user(self.session, user)
        except PluginRejectedDisablingUser as e:
            alert = Alert("danger", str(e))
            return self.redirect("/users/{}".format(user.name), alerts=[alert])

        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))
Beispiel #24
0
def is_role_user(session, user=None, group=None):
    # type: (Session, User, Group) -> bool
    """
    Takes in a User or a Group and returns a boolean indicating whether
    that User/Group is a component of a service account.

    Args:
        session: the database session
        user: a User object to check
        group: a Group object to check

    Throws:
        AssertionError if neither a user nor a group is provided

    Returns:
        whether the User/Group is a component of a service account
    """
    if user is not None:
        return user.role_user

    assert group is not None
    user = User.get(session, name=group.groupname)
    if not user:
        return False

    return user.role_user
Beispiel #25
0
    def post(self):
        supplied_token = self.get_body_argument("token")
        match = TokenValidate.validator.match(supplied_token)
        if not match:
            return self.error(((1, "Token format not recognized"),))

        sess = Session()

        token_name = match.group("token_name")
        token_secret = match.group("token_secret")
        owner = User.get(sess, name=match.group("name"))

        token = UserToken.get(sess, owner, token_name)
        if token is None:
            return self.error(((2, "Token specified does not exist"),))
        if not token.enabled:
            return self.error(((3, "Token is disabled"),))
        if not token.check_secret(token_secret):
            return self.error(((4, "Token secret mismatch"),))

        return self.success({
            "owner": owner.username,
            "identity": str(token),
            "act_as_owner": True,
            "valid": True,
        })
Beispiel #26
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 not self.check_access(self.session, self.current_user, user):
            return self.forbidden()

        try:
            key = get_public_key(self.session, user.id, key_id)
            delete_public_key(self.session, user.id, key_id)
        except KeyNotFound:
            return self.notfound()

        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))
Beispiel #27
0
    def cancel_user_request(self, user_request, reason, authorization):
        # type: (UserGroupRequest, str, Authorization) -> None
        now = datetime.utcnow()
        request = Request.get(self.session, id=user_request.id)
        if not request:
            raise UserGroupRequestNotFoundException(request)
        actor = User.get(self.session, name=authorization.actor)
        if not actor:
            raise UserNotFoundException(authorization.actor)

        request_status_change = RequestStatusChange(
            request=request,
            user_id=actor.id,
            from_status=request.status,
            to_status="cancelled",
            change_at=now,
        ).add(self.session)

        request.status = "cancelled"
        self.session.flush()

        Comment(
            obj_type=OBJ_TYPES["RequestStatusChange"],
            obj_pk=request_status_change.id,
            user_id=actor.id,
            comment=reason,
            created_on=now,
        ).add(self.session)
Beispiel #28
0
    def get(self, user_id=None, name=None):
        self.handle_refresh()

        user = User.get(self.session, user_id, name)

        if not user:
            return self.notfound()

        if user.role_user:
            return self.redirect("/service/{}".format(user_id or name))

        if user.is_service_account:
            service_account = user.service_account
            if service_account.owner:
                return self.redirect("/groups/{}/service/{}".format(
                    service_account.owner.group.name, user.username))
            else:
                self.render(
                    "service-account.html", service_account=service_account, group=None, user=user,
                    **get_user_view_template_vars(self.session, self.current_user, user, self.graph)
                )
                return

        self.render("user.html",
                    user=user,
                    **get_user_view_template_vars(self.session, self.current_user, user, self.graph)
                    )
Beispiel #29
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

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

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

        form = UserShellForm(self.request.arguments)
        form.shell.choices = settings().shell
        if not form.validate():
            return self.render(
                "user-shell.html", form=form, user=user, alerts=self.get_form_alerts(form.errors)
            )

        set_user_metadata(self.session, user.id, USER_METADATA_SHELL_KEY, form.data["shell"])

        AuditLog.log(
            self.session,
            self.current_user.id,
            "changed_shell",
            "Changed shell: {}".format(form.data["shell"]),
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Beispiel #30
0
def test_sa_tokens(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin')

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_role_user(session, user=u)
    assert is_role_user(session, group=g)
    assert get_role_user(session, user=u).group.id == g.id
    assert get_role_user(session, group=g).user.id == u.id
    assert not is_role_user(session, user=user)
    assert not is_role_user(session, group=Group.get(session, name="team-sre"))

    with pytest.raises(HTTPError):
        # Add token
        fe_url = url(base_url, '/users/{}/tokens/add'.format("*****@*****.**"))
        resp = yield http_client.fetch(fe_url, method="POST",
                body=urlencode({'name': 'myDHDToken'}),
                headers={'X-Grouper-User': "******"})

    # Add token
    fe_url = url(base_url, '/users/{}/tokens/add'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'name': 'myDHDToken'}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    # Verify add
    fe_url = url(base_url, '/users/{}'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="GET",
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200
    assert "Added token: myDHDToken" in resp.body

    with pytest.raises(HTTPError):
        # Disable token
        fe_url = url(base_url, '/users/{}/tokens/1/disable'.format("*****@*****.**"))
        resp = yield http_client.fetch(fe_url, method="POST",
                body="",
                headers={'X-Grouper-User': "******"})

    # Disable token
    fe_url = url(base_url, '/users/{}/tokens/1/disable'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body="",
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    # Verify disable
    fe_url = url(base_url, '/users/{}'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="GET",
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200
    assert "Disabled token: myDHDToken" in resp.body
Beispiel #31
0
    def promote_nonauditors(self, session):
        # type: (Session) -> None
        """Checks all enabled audited groups and ensures that all approvers for that group have
        the PERMISSION_AUDITOR permission. All non-auditor approvers of audited groups will be
        promoted to be auditors, i.e., added to the auditors group.

        Args:
            session (Session): database session
        """
        graph = Graph()
        # Hack to ensure the graph is loaded before we access it
        graph.update_from_db(session)
        # map from user object to names of audited groups in which
        # user is a nonauditor approver
        nonauditor_approver_to_groups = defaultdict(
            set)  # type: Dict[User, Set[str]]
        user_is_auditor = {}  # type: Dict[str, bool]
        for group_tuple in graph.get_groups(audited=True,
                                            directly_audited=False):
            group_md = graph.get_group_details(group_tuple.groupname,
                                               expose_aliases=False)
            for username, user_md in iteritems(group_md["users"]):
                if username not in user_is_auditor:
                    user_perms = graph.get_user_details(
                        username)["permissions"]
                    user_is_auditor[username] = any([
                        p["permission"] == PERMISSION_AUDITOR
                        for p in user_perms
                    ])
                if user_is_auditor[username]:
                    # user is already auditor so can skip
                    continue
                if user_md["role"] in APPROVER_ROLE_INDICES:
                    # non-auditor approver. BAD!
                    nonauditor_approver_to_groups[username].add(
                        group_tuple.groupname)

        if nonauditor_approver_to_groups:
            auditors_group = get_auditors_group(self.settings, session)
            for username, group_names in iteritems(
                    nonauditor_approver_to_groups):
                reason = "auto-added due to having approver role(s) in group(s): {}".format(
                    ", ".join(group_names))
                user = User.get(session, name=username)
                assert user
                auditors_group.add_member(user,
                                          user,
                                          reason,
                                          status="actioned")
                notify_nonauditor_promoted(self.settings, session, user,
                                           auditors_group, group_names)

        session.commit()
Beispiel #32
0
def test_user_create(session, tmpdir, users):  # noqa: F811
    # simple
    username = "******"
    call_main(session, tmpdir, "user", "create", username)
    assert User.get(session, name=username), "non-existent user should be created"

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

    # bulk
    usernames = ["*****@*****.**", "*****@*****.**", "*****@*****.**"]
    call_main(session, tmpdir, "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(session, tmpdir, "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"
Beispiel #33
0
    def get(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.session, self.current_user, user):
            return self.forbidden()

        form = UserShellForm()
        form.shell.choices = settings.shell

        self.render("user-shell.html", form=form, user=user)
Beispiel #34
0
def test_github(session, users, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]
    assert get_user_metadata_by_key(session, user.id,
                                    USER_METADATA_GITHUB_USERNAME_KEY) is None

    user = User.get(session, name=user.username)
    fe_url = url(base_url, "/users/{}/github".format(user.username))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"username": "******"}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200
    user = User.get(session, name=user.username)
    assert (get_user_metadata_by_key(session, user.id,
                                     USER_METADATA_GITHUB_USERNAME_KEY)
            is not None)
    assert (get_user_metadata_by_key(
        session, user.id,
        USER_METADATA_GITHUB_USERNAME_KEY).data_value == "joe-on-github")

    audit_entries = AuditLog.get_entries(session,
                                         on_user_id=user.id,
                                         action="changed_github_username")
    assert len(audit_entries) == 1
    assert audit_entries[
        0].description == "Changed GitHub username: joe-on-github"

    fe_url = url(base_url, "/users/{}/github".format(user.username))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"username": ""}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200
    user = User.get(session, name=user.username)
    assert get_user_metadata_by_key(session, user.id,
                                    USER_METADATA_GITHUB_USERNAME_KEY) is None
Beispiel #35
0
def mutate_group_command(session, group, args):
    # type: (Session, Group, Namespace) -> None
    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))

            try:
                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()
            except PluginRejectedGroupMembershipUpdate as e:
                logging.error("%s", e)
Beispiel #36
0
    def get(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")
        token_id = int(self.get_path_argument("token_id"))

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

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

        token = UserToken.get(self.session, user=user, id=token_id)
        return self.render("user-token-disable.html", user=user, token=token)
def create_service_account(session, actor, name, description, machine_set,
                           owner):
    # type: (Session, User, str, str, str, Group) -> ServiceAccount
    """Creates a service account and its underlying user.

    Also adds the service account to the list of accounts managed by the owning group.

    Throws:
        BadMachineSet: if some plugin rejected the machine set
        DuplicateServiceAccount: if a user with the given name already exists
    """
    user = User(username=name, is_service_account=True)
    service_account = ServiceAccount(user=user,
                                     description=description,
                                     machine_set=machine_set)

    if machine_set is not None:
        _check_machine_set(service_account, machine_set)

    try:
        user.add(session)
        service_account.add(session)
        session.flush()
    except IntegrityError:
        session.rollback()
        raise DuplicateServiceAccount("User {} already exists".format(name))

    # Counter is updated here and the session is committed, so we don't need an additional update
    # or commit for the account creation.
    add_service_account(session, owner, service_account)

    AuditLog.log(session,
                 actor.id,
                 "create_service_account",
                 "Created new service account.",
                 on_group_id=owner.id,
                 on_user_id=service_account.user_id)

    return service_account
Beispiel #38
0
    def get(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

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

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

        self.render("user-token-add.html", form=UserTokenForm(), user=user)
Beispiel #39
0
    def get(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

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

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

        self.render("user-password-add.html",
                    form=UserPasswordForm(),
                    user=user)
    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.session, self.current_user, user):
            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.DuplicateKey:
            form.public_key.errors.append(
                "Key already in use. Public keys must be unique.")
        except public_key.PublicKeyParseError:
            form.public_key.errors.append("Public key appears to be invalid.")
        except public_key.BadPublicKey as e:
            form.public_key.errors.append(e.message)

        if form.public_key.errors:
            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_sha256),
                     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))
Beispiel #41
0
    def permission_grants_for_user(self, username):
        # type: (str) -> List[PermissionGrant]
        now = datetime.utcnow()
        user = User.get(self.session, name=username)
        if not user or user.role_user or user.is_service_account or not user.enabled:
            return []

        # Get the groups of which this user is a direct member.
        groups = (self.session.query(Group.id).join(
            GroupEdge, Group.id == GroupEdge.group_id).join(
                User, User.id == GroupEdge.member_pk).filter(
                    Group.enabled == True,
                    User.id == user.id,
                    GroupEdge.active == True,
                    GroupEdge.member_type == OBJ_TYPES["User"],
                    GroupEdge._role != GROUP_EDGE_ROLES.index("np-owner"),
                    or_(GroupEdge.expiration > now,
                        GroupEdge.expiration == None),
                ).distinct())
        group_ids = [g.id for g in groups]

        # Now, get the parent groups of those groups and so forth until we run out of levels of the
        # tree.  Use a set of seen group_ids to avoid querying the same group twice if a user is a
        # member of it via multiple paths.
        seen_group_ids = set(group_ids)
        while group_ids:
            parent_groups = (self.session.query(Group.id).join(
                GroupEdge, Group.id == GroupEdge.group_id).filter(
                    GroupEdge.member_pk.in_(group_ids),
                    Group.enabled == True,
                    GroupEdge.active == True,
                    GroupEdge.member_type == OBJ_TYPES["Group"],
                    GroupEdge._role != GROUP_EDGE_ROLES.index("np-owner"),
                    or_(GroupEdge.expiration > now,
                        GroupEdge.expiration == None),
                ).distinct())
            group_ids = [
                g.id for g in parent_groups if g.id not in seen_group_ids
            ]
            seen_group_ids.update(group_ids)

        # Return the permission grants.
        group_permission_grants = (self.session.query(
            Permission.name, PermissionMap.argument).filter(
                Permission.id == PermissionMap.permission_id,
                PermissionMap.group_id.in_(seen_group_ids),
            ).all())
        return [
            PermissionGrant(g.name, g.argument)
            for g in group_permission_grants
        ]
Beispiel #42
0
def test_user_status_changes(
        make_user_session,
        make_group_session,
        session,
        users,
        groups  # noqa: F811
):
    make_user_session.return_value = session
    make_group_session.return_value = session

    username = "******"
    groupname = "team-sre"

    # add user to a group
    call_main(session, "group", "add_member", "--member", groupname, username)

    # disable the account
    call_main(session, "user", "disable", username)
    assert not User.get(session, name=username).enabled

    # double disabling is a no-op
    call_main(session, "user", "disable", username)
    assert not User.get(session, name=username).enabled

    # re-enable the account, preserving memberships
    call_main(session, "user", "enable", "--preserve-membership", username)
    assert User.get(session, name=username).enabled
    assert (u"User", username) in groups[groupname].my_members()

    # enabling an active account is a no-op
    call_main(session, "user", "enable", username)
    assert User.get(session, name=username).enabled

    # disable and re-enable without the --preserve-membership flag
    call_main(session, "user", "disable", username)
    call_main(session, "user", "enable", username)
    assert User.get(session, name=username).enabled
    assert (u"User", username) not in groups[groupname].my_members()
Beispiel #43
0
    def get(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

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

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

        form = UserShellForm()
        form.shell.choices = settings().shell

        self.render("user-shell.html", form=form, user=user)
    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 not self.check_access(self.session, self.current_user, user):
            return self.forbidden()

        try:
            key = get_public_key(self.session, user.id, key_id)
        except KeyNotFound:
            return self.notfound()

        self.render("public-key-delete.html", user=user, key=key)
Beispiel #45
0
    def get(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")
        password_id = int(self.get_path_argument("password_id"))

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

        if not self.check_access(self.session, self.current_user, user):
            return self.forbidden()
        password = UserPassword.get(self.session, user=user, id=password_id)
        return self.render("user-password-delete.html",
                           user=user,
                           password=password)
Beispiel #46
0
def create_role_user(session, actor, name, description, canjoin):
    # type (Session, User, str, str, str) -> None
    """DEPRECATED: Do not use in production code

    Creates a service account with the given name, description, and canjoin status

    Args:
        session: the database session
        actor: the user creating the service account
        name: the name of the service account
        description: description of the service account
        canjoin: the canjoin status for management of the service account

    Throws:
        IntegrityError: if a user or group with the given name already exists
    """
    user = User(username=name, role_user=True)
    group = Group(groupname=name, description=description, canjoin=canjoin)

    user.add(session)
    group.add(session)

    group.add_member(actor, actor, "Group Creator", "actioned", None,
                     "np-owner")
    group.add_member(actor, user, "Service Account", "actioned", None,
                     "member")
    session.commit()

    AuditLog.log(
        session,
        actor.id,
        "create_role_user",
        "Created new service account.",
        on_group_id=group.id,
        on_user_id=user.id,
    )
Beispiel #47
0
 def get_group(self, name):
     # type: (str) -> Optional[Group]
     group = SQLGroup.get(self.session, name=name)
     if not group:
         return None
     user = SQLUser.get(self.session, name=name)
     is_role_user = user.role_user if user else False
     return Group(
         name=group.groupname,
         description=group.description,
         email_address=group.email_address,
         join_policy=GroupJoinPolicy(group.canjoin),
         enabled=group.enabled,
         is_role_user=is_role_user,
     )
Beispiel #48
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 not self.check_access(self.session, self.current_user, user):
            return self.forbidden()

        token = UserToken.get(self.session, user=user, id=token_id)
        disable_user_token(self.session, token)
        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)
Beispiel #49
0
 def grant_permission_to_service_account(self, permission, argument,
                                         service_account):
     # type: (str, str, str) -> None
     self.create_permission(permission)
     permission_obj = Permission.get(self.session, name=permission)
     assert permission_obj
     user_obj = User.get(self.session, name=service_account)
     assert user_obj, "Must create the service account first"
     assert user_obj.is_service_account
     grant = ServiceAccountPermissionMap(
         permission_id=permission_obj.id,
         service_account_id=user_obj.service_account.id,
         argument=argument,
     )
     grant.add(self.session)
Beispiel #50
0
def test_public_key(session, users, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]
    assert not get_public_keys_of_user(session, user.id)

    # 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": SSH_KEY_ED25519}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_ED25519
    assert keys[
        0].fingerprint == "fa:d9:ca:40:bd:f7:64:37:a7:99:3a:8e:50:8a:c5:94"
    assert keys[
        0].fingerprint_sha256 == "ExrCZ0nqSJv+LqAEh8CWeKUxiAeZA+N0bKC18dK7Adg"
    assert keys[0].comment == "comment"

    # 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 get_public_keys_of_user(session, user.id)
Beispiel #51
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

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

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

        metadata_key = self.get_path_argument("key")

        if metadata_key == USER_METADATA_SHELL_KEY:
            return self.redirect("/users/{}/shell".format(user.name))
        elif metadata_key == USER_METADATA_GITHUB_USERNAME_KEY:
            return self.redirect("/github/link_begin/{}".format(user.id))

        known_field = metadata_key in settings().metadata_options
        metadata_item = get_user_metadata_by_key(self.session, user.id,
                                                 metadata_key)
        if not metadata_item and not known_field:
            return self.notfound()

        form = UserMetadataForm(self.request.arguments)
        form.value.choices = settings().metadata_options.get(
            metadata_key, DEFAULT_METADATA_OPTIIONS)
        if not form.validate():
            return self.render(
                "user-metadata.html",
                form=form,
                user=user,
                metadata_key=metadata_key,
                is_enabled=known_field,
                alerts=self.get_form_alerts(form.errors),
            )

        set_user_metadata(self.session, user.id, metadata_key,
                          form.data["value"])

        AuditLog.log(
            self.session,
            self.current_user.id,
            "changed_user_metadata",
            "Changed {}: {}".format(metadata_key, form.data["value"]),
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Beispiel #52
0
    def get(self, user_id=None, name=None):
        self.handle_refresh()
        user = User.get(self.session, user_id, name)

        if not user or not user.role_user:
            return self.notfound()

        group = Group.get(self.session, name=name)
        actor = self.current_user
        graph = self.graph
        session = self.session
        self.render("service.html",
                    user=user,
                    group=group,
                    **get_role_user_view_template_vars(session, actor, user,
                                                       group, graph))
Beispiel #53
0
def test_user_created_plugin(session, users, groups):
    """Test calls to the user_created plugin."""
    plugin = UserCreatedPlugin()
    grouper.plugin.Plugins = [plugin]

    # Create a regular user.  The service account flag should be false, and the plugin should be
    # called.
    user, created = User.get_or_create(session, username="******")
    assert created == True
    assert plugin.calls == 1

    # Create a role user.  This should cause another plugin call and the service account flag
    # should now be true.
    plugin.expected_service_account = True
    create_role_user(session, user, "*****@*****.**", "description", "canask")
    assert plugin.calls == 2
Beispiel #54
0
    def get(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

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

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

        form = UserShellForm()
        form.shell.choices = settings().shell

        self.render("user-shell.html", form=form, user=user)
Beispiel #55
0
 def add_public_key_to_user(self, key, user):
     # type: (str, str) -> None
     sql_user = User.get(self.session, name=user)
     assert sql_user
     public_key = SSHKey(key, strict=True)
     public_key.parse()
     sql_public_key = PublicKey(
         user_id=sql_user.id,
         public_key=public_key.keydata.strip(),
         fingerprint=public_key.hash_md5().replace("MD5:", ""),
         fingerprint_sha256=public_key.hash_sha256().replace("SHA256:", ""),
         key_size=public_key.bits,
         key_type=public_key.key_type,
         comment=public_key.comment,
     )
     sql_public_key.add(self.session)
Beispiel #56
0
 def add_user_to_group(self, user, group, role="member"):
     # type: (str, str, str) -> None
     self.create_user(user)
     self.create_group(group)
     user_obj = User.get(self.session, name=user)
     assert user_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     edge = GroupEdge(
         group_id=group_obj.id,
         member_type=OBJ_TYPES["User"],
         member_pk=user_obj.id,
         active=True,
         _role=GROUP_EDGE_ROLES.index(role),
     )
     edge.add(self.session)
Beispiel #57
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.session, self.current_user, user):
            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 = add_new_user_token(
                self.session, UserToken(name=form.data["name"], user=user))
            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)
Beispiel #58
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

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

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

        try:
            if user.role_user:
                disable_role_user(self.session, user=user)
            else:
                disable_user(self.session, user)
        except PluginRejectedDisablingUser as e:
            alert = Alert("danger", str(e))
            return self.redirect("/users/{}".format(user.name), alerts=[alert])

        self.session.commit()

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

        if user.role_user:
            group = Group.get(self.session, name=user.username)
            if group and group.audit:
                # complete the audit
                group.audit.complete = True
                self.session.commit()

                cancel_async_emails(self.session, f"audit-{group.id}")

                AuditLog.log(
                    self.session,
                    self.current_user.id,
                    "complete_audit",
                    "Disabling group completes group audit.",
                    on_group_id=group.id,
                )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Beispiel #59
0
    def create_group_request(self, user, group, role="member"):
        # type: (str, str, str) -> None
        self.create_user(user)
        self.create_group(group)

        user_obj = User.get(self.session, name=user)
        assert user_obj
        group_obj = Group.get(self.session, name=group)
        assert group_obj

        # Note: despite the function name, this only creates the request. The flow here is
        # convoluted enough that it seems best to preserve exact behavior for testing.
        group_obj.add_member(requester=user_obj,
                             user_or_group=user_obj,
                             reason="",
                             status="pending",
                             role=role)
def test_add_role_user(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin')

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_role_user(session, user=u)
    assert is_role_user(session, group=g)
    assert get_role_user(session, user=u).group.id == g.id
    assert get_role_user(session, group=g).user.id == u.id
    assert not is_role_user(session, user=user)
    assert not is_role_user(session, group=Group.get(session, name="team-sre"))