Add role management routes
parent
3b09857dbc
commit
562e2653c9
|
@ -1,6 +1,6 @@
|
|||
from app.core import bcrypt
|
||||
from flask import Blueprint
|
||||
from .models import Account
|
||||
from .models import Account, Role
|
||||
|
||||
accounts_bp = Blueprint('accounts', __name__)
|
||||
|
||||
|
@ -44,6 +44,44 @@ def update_account_role(account_id, role_id):
|
|||
acc.save()
|
||||
|
||||
|
||||
def create_role(display_name, permissions):
|
||||
"""
|
||||
Tries to create role
|
||||
|
||||
:param display_name: Name of role - display only
|
||||
:param permissions: List of strings - permissions that this role has
|
||||
:type display_name: String
|
||||
:type permissions: List of String
|
||||
:returns: True if role is successfully created
|
||||
:rtype: Boolean
|
||||
:raises: ValueError if role already exists
|
||||
"""
|
||||
role = Role(display_name, permissions)
|
||||
role.save()
|
||||
|
||||
|
||||
def get_role(role_id):
|
||||
"""
|
||||
Tries to get role
|
||||
|
||||
:param role_id: Id of role
|
||||
:type role_id: int
|
||||
:returns: Role if found
|
||||
:rtype: Role
|
||||
"""
|
||||
return Role.get(role_id)
|
||||
|
||||
|
||||
def get_all_roles():
|
||||
"""
|
||||
Gets all roles
|
||||
|
||||
:returns: Role list if found
|
||||
:rtype: List of Roles
|
||||
"""
|
||||
return Role.get_all()
|
||||
|
||||
|
||||
def create_token(username, password):
|
||||
"""
|
||||
Tries to create token for account with given parameters.
|
||||
|
|
|
@ -122,10 +122,12 @@ class Role(db.Model):
|
|||
__tablename__ = 'roles'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
display_name = db.Column(db.String)
|
||||
display_name = db.Column(db.String, unique=True)
|
||||
permissions = db.Column(db.ARRAY(db.String))
|
||||
|
||||
def __init__(self, name):
|
||||
def __init__(self, name, permissions):
|
||||
self.display_name = str(name)
|
||||
self.permissions = permissions
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
|
@ -147,7 +149,7 @@ class Role(db.Model):
|
|||
"""
|
||||
Get role with id = roleId
|
||||
"""
|
||||
return Role.query.filter_by(id=roleId)
|
||||
return Role.query.filter_by(id=roleId).first_or_404()
|
||||
|
||||
def __repr__(self):
|
||||
return '<Role %s>' % self.display_name
|
||||
return '<Role %s (%s)>' % self.display_name, self.permissions
|
||||
|
|
|
@ -40,7 +40,9 @@ class ProtectedResource(Resource):
|
|||
def add_resources():
|
||||
from .resources.account import (AccountResource,
|
||||
AccountListResource,
|
||||
AccountRoleResource)
|
||||
AccountRoleResource,
|
||||
RoleResource,
|
||||
RolesResource)
|
||||
from .resources.token import TokenResource, ValidateTokenResource
|
||||
from .resources.device import (DeviceResource,
|
||||
DeviceRecordingResource,
|
||||
|
@ -53,6 +55,8 @@ def add_resources():
|
|||
api.add_resource(AccountResource, '/v1/accounts/<int:account_id>')
|
||||
api.add_resource(AccountListResource, '/v1/accounts')
|
||||
api.add_resource(AccountRoleResource, '/v1/accounts/<int:account_id>/role')
|
||||
api.add_resource(RoleResource, '/v1/roles/<int:role_id>')
|
||||
api.add_resource(RolesResource, '/v1/roles')
|
||||
api.add_resource(TokenResource, '/v1/token')
|
||||
api.add_resource(ValidateTokenResource, '/v1/token/validate')
|
||||
api.add_resource(DeviceResource, '/v1/devices/<int:device_id>')
|
||||
|
|
|
@ -17,6 +17,32 @@ class RoleUpdateSchema(Schema):
|
|||
role_id = fields.Integer(required=True, load_only=True, location='json')
|
||||
|
||||
|
||||
class RoleSchema(Schema):
|
||||
role_id = fields.Integer(required=True, location='json')
|
||||
display_name = fields.String(required=True, location='json')
|
||||
permissions = fields.List(fields.String, required=True,
|
||||
location='json', many=True)
|
||||
|
||||
|
||||
class RoleWrapperSchema(Schema):
|
||||
role = fields.Nested(RoleSchema, required=True, location='json')
|
||||
|
||||
|
||||
class RolesWrapperSchema(Schema):
|
||||
roles = fields.Nested(RoleSchema, required=True,
|
||||
location='json', many=True)
|
||||
|
||||
|
||||
class RoleCreationSchema(Schema):
|
||||
display_name = fields.String(required=True, location='json')
|
||||
permissions = fields.List(fields.String, required=True,
|
||||
location='json', many=True)
|
||||
|
||||
|
||||
class RoleCreationWrapperSchema(Schema):
|
||||
role = fields.Nested(RoleCreationSchema, required=True, location='json')
|
||||
|
||||
|
||||
class UserWrapperSchema(Schema):
|
||||
user = fields.Nested(UserSchema, required=True, location='json')
|
||||
|
||||
|
@ -29,6 +55,29 @@ class AccountResource(ProtectedResource):
|
|||
abort(403, message='You can only get your own account', status='error')
|
||||
|
||||
|
||||
class RoleResource(ProtectedResource):
|
||||
@swag_from('swagger/get_role_spec.yaml')
|
||||
def get(self, role_id):
|
||||
return RoleWrapperSchema().dump(
|
||||
{'role': accounts.get_role(role_id)}), 200
|
||||
|
||||
|
||||
class RolesResource(ProtectedResource):
|
||||
@use_args(RoleCreationWrapperSchema())
|
||||
@swag_from('swagger/create_role_spec.yaml')
|
||||
def post(self, args):
|
||||
args = args['role']
|
||||
success = accounts.create_role(args['display_name'],
|
||||
args['permissions'])
|
||||
if success:
|
||||
return '', 201
|
||||
|
||||
@swag_from('swagger/get_roles_spec.yaml')
|
||||
def get(self):
|
||||
return RolesWrapperSchema().dump(
|
||||
{'roles': accounts.get_all_roles()}), 200
|
||||
|
||||
|
||||
class AccountRoleResource(ProtectedResource):
|
||||
@use_args(RoleUpdateSchema())
|
||||
@swag_from('swagger/update_account_role_spec.yaml')
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 55611f1868bd
|
||||
Revises: 5aa58dcd7a2c
|
||||
Create Date: 2018-09-23 00:56:34.193022
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '55611f1868bd'
|
||||
down_revision = '5aa58dcd7a2c'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('roles', sa.Column('permissions', sa.ARRAY(sa.String()), nullable=True))
|
||||
op.create_unique_constraint(None, 'roles', ['display_name'])
|
||||
role = sa.table('roles', sa.column('id', sa.Integer),
|
||||
sa.column('permissions', sa.ARRAY(sa.String)))
|
||||
op.execute(role.update().where(role.c.id == op.inline_literal(1)).
|
||||
values({'permissions':
|
||||
['CREATE_DEVICE_TYPE', 'ASSIGN_ROLE',
|
||||
'CREATE_DEVICE', 'CREATE_DASHBOARD',
|
||||
'READ_DEVICE_TYPES', 'READ_ROLES']})
|
||||
)
|
||||
|
||||
op.execute(role.update().where(role.c.id == op.inline_literal(2)).
|
||||
values({'permissions':
|
||||
['CREATE_DEVICE', 'CREATE_DASHBOARD',
|
||||
'READ_DEVICE_TYPES', 'READ_ROLES']})
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'roles', type_='unique')
|
||||
op.drop_column('roles', 'permissions')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue