Skip to content

Commit

Permalink
Merge pull request #69 from MPrevide/group-perm
Browse files Browse the repository at this point in the history
System permission
  • Loading branch information
mprevide committed Dec 26, 2018
2 parents 4942d9e + 6c06c44 commit efb9150
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 35 deletions.
40 changes: 24 additions & 16 deletions auth/controller/CRUDController.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sqlalchemy.orm.exc as orm_exceptions

import controller.PasswordController as password
from database.Models import Permission, User, Group, PermissionEnum
from database.Models import Permission, User, Group, PermissionEnum, PermissionTypeEnum
import controller.RelationshipController as rship
from database.Models import UserPermission, GroupPermission, UserGroup
from database.flaskAlchemyInit import HTTPRequestError
Expand Down Expand Up @@ -343,15 +343,15 @@ def create_perm(db_session, permission, requester):
check_perm(permission)
permission['created_by'] = requester['userid']
perm = Permission(**permission)
log().info(f"permission {perm.name} deleted by {requester['username']}")
log().info(f"permission {perm.name} create by {requester['username']}")
log().info(perm.safe_dict())

db_session.add(perm)
db_session.commit()
return perm


def search_perm(db_session, path=None, method=None, permission=None):
def search_perm(db_session, path=None, method=None, permission=None, type=None):
"""
Retrieves a set of permissions from database.
:param db_session: The postgres session to be used.
Expand All @@ -374,6 +374,11 @@ def search_perm(db_session, path=None, method=None, permission=None):
raise HTTPRequestError(400, f"Invalid filter. Permission can't be {permission}")
perm_query = perm_query.filter_by(permission=permission)

if type:
if type not in [p.value for p in PermissionTypeEnum]:
raise HTTPRequestError(400, f"Invalid filter. Permission type can't be {type}")
perm_query = perm_query.filter_by(type=type)

perms = perm_query.all()
if not perms:
raise HTTPRequestError(404, "No results found with these filters")
Expand Down Expand Up @@ -427,19 +432,22 @@ def delete_perm(db_session, permission: str, requester):
"""
try:
perm = Permission.get_by_name_or_id(permission)
db_session.execute(
UserPermission.__table__.delete(UserPermission.permission_id == perm.id)
)
db_session.execute(
GroupPermission.__table__.delete(GroupPermission.permission_id == perm.id)
)
cache.delete_key(action=perm.method, resource=perm.path)
log().info(f"permission {perm.name} deleted by {requester['username']}")
log().info(perm.safe_dict())
db_session.delete(perm)
db_session.commit()
MVUserPermission.refresh()
MVGroupPermission.refresh()
if perm.type == PermissionTypeEnum.api:
db_session.execute(
UserPermission.__table__.delete(UserPermission.permission_id == perm.id)
)
db_session.execute(
GroupPermission.__table__.delete(GroupPermission.permission_id == perm.id)
)
cache.delete_key(action=perm.method, resource=perm.path)
log().info(f"permission {perm.name} deleted by {requester['username']}")
log().info(perm.safe_dict())
db_session.delete(perm)
db_session.commit()
MVUserPermission.refresh()
MVGroupPermission.refresh()
else:
raise HTTPRequestError(405, "Can't delete a system permission")
except orm_exceptions.NoResultFound:
raise HTTPRequestError(404, "No permission found with this ID or name")

Expand Down
33 changes: 24 additions & 9 deletions auth/database/Models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ class PermissionEnum(enum.Enum):
notApplicable = 'notApplicable'


class PermissionTypeEnum(enum.Enum):
system = 'system'
api = 'api'
notApplicable = 'notApplicable'


# Model for the database tables
class Permission(db.Model):
__tablename__ = 'permission'

# fields that can be filled by user input
fillable = ['name', 'path', 'method', 'permission']
fillable = ['name', 'path', 'method', 'permission', 'type']

