User Guide

Here you will learn how to use the package correctly and you will see useful examples

Authentication

This service provides a Login and Logout.

Login

Check this example to how use the Login:

from flask import Blueprint, request
from flask_restplus import Api, Resource
from flask_graphql import GraphQLView
from flask_auth_service_mongo.constants.security import ROLE_ADMIN_NAME
from flask_auth_service_mongo.security import auth
from flask_auth_service_mongo.security.use_cases import user as UseCase

routes_admin = Blueprint('routes_admin', __name__)
api = Api(routes_admin)


@api.route('/')
class ApiAdmin(Resource):
    @auth.required(role=ROLE_ADMIN_NAME)
    def get(self):
        return dict(message='Hello admin!')


@api.route('/login')
class ApiLogin(Resource):
    def post(self):
        use_case = UseCase.Login()
        result = use_case.handle(
            role=ROLE_ADMIN_NAME,
            request=request.get_json()
        )

        response = dict(
            message=result.message
        )
        if result.token:
            response['data'] = dict(
                token=result.token
            )
        return response, result.http_code

Logout

Check this example to how use Logout:

from flask import Blueprint, request
from flask_restplus import Api, Resource
from flask_graphql import GraphQLView
from flask_auth_service_mongo.constants.security import ROLE_ADMIN_NAME
from flask_auth_service_mongo.security import auth
from flask_auth_service_mongo.security.use_cases import user as UseCase

routes_admin = Blueprint('routes_admin', __name__)
api = Api(routes_admin)

@api.route('/logout')
class ApiLogout(Resource):
    @auth.required(role=ROLE_ADMIN_NAME)
    def post(self):
        authorization = request.headers.get('Authorization')
        _, token = authorization.split(' ')
        use_case = UseCase.Logout()
        result = use_case.handle(token=token)

        response = dict(message=result.message)
        return response, result.http_code

Note

The file where login/logout was implemented must be registered in the app/__init__.py.

Example:

from app.routes.admin import routes_admin
app.register_blueprint(routes_admin, url_prefix='/admin')

CRUD User

This service provides Create, Read, Update and Delete options.

Create

A simple example to how create an user:

import graphene
from graphene.relay import Node
from graphene_mongo import MongoengineObjectType
from graphql import GraphQLError
from utils.schema import input_to_dictionary
from flask_auth_service_mongo.security import models
from flask_auth_service_mongo.security.use_cases import user as UseCase


class User(MongoengineObjectType, UserAttribute):
    """User Node"""

    class Meta:
        model = models.User
        interfaces = (Node,)
        exclude_fields = ('password')


class CreateUserInput(graphene.InputObjectType, UserAttribute):
    """Arguments to create a User"""
    username = graphene.String(required=True)
    password = graphene.String(required=True)
    password_confirmed = graphene.String(required=True)
    role = graphene.String(required=True)


class CreateUser(graphene.Mutation):
    user = graphene.Field(lambda: User)

    class Arguments(UserAttribute):
        input = CreateUserInput(required=True)

    def mutate(self, info, input):
        data = input_to_dictionary(input)
        use_case = UseCase.CreateUser()
        result = use_case.handle(data)
        if result.http_code > 299:
            raise GraphQLError(
                "{}. {}".format(
                    result.message,
                    result.errors if result.errors else ""
                )
            )
        return CreateUser(
            user=result.user
        )

Update

A simple example to how update an user:

import graphene
from graphene.relay import Node
from graphene_mongo import MongoengineObjectType
from graphql import GraphQLError
from utils.schema import input_to_dictionary
from flask_auth_service_mongo.security import models
from flask_auth_service_mongo.security.use_cases import user as UseCase


class User(MongoengineObjectType, UserAttribute):
    """User Node"""

    class Meta:
        model = models.User
        interfaces = (Node,)
        exclude_fields = ('password')


class UpdateUserInput(graphene.InputObjectType):
    """Arguments to update a User."""
    id = graphene.ID(required=True)
    password = graphene.String(required=True)
    password_confirmed = graphene.String(required=True)


class UpdateUser(graphene.Mutation):
    user = graphene.Field(lambda: User)

    class Arguments(UserAttribute):
        input = UpdateUserInput(required=True)

    def mutate(self, info, input):
        data = input_to_dictionary(input)
        uuid = data.pop('id')

        use_case = UseCase.EditUser()
        result = use_case.handle(uuid=uuid, request=data)

        if result.http_code > 299:
            raise GraphQLError(
                "{}. {}".format(
                    result.message,
                    result.errors if result.errors else ""
                )
            )
        return UpdateUser(
            user=result.user
        )

Delete

A simple example to how delete an user:

import graphene
from graphene.relay import Node
from graphene_mongo import MongoengineObjectType
from graphql import GraphQLError
from utils.schema import input_to_dictionary
from flask_auth_service_mongo.security import models
from flask_auth_service_mongo.security.use_cases import user as UseCase


class User(MongoengineObjectType, UserAttribute):
    """User Node"""

    class Meta:
        model = models.User
        interfaces = (Node,)
        exclude_fields = ('password')


class DeleteUserInput(graphene.InputObjectType):
    """Arguments to delete a User."""
    id = graphene.ID(required=True)


class DeleteUser(graphene.Mutation):
    ok = graphene.Boolean()

    class Arguments(UserAttribute):
        input = DeleteUserInput(required=True)

    def mutate(self, info, input):
        data = input_to_dictionary(input)
        uuid = data.pop('id')

        use_case = UseCase.DeleteUser()
        result = use_case.handle(uuid)

        if result.http_code > 299:
            raise GraphQLError(
                "{}. {}".format(
                    result.message,
                    result.errors if result.errors else ""
                )
            )
        return DeleteUser(
            ok=True
        )

Note

Look that from utils.schema import input_to_dictionary isn’t in the package. This method converts Graphene inputs to a dictionary.

Role

This service provides creating new roles

Create

Check this example to how create a new role through a command:

import json
import click
from flask import Blueprint
from flask_auth_service_mongo.security.use_cases import role as UseCase

command_security = Blueprint(
    'command_security',
    __name__,
    cli_group='security'
)


@command_security.cli.command(
    'role-new',
    help="Create a 'Role'"
)
@click.option('-n', '--name', 'name', required=True, prompt=True)
@click.option('-p', '--permissions', 'permissions',
            help='''JSON example: '{"key": "value"}' ''')
def role_new(**kwargs):
    request = dict()
    for (key, value) in kwargs.items():
        if value is not None:
            request[key] = value
    try:
        if 'permissions' in request:
            request['permissions'] = json.loads(request['permissions'])
        use_case = UseCase.NewRole()
        result = use_case.handle(request)
        click.echo("Create a 'Role': {}. {}".format(
            result.message,
            result.errors if result.errors else ""
        ))
    except Exception as e:
        click.echo("Create a 'Role' ERROR: {}".format(e))