def get_user_view_template_vars(session, actor, user, graph): # TODO(cbguder): get around circular dependencies from grouper.fe.handlers.user_disable import UserDisable from grouper.fe.handlers.user_enable import UserEnable ret = {} if user.is_service_account: ret["can_control"] = ( can_manage_service_account(session, user.service_account, actor) or user_is_user_admin(session, actor) ) ret["can_disable"] = ret["can_control"] ret["can_enable"] = user_is_user_admin(session, actor) ret["account"] = user.service_account else: ret["can_control"] = (user.name == actor.name or user_is_user_admin(session, actor)) ret["can_disable"] = UserDisable.check_access(session, actor, user) ret["can_enable"] = UserEnable.check_access(session, actor, user) if user.id == actor.id: ret["num_pending_group_requests"] = user_requests_aggregate(session, actor).count() _, ret["num_pending_perm_requests"] = get_requests_by_owner(session, actor, status='pending', limit=1, offset=0) else: ret["num_pending_group_requests"] = None ret["num_pending_perm_requests"] = None try: user_md = 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 = {} shell = (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value if get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) else "No shell configured") ret["shell"] = shell ret["open_audits"] = user_open_audits(session, user) group_edge_list = get_groups_by_user(session, user) if user.enabled else [] ret["groups"] = [{'name': g.name, 'type': 'Group', 'role': ge._role} for g, ge in group_edge_list] ret["passwords"] = user_passwords(session, user) ret["public_keys"] = get_public_keys_of_user(session, user.id) for key in ret["public_keys"]: key.tags = get_public_key_tags(session, key) key.pretty_permissions = ["{} ({})".format(perm.name, perm.argument if perm.argument else "unargumented") for perm in get_public_key_permissions(session, key)] ret["log_entries"] = get_log_entries_by_user(session, user) ret["user_tokens"] = user.tokens if user.is_service_account: service_account = user.service_account ret["permissions"] = service_account_permissions(session, service_account) else: ret["permissions"] = user_md.get('permissions', []) return ret
def get_user_view_template_vars(session, actor, user, graph): ret = {} ret["can_control"] = (user.name == actor.name or user_is_user_admin(session, actor)) ret["can_disable"] = UserDisable.check_access(session, actor, user) ret["can_enable"] = UserEnable.check_access(session, actor, user) if user.id == actor.id: ret["num_pending_group_requests"] = user_requests_aggregate( session, actor).count() _, ret["num_pending_perm_requests"] = get_requests_by_owner( session, actor, status='pending', limit=1, offset=0) else: ret["num_pending_group_requests"] = None ret["num_pending_perm_requests"] = None try: user_md = 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 = {} shell = (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value if get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) else "No shell configured") ret["shell"] = shell ret["open_audits"] = user_open_audits(session, user) group_edge_list = get_groups_by_user(session, user) if user.enabled else [] ret["groups"] = [{ 'name': g.name, 'type': 'Group', 'role': ge._role } for g, ge in group_edge_list] ret["passwords"] = user_passwords(session, user) ret["public_keys"] = get_public_keys_of_user(session, user.id) for key in ret["public_keys"]: key.tags = get_public_key_tags(session, key) key.pretty_permissions = [ "{} ({})".format( perm.name, perm.argument if perm.argument else "unargumented") for perm in get_public_key_permissions(session, key) ] ret["permissions"] = user_md.get('permissions', []) ret["log_entries"] = get_log_entries_by_user(session, user) ret["user_tokens"] = user.tokens return ret
def test_add_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() # add SSH key 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': key_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 key = session.query(PublicKey).filter_by(user_id=user.id).scalar() # add SSH key 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': key_2}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 key2 = session.query(PublicKey).filter_by(public_key=key_2).scalar() fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert get_public_key_tags(session, key) == [], "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "dont_tag_me_bro", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="dont_tag_me_bro") key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert get_public_key_tags(session, key) == [], "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" key2 = session.query(PublicKey).filter_by(public_key=key_2).scalar() assert len(get_public_key_tags(session, key2)) == 0, "Keys other than the one with the added tag should not gain tags" # Non-admin and not user adding tag should fail fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key.id)) with pytest.raises(HTTPError): resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here"}), headers={'X-Grouper-User': "******"}) key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" # User admins test fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "dont_tag_me_bro"}), headers={'X-Grouper-User': "******"}) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 2, "The key should have 2 tags now" assert set([x.name for x in get_public_key_tags(session, key)]) == set(["tyler_was_here", "dont_tag_me_bro"])
def test_remove_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() # add SSH key 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': key_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 key = session.query(PublicKey).filter_by(user_id=user.id).scalar() # add SSH key 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': key_2}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 key2 = session.query(PublicKey).filter_by(public_key=key_2).scalar() fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert get_public_key_tags(session, key) == [], "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "dont_tag_me_bro", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag2 = PublicKeyTag.get(session, name="dont_tag_me_bro") key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert get_public_key_tags(session, key) == [], "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" key2 = session.query(PublicKey).filter_by(public_key=key_2).scalar() assert len(get_public_key_tags(session, key2)) == 0, "Keys other than the one with the added tag should not gain tags" fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key2.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here"}), headers={'X-Grouper-User': user.username}) key = session.query(PublicKey).filter_by(public_key=key_1).scalar() # Fail Remove tag tag = PublicKeyTag.get(session, name="dont_tag_me_bro") fe_url = url(base_url, '/users/{}/public-key/{}/delete_tag/{}'.format(user.username, key.id, tag.id)) with pytest.raises(HTTPError): resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': "******"}) # Remove tag that isn't on key: should fail silently tag = PublicKeyTag.get(session, name="dont_tag_me_bro") fe_url = url(base_url, '/users/{}/public-key/{}/delete_tag/{}'.format(user.username, key.id, tag.id)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': user.username}) assert resp.code == 200 # Remove tag tag = PublicKeyTag.get(session, name="tyler_was_here") fe_url = url(base_url, '/users/{}/public-key/{}/delete_tag/{}'.format(user.username, key.id, tag.id)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': user.username}) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 0, "The key should have exactly 0 tags" key2 = session.query(PublicKey).filter_by(public_key=key_2).scalar() assert len(get_public_key_tags(session, key2)) == 1, "Removing a tag from one key should not affect other keys" # User admin remove tag # readd tag fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" # Nonuser admin fail Remove tag tag = PublicKeyTag.get(session, name="tyler_was_here") fe_url = url(base_url, '/users/{}/public-key/{}/delete_tag/{}'.format(user.username, key.id, tag.id)) with pytest.raises(HTTPError): resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': "******"}) key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tags" # Remove tag tag = PublicKeyTag.get(session, name="tyler_was_here") fe_url = url(base_url, '/users/{}/public-key/{}/delete_tag/{}'.format(user.username, key.id, tag.id)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': "******"}) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=key_1).scalar() assert len(get_public_key_tags(session, key)) == 0, "The key should have exactly 0 tags"
def test_add_tag(users, http_client, base_url, session): # noqa: F811 user = session.query(User).filter_by(username="******").scalar() # add SSH key 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 key = session.query(PublicKey).filter_by(user_id=user.id).scalar() # add SSH key 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_2}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 key2 = session.query(PublicKey).filter_by(public_key=SSH_KEY_2).scalar() fe_url = url(base_url, "/tags") resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={"X-Grouper-User": user.username}, ) PublicKeyTag.get(session, name="tyler_was_here") key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert ( get_public_key_tags(session, key) == [] ), "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, "/tags") resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "dont_tag_me_bro", "description": "Test Tag Please Ignore"}), headers={"X-Grouper-User": user.username}, ) PublicKeyTag.get(session, name="dont_tag_me_bro") key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert ( get_public_key_tags(session, key) == [] ), "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, "/users/{}/public-key/{}/tag".format(user.username, key.id)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "tyler_was_here"}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" key2 = session.query(PublicKey).filter_by(public_key=SSH_KEY_2).scalar() assert ( len(get_public_key_tags(session, key2)) == 0 ), "Keys other than the one with the added tag should not gain tags" # Non-admin and not user adding tag should fail fe_url = url(base_url, "/users/{}/public-key/{}/tag".format(user.username, key.id)) with pytest.raises(HTTPError): resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "tyler_was_here"}), headers={"X-Grouper-User": "******"}, ) key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" # User admins test fe_url = url(base_url, "/users/{}/public-key/{}/tag".format(user.username, key.id)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "dont_tag_me_bro"}), headers={"X-Grouper-User": "******"}, ) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 2, "The key should have 2 tags now" assert set([x.name for x in get_public_key_tags(session, key)]) == set( ["tyler_was_here", "dont_tag_me_bro"] )
def test_remove_tag(users, http_client, base_url, session): # noqa: F811 user = session.query(User).filter_by(username="******").scalar() # add SSH key 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 key = session.query(PublicKey).filter_by(user_id=user.id).scalar() # add SSH key 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_2}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 key2 = session.query(PublicKey).filter_by(public_key=SSH_KEY_2).scalar() fe_url = url(base_url, "/tags") resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={"X-Grouper-User": user.username}, ) tag = PublicKeyTag.get(session, name="tyler_was_here") key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert ( get_public_key_tags(session, key) == [] ), "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, "/tags") resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "dont_tag_me_bro", "description": "Test Tag Please Ignore"}), headers={"X-Grouper-User": user.username}, ) PublicKeyTag.get(session, name="dont_tag_me_bro") key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert ( get_public_key_tags(session, key) == [] ), "No public keys should have a tag unless it's been added to the key" fe_url = url(base_url, "/users/{}/public-key/{}/tag".format(user.username, key.id)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "tyler_was_here"}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" key2 = session.query(PublicKey).filter_by(public_key=SSH_KEY_2).scalar() assert ( len(get_public_key_tags(session, key2)) == 0 ), "Keys other than the one with the added tag should not gain tags" fe_url = url(base_url, "/users/{}/public-key/{}/tag".format(user.username, key2.id)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "tyler_was_here"}), headers={"X-Grouper-User": user.username}, ) key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() # Fail Remove tag tag = PublicKeyTag.get(session, name="dont_tag_me_bro") fe_url = url( base_url, "/users/{}/public-key/{}/delete_tag/{}".format(user.username, key.id, tag.id) ) with pytest.raises(HTTPError): resp = yield http_client.fetch( fe_url, method="POST", body="", headers={"X-Grouper-User": "******"} ) # Remove tag that isn't on key: should fail silently tag = PublicKeyTag.get(session, name="dont_tag_me_bro") fe_url = url( base_url, "/users/{}/public-key/{}/delete_tag/{}".format(user.username, key.id, tag.id) ) resp = yield http_client.fetch( fe_url, method="POST", body="", headers={"X-Grouper-User": user.username} ) assert resp.code == 200 # Remove tag tag = PublicKeyTag.get(session, name="tyler_was_here") fe_url = url( base_url, "/users/{}/public-key/{}/delete_tag/{}".format(user.username, key.id, tag.id) ) resp = yield http_client.fetch( fe_url, method="POST", body="", headers={"X-Grouper-User": user.username} ) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 0, "The key should have exactly 0 tags" key2 = session.query(PublicKey).filter_by(public_key=SSH_KEY_2).scalar() assert ( len(get_public_key_tags(session, key2)) == 1 ), "Removing a tag from one key should not affect other keys" # User admin remove tag # readd tag fe_url = url(base_url, "/users/{}/public-key/{}/tag".format(user.username, key.id)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"tagname": "tyler_was_here"}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tag" assert get_public_key_tags(session, key)[0].name == "tyler_was_here" # Nonuser admin fail Remove tag tag = PublicKeyTag.get(session, name="tyler_was_here") fe_url = url( base_url, "/users/{}/public-key/{}/delete_tag/{}".format(user.username, key.id, tag.id) ) with pytest.raises(HTTPError): resp = yield http_client.fetch( fe_url, method="POST", body="", headers={"X-Grouper-User": "******"} ) key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 1, "The key should have exactly 1 tags" # Remove tag tag = PublicKeyTag.get(session, name="tyler_was_here") fe_url = url( base_url, "/users/{}/public-key/{}/delete_tag/{}".format(user.username, key.id, tag.id) ) resp = yield http_client.fetch( fe_url, method="POST", body="", headers={"X-Grouper-User": "******"} ) assert resp.code == 200 key = session.query(PublicKey).filter_by(public_key=SSH_KEY_1).scalar() assert len(get_public_key_tags(session, key)) == 0, "The key should have exactly 0 tags"
def get_user_view_template_vars(session, actor, user, graph): # TODO(cbguder): get around circular dependencies from grouper.fe.handlers.user_disable import UserDisable from grouper.fe.handlers.user_enable import UserEnable ret = {} if user.is_service_account: ret["can_control"] = can_manage_service_account( session, user.service_account, actor ) or user_is_user_admin(session, actor) ret["can_disable"] = ret["can_control"] ret["can_enable"] = user_is_user_admin(session, actor) ret["can_enable_preserving_membership"] = user_is_user_admin(session, actor) ret["account"] = user.service_account else: ret["can_control"] = user.name == actor.name or user_is_user_admin(session, actor) ret["can_disable"] = UserDisable.check_access(session, actor, user) ret["can_enable_preserving_membership"] = UserEnable.check_access(session, actor, user) ret["can_enable"] = UserEnable.check_access_without_membership(session, actor, user) if user.id == actor.id: ret["num_pending_group_requests"] = user_requests_aggregate(session, actor).count() _, ret["num_pending_perm_requests"] = get_requests( session, status="pending", limit=1, offset=0, owner=actor ) else: ret["num_pending_group_requests"] = None ret["num_pending_perm_requests"] = None try: user_md = 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 = {} shell = ( get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value if get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) else "No shell configured" ) ret["shell"] = shell ret["open_audits"] = user_open_audits(session, user) group_edge_list = get_groups_by_user(session, user) if user.enabled else [] ret["groups"] = [ {"name": g.name, "type": "Group", "role": ge._role} for g, ge in group_edge_list ] ret["passwords"] = user_passwords(session, user) ret["public_keys"] = get_public_keys_of_user(session, user.id) for key in ret["public_keys"]: key.tags = get_public_key_tags(session, key) key.pretty_permissions = [ "{} ({})".format(perm.name, perm.argument if perm.argument else "unargumented") for perm in get_public_key_permissions(session, key) ] ret["log_entries"] = get_log_entries_by_user(session, user) ret["user_tokens"] = user.tokens if user.is_service_account: service_account = user.service_account ret["permissions"] = service_account_permissions(session, service_account) else: ret["permissions"] = user_md.get("permissions", []) return ret