""" .. module: lemur.users.views :platform: Unix :copyright: (c) 2018 by Netflix Inc., see AUTHORS for more :license: Apache, see LICENSE for more details. .. moduleauthor:: Kevin Glisson """ from flask import g, Blueprint from flask_restful import reqparse, Api from lemur.common.schema import validate_schema from lemur.common.utils import paginated_parser from lemur.auth.service import AuthenticatedResource from lemur.auth.permissions import admin_permission from lemur.users import service from lemur.certificates import service as certificate_service from lemur.roles import service as role_service from lemur.users.schemas import user_input_schema, user_output_schema, users_output_schema mod = Blueprint('users', __name__) api = Api(mod) class UsersList(AuthenticatedResource): """ Defines the 'users' endpoint """ def __init__(self): self.reqparse = reqparse.RequestParser() super(UsersList, self).__init__() @validate_schema(None, users_output_schema) def get(self): """ .. http:get:: /users The current user list **Example request**: .. sourcecode:: http GET /users HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "items": [ { "id": 2, "active": True, "email": "user2@example.com", "username": "user2", "profileImage": null }, { "id": 1, "active": False, "email": "user1@example.com", "username": "user1", "profileImage": null } ] "total": 2 } :query sortBy: field to sort on :query sortDir: asc or desc :query page: int default is 1 :query filter: key value pair format is k;v :query count: count number default is 10 :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ parser = paginated_parser.copy() parser.add_argument('owner', type=str, location='args') parser.add_argument('id', type=str, location='args') args = parser.parse_args() return service.render(args) @admin_permission.require(http_exception=403) @validate_schema(user_input_schema, user_output_schema) def post(self, data=None): """ .. http:post:: /users Creates a new user **Example request**: .. sourcecode:: http POST /users HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "username": "user3", "email": "user3@example.com", "active": true, "roles": [ {'id': 1} - or - {'name': 'myRole'} ] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "id": 3, "active": True, "email": "user3@example.com, "username": "user3", "profileImage": null } :arg username: username for new user :arg email: email address for new user :arg password: password for new user :arg active: boolean, if the user is currently active :arg roles: list, roles that the user should be apart of :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ return service.create(data['username'], data['password'], data['email'], data['active'], None, data['roles']) class Users(AuthenticatedResource): def __init__(self): self.reqparse = reqparse.RequestParser() super(Users, self).__init__() @validate_schema(None, user_output_schema) def get(self, user_id): """ .. http:get:: /users/1 Get a specific user **Example request**: .. sourcecode:: http GET /users/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "id": 1, "active": false, "email": "user1@example.com", "username": "user1", "profileImage": null } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ return service.get(user_id) @admin_permission.require(http_exception=403) @validate_schema(user_input_schema, user_output_schema) def put(self, user_id, data=None): """ .. http:put:: /users/1 Update a user **Example request**: .. sourcecode:: http PUT /users/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "username": "user1", "email": "user1@example.com", "active": false, "roles": [ {'id': 1} - or - {'name': 'myRole'} ] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "id": 1, "username": "user1", "email": "user1@example.com", "active": false, "profileImage": null } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ return service.update(user_id, data['username'], data['email'], data['active'], None, data['roles']) class CertificateUsers(AuthenticatedResource): def __init__(self): self.reqparse = reqparse.RequestParser() super(CertificateUsers, self).__init__() @validate_schema(None, user_output_schema) def get(self, certificate_id): """ .. http:get:: /certificates/1/creator Get a certificate's creator **Example request**: .. sourcecode:: http GET /certificates/1/creator HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "id": 1, "active": false, "email": "user1@example.com", "username": "user1", "profileImage": null } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ return certificate_service.get(certificate_id).user class RoleUsers(AuthenticatedResource): def __init__(self): self.reqparse = reqparse.RequestParser() super(RoleUsers, self).__init__() @validate_schema(None, users_output_schema) def get(self, role_id): """ .. http:get:: /roles/1/users Get all users associated with a role **Example request**: .. sourcecode:: http GET /roles/1/users HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "items": [ { "id": 2, "active": True, "email": "user2@example.com", "username": "user2", "profileImage": null }, { "id": 1, "active": False, "email": "user1@example.com", "username": "user1", "profileImage": null } ] "total": 2 } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ return role_service.get(role_id).users class Me(AuthenticatedResource): def __init__(self): super(Me, self).__init__() @validate_schema(None, user_output_schema) def get(self): """ .. http:get:: /auth/me Get the currently authenticated user **Example request**: .. sourcecode:: http GET /auth/me HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "id": 1, "active": false, "email": "user1@example.com", "username": "user1", "profileImage": null } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error """ return g.current_user api.add_resource(Me, '/auth/me', endpoint='me') api.add_resource(UsersList, '/users', endpoint='users') api.add_resource(Users, '/users/', endpoint='user') api.add_resource(CertificateUsers, '/certificates//creator', endpoint='certificateCreator') api.add_resource(RoleUsers, '/roles//users', endpoint='roleUsers')