Compare commits

...

2 Commits

  1. 2
      __init__.py
  2. 10
      resource.py
  3. 86
      views.py

@ -11,7 +11,7 @@ class MongoApi:
app: Flask = None app: Flask = None
authentication_methods: list = [] authentication_methods: list = []
def __init__(self, app: Flask, authentication_methods): def __init__(self, app: Flask, authentication_methods=[]):
self.app = app self.app = app
self.authentication_methods = authentication_methods self.authentication_methods = authentication_methods

@ -104,10 +104,14 @@ class Resource:
data.get(**{self.as_pk: pk}) data.get(**{self.as_pk: pk})
return data return data
def to_json(self, pk: str = None) -> tuple: def to_json(self, pk: str = None, qs=None) -> tuple:
if qs is None:
if self.mongo_qs is None:
self.mongo_qs = self.to_qs(pk)
else:
self.mongo_qs = qs
if self.mongo_qs is None:
self.mongo_qs = self.to_qs(pk)
data = self.mongo_qs data = self.mongo_qs
count = data.count() count = data.count()

@ -5,7 +5,7 @@ import mongoengine
from flask import jsonify, request from flask import jsonify, request
from flask_views.base import View from flask_views.base import View
from mongoengine import ValidationError, DoesNotExist, InvalidQueryError from mongoengine import ValidationError, DoesNotExist, InvalidQueryError
from werkzeug.exceptions import Unauthorized, NotFound from werkzeug.exceptions import Unauthorized, NotFound, Forbidden
from restapi.resource import Resource from restapi.resource import Resource
@ -14,7 +14,7 @@ class ApiView(View):
model = None model = None
authentication_methods = [] authentication_methods = []
def __init__(self, model,authentication_methods): def __init__(self, model, authentication_methods):
self.start = time.time() self.start = time.time()
self.model = model self.model = model
self.resource = Resource(self.model) self.resource = Resource(self.model)
@ -28,22 +28,28 @@ class ApiView(View):
def _dispatch_request(self, *args, **kwargs): def _dispatch_request(self, *args, **kwargs):
authorized = True if len(self.authentication_methods) == 0 else False authorized = True if len(self.authentication_methods) == 0 else False
autherror = None
for authentication_method in self.authentication_methods: for authentication_method in self.authentication_methods:
if authentication_method().authorized(): authclass = authentication_method()
if authclass.authorized():
authorized = True authorized = True
else:
autherror = authclass.get_error()
if not authorized: if not authorized:
return {'error': 'Unauthorized'}, '401 Unauthorized' return {'error': 'Unauthorized', "message": str(autherror), "status": False}, '401 Unauthorized'
try: try:
return super(ApiView, self).dispatch_request(*args, **kwargs) return super(ApiView, self).dispatch_request(*args, **kwargs)
except mongoengine.queryset.DoesNotExist as e: except mongoengine.queryset.DoesNotExist as e:
return {'error': 'Empty query: ' + str(e)}, '404 Not Found' return {'error': 'empty_query', "message": str(e), "status": False}, '404 Not Found'
except ValidationError as e: except ValidationError as e:
return e.args[0], '400 Bad Request' return {"error": "bad_request", "message": e.args, "status": False}, '400 Bad Request'
except Unauthorized: except Unauthorized:
return {'error': 'Unauthorized'}, '401 Unauthorized' return {'error': 'Unauthorized', "status": False}, '401 Unauthorized'
except Forbidden:
return {'error': 'Access_Denied', "status": False}, '403 Access Denied'
except NotFound as e: except NotFound as e:
return {'error': str(e)}, '404 Not Found' return {'error': str(e), "status": False}, '404 Not Found'
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
""" """
@ -55,7 +61,8 @@ class ApiView(View):
if 'pk' in kwargs: if 'pk' in kwargs:
try: try:
qs = self.resource.to_qs(pk=kwargs.get('pk')) qs = self.resource.to_qs(pk=kwargs.get('pk'))
count, data = self.resource.to_json(pk=kwargs.get('pk')) qs = self.has_read_permission(qs)
count, data = self.resource.to_json(pk=kwargs.get('pk'), qs=qs)
response = { response = {
'response': data, 'response': data,
'status': True, 'status': True,
@ -73,7 +80,9 @@ class ApiView(View):
if "query" in request.args and self.model._meta.get('can_query'): if "query" in request.args and self.model._meta.get('can_query'):
self.resource.external_query(json.loads(request.args.get('query'))) self.resource.external_query(json.loads(request.args.get('query')))
qs = self.resource.to_qs() qs = self.resource.to_qs()
count, data = self.resource.to_json() qs = self.has_read_permission(qs)
count, data = self.resource.to_json(qs=qs)
response = { response = {
'response': data, 'response': data,
'info': { 'info': {
@ -89,8 +98,6 @@ class ApiView(View):
def post(self, *args, **kwargs): def post(self, *args, **kwargs):
""" """
TODO: check permissions
:param args: :param args:
:param kwargs: :param kwargs:
:return: :return:
@ -109,8 +116,20 @@ class ApiView(View):
'status': False, 'status': False,
'errors': str(e) 'errors': str(e)
}), 400 }), 400
data = item.save() resp, obj = self.has_add_permission(item)
return self.get(pk=data.id, code=201) from flask import current_app
if resp:
try:
item = obj
data = item.save()
except Exception as e:
current_app.logger.error(e)
current_app.logger.info(item.pk)
return self.get(pk=item.pk, code=201)
else:
raise Forbidden()
def put(self, *args, **kwargs): def put(self, *args, **kwargs):
""" """
@ -127,7 +146,15 @@ class ApiView(View):
}), 403 }), 403
else: else:
try: try:
self.model.objects(id=kwargs.get('pk')).update(**request.json) item = self.model.objects.get(id=kwargs.get('pk'))
updata = request.json
resp, obj = self.has_change_permission(item, updata)
from flask import current_app
if resp:
updata = obj
item.update(**updata)
else:
raise Forbidden()
return self.get(pk=kwargs.get('pk')) return self.get(pk=kwargs.get('pk'))
except ValidationError as v: except ValidationError as v:
print(v.__dict__) print(v.__dict__)
@ -141,16 +168,31 @@ class ApiView(View):
'errors': str(e) 'errors': str(e)
}), 400 }), 400
def has_read_permission(self, request, qs): def has_read_permission(self, qs):
for authentication_method in self.authentication_methods:
authclass = authentication_method()
qs = authclass.has_model_read_permission(qs)
return qs return qs
def has_add_permission(self, request, obj): def has_add_permission(self, obj):
return True has_ret = False
for authentication_method in self.authentication_methods:
def has_change_permission(self, request, obj): authclass = authentication_method()
return True resp, obj = authclass.has_model_write_permission(obj)
if resp:
has_ret = True
return has_ret, obj
def has_change_permission(self, obj, update):
has_ret = False
for authentication_method in self.authentication_methods:
authclass = authentication_method()
resp, obj = authclass.has_model_update_permission(obj, update)
if resp:
has_ret = True
return has_ret, update
def has_delete_permission(self, request, obj): def has_delete_permission(self, obj):
return True return True
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):

Loading…
Cancel
Save