def test_github_user_admin(session, users, http_client, base_url): # noqa: F811 user = users["*****@*****.**"] set_user_metadata(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY, "zorkian") data = get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) assert data assert data.data_value == "zorkian" # Another random user should not be able to clear the GitHub identity. fe_url = url(base_url, f"/users/{user.username}/github/clear") with pytest.raises(HTTPError) as excinfo: resp = yield http_client.fetch( fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=b"") assert excinfo.value.code == 403 data = get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) assert data assert data.data_value == "zorkian" # A user admin should be able to clear the GitHub identity. resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=b"") assert resp.code == 200 assert get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) is None
def get_user_view_template_vars(session, actor, user, graph): # type: (Session, User, User, GroupGraph) -> Dict[str, Any] # TODO(cbguder): get around circular dependencies from grouper.fe.handlers.user_disable import UserDisable from grouper.fe.handlers.user_enable import UserEnable ret = {} # type: Dict[str, Any] 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_metadata = get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) ret["shell"] = shell_metadata.data_value if shell_metadata else "No shell configured" github_username = get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) ret["github_username"] = github_username.data_value if github_username else "(Unset)" 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) 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", []) for permission in ret["permissions"]: permission["granted_on"] = datetime.fromtimestamp(permission["granted_on"]) return ret
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_shell(session, users, http_client, base_url, graph): user = users['*****@*****.**'] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/bash") graph.update_from_db(session) fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) assert body["data"]["user"]["metadata"] != [], "There should be metadata" assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_key"] == "shell", "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_value"] == "/bin/bash", "The shell should be set to the correct value" set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/zsh") graph.update_from_db(session) fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) assert body["data"]["user"]["metadata"] != [], "There should be metadata" assert body["data"]["user"]["metadata"][0]["data_key"] == "shell", "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_value"] == "/bin/zsh", "The shell should be set to the correct value" assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!"
def test_github_username(session, users, http_client, base_url, graph): # noqa: F811 user = users["*****@*****.**"] assert get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) is None set_user_metadata(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY, "zorkian-on-gh") graph.update_from_db(session) fe_url = url(base_url, "/users/{}".format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) [metadata] = body["data"]["user"]["metadata"] assert metadata["data_key"] == "github_username" assert metadata["data_value"] == "zorkian-on-gh" set_user_metadata(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY, None) graph.update_from_db(session) fe_url = url(base_url, "/users/{}".format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) assert body["data"]["user"]["metadata"] == []
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() 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() form.value.choices = settings().metadata_options.get( metadata_key, DEFAULT_METADATA_OPTIIONS) self.render( "user-metadata.html", form=form, user=user, is_enabled=known_field, metadata_key=metadata_key, )
def test_shell(session, users, http_client, base_url, graph): user = users['*****@*****.**'] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/bash") graph.update_from_db(session) fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) assert body["data"]["user"]["metadata"] != [], "There should be metadata" assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_key"] == "shell", "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_value"] == "/bin/bash", "The shell should be set to the correct value" set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/zsh") graph.update_from_db(session) fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) assert body["data"]["user"]["metadata"] != [], "There should be metadata" assert body["data"]["user"]["metadata"][0]["data_key"] == "shell", "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_value"] == "/bin/zsh", "The shell should be set to the correct value" assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!"
def test_metadata(session, users, http_client, base_url): # noqa: F811 settings().metadata_options = { "favorite_food": [["pizza", "pizza"], ["kale", "kale"]] } user = users["*****@*****.**"] assert not get_user_metadata_by_key(session, user.id, "favorite_food") user = User.get(session, name=user.username) set_user_metadata(session, user.id, "favorite_food", "default") fe_url = url(base_url, "/users/{}/metadata/favorite_food".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"value": "pizza"}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 assert get_user_metadata_by_key(session, user.id, "favorite_food").data_value == "pizza" fe_url = url(base_url, "/users/{}/metadata/favorite_food".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"value": "kale"}), headers={"X-Grouper-User": user.username}, ) assert get_user_metadata_by_key(session, user.id, "favorite_food").data_value == "kale" fe_url = url(base_url, "/users/{}/metadata/favorite_food".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"value": "donuts"}), headers={"X-Grouper-User": user.username}, ) assert get_user_metadata_by_key(session, user.id, "favorite_food").data_value == "kale"
def test_shell(session, users, http_client, base_url): with patch('grouper.fe.handlers.user_shell.settings') as mock_settings: mock_settings.shell = [['/bin/bash', 'bash'], ['/bin/zsh', 'zsh']] user = users['*****@*****.**'] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) user = User.get(session, name=user.username) fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({'shell': "/bin/bash"}), 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_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash") fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({'shell': "/bin/fish"}), 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_SHELL_KEY) is not None, \ "The user should have shell metadata" assert get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash" fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({'shell': "/bin/zsh"}), 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_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/zsh")
def test_shell(session, users, http_client, base_url): # noqa: F811 settings().shell = [["/bin/bash", "bash"], ["/bin/zsh", "zsh"]] user = users["*****@*****.**"] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) user = User.get(session, name=user.username) fe_url = url(base_url, "/users/{}/shell".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"shell": "/bin/bash"}), 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_SHELL_KEY) is not None), "The user should have shell metadata" assert (get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash") fe_url = url(base_url, "/users/{}/shell".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"shell": "/bin/fish"}), 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_SHELL_KEY) is not None), "The user should have shell metadata" assert (get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash") fe_url = url(base_url, "/users/{}/shell".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"shell": "/bin/zsh"}), 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_SHELL_KEY) is not None), "The user should have shell metadata" assert (get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/zsh")
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
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))
def test_shell(session, users, http_client, base_url): with patch('grouper.fe.handlers.user_shell.settings') as mock_settings: mock_settings.shell = [['/bin/bash', 'bash'], ['/bin/zsh', 'zsh']] user = users['*****@*****.**'] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) user = User.get(session, name=user.username) fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'shell': "/bin/bash"}), 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_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash") fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'shell': "/bin/fish"}), 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_SHELL_KEY) is not None, \ "The user should have shell metadata" assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash" fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'shell': "/bin/zsh"}), 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_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/zsh")
def test_github_username(session, users, http_client, base_url, graph): # noqa: F811 user = users["*****@*****.**"] assert get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) is None set_user_metadata(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY, "zorkian-on-gh") graph.update_from_db(session) fe_url = url(base_url, "/users/{}".format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) [metadata] = body["data"]["user"]["metadata"] assert metadata["data_key"] == "github_username" assert metadata["data_value"] == "zorkian-on-gh" set_user_metadata(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY, None) graph.update_from_db(session) fe_url = url(base_url, "/users/{}".format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) assert body["data"]["user"]["metadata"] == []
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
def test_github(session, users, http_client, base_url, mocker): # 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, "/github/link_begin/{}".format(user.id)) mocker.patch.object(settings(), "github_app_client_id", "a-client-id") resp = yield http_client.fetch( fe_url, method="GET", headers={"X-Grouper-User": user.username}, follow_redirects=False, raise_error=False, ) assert resp.code == 302 redir_url = urlparse(resp.headers["Location"]) assert redir_url.netloc == "github.com" assert redir_url.path == "/login/oauth/authorize" query_params = parse_qs(redir_url.query) assert query_params["client_id"] == ["a-client-id"] (state, ) = query_params["state"] assert "github-link-state={}".format(state) in resp.headers["Set-cookie"] assert query_params["redirect_uri"] == [ "http://127.0.0.1:8888/github/link_complete/{}".format(user.id) ] fe_url = url( base_url, "/github/link_complete/{}?code=tempcode&state={}".format( user.id, state)) with pytest.raises(HTTPError) as excinfo: yield http_client.fetch( fe_url, method="GET", headers={ "X-Grouper-User": user.username, "Cookie": "github-link-state=bogus-state" }, ) assert excinfo.value.code == 400 recorder = FakeGitHubHttpClient() proxy_plugin = PluginProxy([SecretPlugin()]) mocker.patch("grouper.fe.handlers.github._get_github_http_client", lambda: recorder) mocker.patch("grouper.fe.handlers.github.get_plugin_proxy", lambda: proxy_plugin) mocker.patch.object(settings(), "http_proxy_host", "proxy-server") mocker.patch.object(settings(), "http_proxy_port", 42) resp = yield http_client.fetch( fe_url, method="GET", headers={ "X-Grouper-User": user.username, "Cookie": "github-link-state=" + state }, ) authorize_request, user_request = recorder.requests assert authorize_request.proxy_host == "proxy-server" assert authorize_request.proxy_port == 42 assert user_request.proxy_host == "proxy-server" assert user_request.proxy_port == 42 authorize_params = parse_qs(authorize_request.body) assert authorize_params[b"code"] == [b"tempcode"] assert authorize_params[b"state"] == [state.encode("ascii")] assert authorize_params[b"client_id"] == [b"a-client-id"] assert authorize_params[b"client_secret"] == [b"client-secret"] assert user_request.headers["Authorization"] == "token a-access-token" 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 == "zorkian-on-gh") 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: zorkian-on-gh" fe_url = url(base_url, "/users/{}/github/clear".format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": user.username}, body=b"") assert resp.code == 200 assert get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) is None audit_entries = AuditLog.get_entries(session, on_user_id=user.id, action="changed_github_username") assert len(audit_entries) == 2 audit_entries.sort(key=operator.attrgetter("id")) assert audit_entries[1].description == "Cleared GitHub link"
def get_user_view_template_vars(session, actor, user, graph): # type: (Session, User, User, GroupGraph) -> Dict[str, Any] # TODO(cbguder): get around circular dependencies from grouper.fe.handlers.user_disable import UserDisable from grouper.fe.handlers.user_enable import UserEnable ret = {} # type: Dict[str, Any] 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 github_username = get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY) ret["github_username"] = github_username.data_value if github_username else "(Unset)" 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) 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", []) for permission in ret["permissions"]: permission["granted_on"] = datetime.fromtimestamp(permission["granted_on"]) return ret
def test_shell(session, users, http_client, base_url): # noqa: F811 settings().shell = [["/bin/bash", "bash"], ["/bin/zsh", "zsh"]] user = users["*****@*****.**"] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) user = User.get(session, name=user.username) fe_url = url(base_url, "/users/{}/shell".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"shell": "/bin/bash"}), 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_SHELL_KEY) is not None ), "The user should have shell metadata" assert ( get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash" ) fe_url = url(base_url, "/users/{}/shell".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"shell": "/bin/fish"}), 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_SHELL_KEY) is not None ), "The user should have shell metadata" assert ( get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash" ) fe_url = url(base_url, "/users/{}/shell".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"shell": "/bin/zsh"}), 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_SHELL_KEY) is not None ), "The user should have shell metadata" assert ( get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/zsh" )