Skip to content

Commit

Permalink
Add API for self requests
Browse files Browse the repository at this point in the history
This patchset brings 2 new API calls (and their support in lib and cli):
GET /v1/user/self and GET /v1/role/self.

Change-Id: Ie7266a0fb94a87949ef08776325eb9c1c6462f9c
  • Loading branch information
9seconds committed Apr 6, 2017
1 parent 7f64056 commit aeb058b
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 6 deletions.
17 changes: 11 additions & 6 deletions backend/api/decapod_api/auth/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,23 @@ def require_user_model(user_name):

return user_model

@staticmethod
def get_current_user():
user_model = getattr(flask.g, "token", None)
user_model = getattr(user_model, "user", None)
if not user_model:
LOG.warning("Cannot find authenticated user model")
raise exceptions.Forbidden

return user_model

def require_authorization(self, permission_class, permission_name):
role.PermissionSet.add_permission(permission_class, permission_name)

def outer_decorator(func):
@functools.wraps(func)
def inner_decorator(*args, **kwargs):
user_model = getattr(flask.g, "token", None)
user_model = getattr(user_model, "user", None)
if not user_model:
LOG.warning("Cannot find authenticated user model")
raise exceptions.Forbidden

user_model = self.get_current_user()
self.check_auth_permission(
user_model, permission_class, permission_name)

Expand Down
2 changes: 2 additions & 0 deletions backend/api/decapod_api/views/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,7 @@
playbook_configuration.PlaybookConfigurationView.register_to(BLUEPRINT)
playbook.PlaybookView.register_to(BLUEPRINT)
role.RoleView.register_to(BLUEPRINT)
role.RoleSelfView.register_to(BLUEPRINT)
server.ServerView.register_to(BLUEPRINT)
user.UserView.register_to(BLUEPRINT)
user.UserSelfView.register_to(BLUEPRINT)
21 changes: 21 additions & 0 deletions backend/api/decapod_api/views/v1/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,24 @@ def delete(self, item_id, item):
LOG.info("Role %s was deleted by %s", item_id, self.initiator_id)

return item


class RoleSelfView(generic.View):

NAME = "role_self"

decorators = [auth.AUTH.require_authentication]

@classmethod
def register_to(cls, application):
main_endpoint = generic.make_endpoint(RoleView.ENDPOINT, "self")
application.add_url_rule(
main_endpoint,
view_func=cls.as_view(cls.NAME), methods=["GET"])

def get(self):
role_model = auth.AUTH.get_current_user().role
if role_model is None:
raise http_exceptions.NotFound("Cannot find role")

return role_model
17 changes: 17 additions & 0 deletions backend/api/decapod_api/views/v1/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,23 @@ def delete(self, item_id, item):
return item


class UserSelfView(generic.View):

NAME = "user_self"

decorators = [auth.AUTH.require_authentication]

@classmethod
def register_to(cls, application):
main_endpoint = generic.make_endpoint(UserView.ENDPOINT, "self")
application.add_url_rule(
main_endpoint,
view_func=cls.as_view(cls.NAME), methods=["GET"])

def get(self):
return auth.AUTH.get_current_user()


def make_password_message(model, password):
"""Creates email message for password."""

Expand Down
7 changes: 7 additions & 0 deletions decapodcli/decapodcli/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ def get(role_id, client):
return client.get_role(str(role_id))


@decorators.command(role)
def self(client):
"""Requests information on role of the current user."""

return client.get_role_self()


@click.argument("role-id", type=click.UUID)
@decorators.command(role, True, True)
def get_version_all(role_id, client, query_params):
Expand Down
7 changes: 7 additions & 0 deletions decapodcli/decapodcli/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ def get(user_id, client):
return client.get_user(str(user_id))


@decorators.command(user)
def self(client):
"""Requests information on current user."""

return client.get_user_self()


@click.argument("user-id", type=click.UUID)
@decorators.command(user, True, True)
def get_version_all(user_id, client, query_params):
Expand Down
32 changes: 32 additions & 0 deletions decapodlib/decapodlib/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,22 @@ def get_user(self, user_id, **kwargs):
url = self._make_url("/v1/user/{0}/".format(user_id))
return self._session.get(url, **kwargs)

def get_user_self(self, **kwargs):
"""This methods requests model of current user.
This method does ``GET /v1/user/self/`` endpoint call.
:return: User model of current user.
:rtype: dict
:raises decapodlib.exceptions.DecapodError: if not possible to
connect to API.
:raises decapodlib.exceptions.DecapodAPIError: if API returns error
response.
"""

url = self._make_url("/v1/user/self/")
return self._session.get(url, **kwargs)

@inject_pagination_params
def get_user_versions(self, user_id, query_params, **kwargs):
"""This method fetches a list of all versions for a certain user
Expand Down Expand Up @@ -1284,6 +1300,22 @@ def get_role(self, role_id, **kwargs):
url = self._make_url("/v1/role/{0}/".format(role_id))
return self._session.get(url, **kwargs)

def get_role_self(self, **kwargs):
"""This methods requests model of role of current user.
This method does ``GET /v1/role/self/`` endpoint call.
:return: Role model of current user.
:rtype: dict
:raises decapodlib.exceptions.DecapodError: if not possible to
connect to API.
:raises decapodlib.exceptions.DecapodAPIError: if API returns error
response.
"""

url = self._make_url("/v1/role/self/")
return self._session.get(url, **kwargs)

@inject_pagination_params
def get_role_versions(self, role_id, query_params, **kwargs):
"""This method fetches a list of all versions for a certain role
Expand Down
15 changes: 15 additions & 0 deletions tests/api/views/v1/test_api_role.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,18 @@ def test_delete_role_with_active_user(sudo_client_v1, normal_user_with_role):

response = sudo_client_v1.delete("/v1/role/{0}/".format(role_data["id"]))
assert response.status_code == 200


def test_get_role_self_wo_role(client_v1, normal_user):
client_v1.login(normal_user.login, "qwerty")
response = client_v1.get("/v1/role/self/")

assert response.status_code == 404


def test_get_role_self(client_v1, normal_user_with_role):
client_v1.login(normal_user_with_role.login, "qwerty")
response = client_v1.get("/v1/role/self/")

assert response.status_code == 200
assert response.json["id"] == normal_user_with_role.role.model_id
8 changes: 8 additions & 0 deletions tests/api/views/v1/test_api_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,3 +491,11 @@ def test_user_filtering(sudo_client_v1, email, clean_user_collection):
"/v1/user/?filter={0}".format(json.dumps({"login": {"ne": login}}))
)
assert response.json["total"] == 10


def test_get_self(client_v1, normal_user):
client_v1.login(normal_user.login, "qwerty")
response = client_v1.get("/v1/user/self/")

assert response.status_code == 200
assert response.json["id"] == normal_user.model_id

0 comments on commit aeb058b

Please sign in to comment.