def as_dict(self):
"""
Expand All @@ -38,6 +44,12 @@ def as_dict(self):
}
if type(tmp_dict['permission']) != str:
tmp_dict['permission'] = tmp_dict['permission'].value

if (not tmp_dict['type'] is None) and type(tmp_dict['type']) != str:
tmp_dict['type'] = tmp_dict['type'].value
elif tmp_dict['type'] is None:
tmp_dict['type'] = PermissionTypeEnum.api.value

return tmp_dict

def safe_dict(self):
Expand All @@ -62,6 +74,7 @@ def get_by_name_or_id(name_id: str):
unique=True, index=True)
method = Column(String(PermissionLimits.method), nullable=False)
permission = Column(Enum(PermissionEnum), nullable=False)
type = Column(Enum(PermissionTypeEnum), nullable=False, default=PermissionTypeEnum.api)

created_date = Column(DateTime, default=datetime.datetime.utcnow)
created_by = Column(Integer, nullable=False)
Expand Down Expand Up @@ -209,10 +222,11 @@ class PasswordRequest(db.Model):

class MVUserPermission(db.Model):
selectClause = db.select([UserPermission.user_id,
Permission.id,
Permission.path,
Permission.method,
Permission.permission, ]
Permission.id,
Permission.path,
Permission.method,
Permission.permission,
Permission.type, ]
).select_from(db.join(UserPermission, Permission))

__table__ = create_mat_view('mv_user_permission',
Expand All @@ -233,10 +247,11 @@ def refresh(concurrently=False):

class MVGroupPermission(db.Model):
selectClause = db.select([GroupPermission.group_id,
Permission.id,
Permission.path,
Permission.method,
Permission.permission, ]
Permission.id,
Permission.path,
Permission.method,
Permission.permission,
Permission.type,]
).select_from(db.join(GroupPermission,
Permission))

Expand Down
3 changes: 2 additions & 1 deletion auth/initialConf.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,13 @@ def create_groups():

# A utility function to create a permission dict
# so the List 'predefPerms' get less verbose
def permission_dict_helper(name, path, method, permission=PermissionEnum.permit):
def permission_dict_helper(name, path, method, permission=PermissionEnum.permit, type_perm=PermissionTypeEnum.system):
return {
"name": name,
"path": path,
"method": method,
"permission": permission,
"type": type_perm,
"created_by": 0
}

Expand Down
5 changes: 3 additions & 2 deletions auth/webRoutes.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

from utils.serialization import json_serial


# Authentication endpoint
@app.route('/', methods=['POST'])
def authenticate():
Expand Down Expand Up @@ -116,8 +117,8 @@ def list_permissions():
# search filters
request.args['path'] if 'path' in request.args else None,
request.args['method'] if 'method' in request.args else None,
request.args['permission']
if 'permission' in request.args else None
request.args['permission'] if 'permission' in request.args else None,
request.args['type'] if 'type' in request.args else None
)
permissions_safe = list(map(lambda p: p.safe_dict(), perms))
return make_response(json.dumps({"permissions": permissions_safe}, default=json_serial), 200)
Expand Down
15 changes: 12 additions & 3 deletions docs/crud-api.apib
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ also be escaped
"id": 131
}

### Search permission [GET /pap/permission?{path,method,permission}]
### Search permission [GET /pap/permission?{path,method,permission,type}]

+ Parameters
+ path: \/devices\/info (optional, string) - a path string.
+ method: POST (optional, enum) - one HTTP method.
+ permission: permit (optional, enum) - "permit" or "deny".
+ type: api (optional, enum) - "api" or "system"

+ Request (application/json)
+ Headers
Expand All @@ -54,7 +55,8 @@ also be escaped
"id" : 131,
"path" : "/devices/info/\\*",
"method" : "POST|PUT|DELETE",
"permission" : "permit"
"permission" : "permit",
"type": "api"
}
]
}
Expand Down Expand Up @@ -84,7 +86,8 @@ also be escaped
"id" : 131,
"path" : "/devices/info/\\*",
"method" : "POST|PUT|DELETE",
"permission" : "permit"
"permission" : "permit",
"type": "api"
}


Expand Down Expand Up @@ -145,6 +148,12 @@ also be escaped
"status": 404,
"message": "No permission found with this ID"
}
+ Response 405 (application/json)

{
"status": 405,
"message": "Can't delete a system permission"
}

## Group creation [/pap/group]
### Create a new group [POST]
Expand Down
25 changes: 21 additions & 4 deletions tests/dredd-hooks/clear_data_hook.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import dredd_hooks as hooks
import controller.CRUDController as crud
from database.Models import PermissionTypeEnum
from database.flaskAlchemyInit import db
from database.flaskAlchemyInit import HTTPRequestError

from database.flaskAlchemyInit import log


@hooks.before_all
def auth_clear_permissions_and_groups(transaction):
requester = {
"userid": 0,
"username": "dredd"
}
log().info(">>>>>>> Limpando cenario para proxima execucao...")
try:
users = crud.search_user(db.session, None)
# Delete all users
Expand All @@ -20,10 +24,14 @@ def auth_clear_permissions_and_groups(transaction):

try:
permissions = crud.search_perm(db.session)
log().info(">>>>>>> Removendo permissao: ")
for permission in permissions:
crud.delete_perm(db.session, permission.name, requester)
log().info(">>>>>>> Permissao: " + permission.name + ", tipo: " + permission.type.value)
if permission.type != PermissionTypeEnum.system:
crud.delete_perm(db.session, permission.name, requester)
except HTTPRequestError as e:
pass
log().error(">>>>> Excecao durante remocao de permissao: " + e)
# pass

try:
groups = crud.search_group(db.session)
Expand All @@ -32,13 +40,16 @@ def auth_clear_permissions_and_groups(transaction):
except HTTPRequestError as e:
pass

log().info(">>>>>>> ... cenario foi limpo.")


@hooks.after_each
def auth_clear_everything_hook(transaction):
requester = {
"userid": 0,
"username": "dredd"
}
log().info(">>>>>>> Limpando cenario apos execucao de caso de teste...")
try:
users = crud.search_user(db.session, None)
# Delete all users
Expand All @@ -49,14 +60,20 @@ def auth_clear_everything_hook(transaction):

try:
permissions = crud.search_perm(db.session)
log().info(">>>>>>> Removendo permissao: ")
for permission in permissions:
crud.delete_perm(db.session, permission.name, requester)
log().info(">>>>>>> Permissao: " + permission.name + ", tipo: " + permission.type.value)
if permission.type != PermissionTypeEnum.system:
crud.delete_perm(db.session, permission.name, requester)
except HTTPRequestError as e:
pass
log().error(">>>>> Excecao durante remocao de permissao: " + e)
# pass

try:
groups = crud.search_group(db.session)
for group in groups:
crud.delete_group(db.session, group.name, requester)
except HTTPRequestError as e:
pass

log().info(">>>>>>> ... cenario foi limpo apos execucao de caso de teste.")

0 comments on commit efb9150

Please sign in to comment.