예제 #1
0
 def login(self):
     body = request.json
     if body['password'] != body['confirmpassword']:
         raise BussinessException("error",400,"confirm password mismatch") 
     db = self.getConnection()
     payload = {}    
     result = db.user.find_one({'email':body['email'],'password':body['password']},{'_id':True,'isAdmin':True, 'firstName': True, 'lastName': True})
     if not result:
         raise BussinessException("error",400,"Check your username and passsword!")
     payload['id'] = str(result['_id'])
     payload['firstName'] = result['firstName']
     payload['firstName'] = result['lastName']
     if result.get('isAdmin',None):
         payload['role'] = 'admin'
     else:
         payload['role'] = 'user'
     timestamp = self._current_timestamp()
     payload = {
         "iss": JWT_ISSUER,
         "iat": int(timestamp),
         "exp": int(timestamp + JWT_LIFETIME_SECONDS),
         "sub": json.dumps(payload),
     }
     # token must contain role and id of the user under sub key
     return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
예제 #2
0
 def deleteStaticUsingUnique(self,unique):
     resource = self.__static_collection
     if not unique:
         raise BussinessException("error",400, "Invalid file name")
     result = self.db[resource].delete_one({"unique": unique})
     if not result.deleted_count:
         raise BussinessException("error",400, "File not found")
     return {"file": unique, "detail": "File successfully removed"}, 200
예제 #3
0
 def deleteStatic(self,type,id):
     resource = self.__static_collection
     obj_id = convertToObjectId(id)
     if not obj_id:
         raise BussinessException("error",400, "Invalid file url")
     result = self.db[resource].delete_one({"_id": obj_id})
     if not result.deleted_count:
         raise BussinessException("error",400, "File not found")
     return {"url": type+"/"+id, "detail": "File successfully removed"}, 200
예제 #4
0
    def checkStaticAuthz(self, request, token):

        if self.__static_rules == None:
            raise BussinessException("error", 500,
                                     "No rules defined; Contact Admin")

        # the static rest api must be static/{type}/{id}
        auth_type = request.view_args.get("type", None)
        obj_id = request.view_args.get("id", None)

        if auth_type is None or obj_id is None:
            raise BussinessException("error", 500,
                                     "Authz error; Contact Admin")

        subject = json.loads(token['sub'])
        role = subject['role']
        user_id = subject['id']
        if role in self.__roles_global:
            return True

        required_type = self.__static_rules.get(auth_type, None)
        if not required_type:
            return True  # if url don't exist, return true
        authz_list = required_type.get(request.method, None)
        if authz_list == None:
            return True  # if method don't exist, return true

        for authz in authz_list:
            if authz == "all":
                return True
            elif authz.find(":") == -1:
                if role == authz:
                    return True
            else:
                # check for curr attr
                values = authz.split(":")
                if values[1] == "curr":
                    obj_id = convertToObjectId(obj_id)
                    if not obj_id:
                        raise BussinessException("error", 400,
                                                 "Invalid File id")
                    result = self.db[self.__static_collection].find_one(
                        {"_id": obj_id}, {
                            "_id": False,
                            "owner": True
                        })
                    if not result:
                        raise BussinessException("error", 400,
                                                 "File not found")
                    if user_id == result["owner"] and values[0] == role:
                        return True
                else:
                    # check at application start and do sys.exit
                    raise BussinessException("error", 500,
                                             "Authz error; Contact Admin")
        return False
예제 #5
0
 def retrieve(self, obj_id, resource = None, projection = None):
     resource = resource if resource else self.resource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     result = self.db[resource].find_one({"_id": obj_id}, mask)
     if not result:
         raise BussinessException("error",400,resource + " not found")
     return result, 200
예제 #6
0
 def remove(self, obj_id, resource = None, projection = None):
     resource = resource if resource else self.resource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400, "Invalid " + resource + " id")
     result = self.db[resource].delete_one({"_id": obj_id})
     if not result.deleted_count:
         raise BussinessException("error",400,resource + " not found")
     return {"id": obj_id, "detail": resource  + " successfully removed"}, 200
예제 #7
0
 def update(self, obj_id, data, resource = None, projection = None):
     resource = resource if resource else self.resource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     result = self.db[resource].update_one({"_id": obj_id}, {'$set': data})
     if not result.matched_count:
         raise BussinessException("error",400,resource + " not found")
     return self.db[resource].find_one({"_id": obj_id}, mask), 200
예제 #8
0
 def remove_subdocument(self, obj_id, resource = None, subresource = None, projection = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     mask = self.projection_helper(projection,subresource) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400, "Invalid " + resource + " id")
     result = self.db[resource].update_one({"_id": obj_id}, {'$unset': { subresource : ""}})
     if not result.matched_count:
         raise BussinessException("error",400,subresource + " not found")
     return {"id": obj_id, "detail": subresource  + " successfully removed"}, 200
예제 #9
0
 def retriveStatic(self,type,id):
     resource = self.__static_collection
     obj_id = convertToObjectId(id)
     if not obj_id:
         raise BussinessException("error",400, "Invalid file url")
     result = self.db[resource].find_one({"_id": obj_id},{"_id": False,"binary": True})
     if not result:
         raise BussinessException("error",400, "File not found")
     response =  send_file(io.BytesIO(result['binary']), attachment_filename="download.pdf", as_attachment=True)
     response.headers["Content-Type"] = 'application/pdf'
     response.direct_passthrough = False
     return response, 200
예제 #10
0
 def insert_array(self, obj_id, data, resource = None, subresource = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     data = {
         subresource : data
     }
     result = self.db[resource].update_one({"_id": obj_id}, {'$push': data})
     if not result.matched_count:
         raise BussinessException("error",400,subresource + " not found")
     return self.db[resource].find_one({"_id": obj_id})[subresource], 200
예제 #11
0
 def retrieve_array(self, obj_id, resource = None, subresource = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     result = self.db[resource].find_one({"_id": obj_id})
     if not result:
         raise BussinessException("error",400,resource + " list is empty")
     result = result.get(subresource,None)
     if not result:
         raise BussinessException("error",400,resource + " not found")
     return result, 200
예제 #12
0
    def checkAuthz(self, request, token):

        #check if the url is static
        if str(request.url_rule) == "/static/<type>/<id>":
            return self.checkStaticAuthz(request, token)

        if self.__rules == None:
            raise BussinessException("error", 500,
                                     "No rules defined; Contact Admin")

        subject = json.loads(token['sub'])
        role = subject['role']
        id = subject['id']
        if role in self.__roles_global:
            return True
        rule = self.__rules.get(str(request.url_rule), None)
        if not rule:
            raise BussinessException("error", 500,
                                     "Authz error; Contact Admin")
        authz_list = rule.get(request.method, None)
        if authz_list == None:
            raise BussinessException("error", 500,
                                     "Authz error; Contact Admin")
        for authz in authz_list:
            if authz == "all":
                return True
            elif authz.find(":") == -1:
                if role == authz:
                    return True
            else:
                # check for curr attr
                values = authz.split(":")
                if values[1] == "curr":
                    # get first path param name
                    url_rule = str(request.url_rule)
                    start = url_rule.find("<")
                    end = url_rule.find(">")
                    if start == -1 and end == -1:
                        raise BussinessException("error", 500,
                                                 "Authz error; Contact Admin")
                    first_param = url_rule[start + 1:end]
                    first_param_value = request.view_args.get(
                        first_param, None)
                    if id == first_param_value and values[0] == role:
                        return True
                else:
                    # check at application start and do sys.exit
                    raise BussinessException("error", 500,
                                             "Authz error; Contact Admin")
        return False
예제 #13
0
 def retrieveAll_subdocument_array(self, obj_id, resource = None, subresource = None, projection = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     result = self.db[resource].find_one({"_id": obj_id}, mask)
     if not result:
         raise BussinessException("error",400,resource + " list is empty")
     result = result.get(subresource,None)
     if not result:
         raise BussinessException("error",400,resource + " not found")
     return result, 200
예제 #14
0
 def insert_subdocument_array(self, obj_id, data, resource = None, subresource = None, projection = None, objectId = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     sub_obj_id = data["_id"] = objectId if objectId else ObjectId() # sub_obj_id
     data = {
         subresource : data
     }
     result = self.db[resource].update_one({"_id": obj_id}, {'$push': data})
     if not result.matched_count:
         raise BussinessException("error",400,subresource + " not found")
     return self.db[resource].find_one({ subresource+"._id" :  sub_obj_id }, {subresource + ".$" : 1}).get(subresource)[0]
예제 #15
0
 def remove_subdocument_array(self, obj_id, sub_obj_id, resource = None, subresource = None, projection = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     sub_obj_id = convertToObjectId(sub_obj_id)
     if not sub_obj_id:
         raise BussinessException("error",400,resource + "Invalid " + subresource + " id")
     result = self.db[resource].find_one({ subresource+"._id" :  sub_obj_id }, {subresource + ".$" : 1})
     if not result:
         raise BussinessException("error",400,resource + subresource + " not found")
     result = self.db[resource].update_one({ "_id": obj_id}, {'$pull': {subresource : {"_id" : sub_obj_id }}})
     # since we find with obj_id, it always matches and result.matchcount will be 1
     return {"id": sub_obj_id, "detail": subresource  + " successfully removed"}, 200
예제 #16
0
 def retrieveAll(self, search=None, resource = None, projection = None):
     resource = resource if resource else self.resource
     mask = self.projection_helper(projection) if projection else self.mask
     result = list(self.db[resource].find(search, mask))
     if not result:
         raise BussinessException("error",400,resource + " list is empty")
     return result, 200
예제 #17
0
 def update_subdocument(self, obj_id, data, unset_data = None, resource = None, subresource = None, projection = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     mask = self.projection_helper(projection,subresource) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     # optimse this using only data and removing unset_data
     update = {}
     if data:
         update['$set'] = self.subresource_update_data_helper(data, subresource)
     if unset_data:
         update['$unset'] = self.subresource_update_data_helper(unset_data, subresource)
     result = self.db[resource].update_one({"_id": obj_id}, update)
     if not result.matched_count:
         raise BussinessException("error",400,resource + " not found")
     return self.db[resource].find_one({"_id": obj_id}, mask)[subresource], 200
예제 #18
0
 def remove_array(self, obj_id, value, resource = None, subresource = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,"Invalid " + resource + " id")
     print(value)
     self.db[resource].update_one({ "_id": obj_id}, {'$pull': {subresource : { '$in': [value] }}})
     return self.db[resource].find_one({"_id": obj_id})[subresource], 200    
예제 #19
0
 def insert(self, data, resource = None, projection = None, objectId = None):
     resource = resource if resource else self.resource
     mask = self.projection_helper(projection) if projection else self.mask
     if objectId:
         data["_id"] = objectId
     try:
         obj_id = self.db[resource].insert_one(data).inserted_id
     except errors.DuplicateKeyError:
         raise BussinessException("error",400,resource + " already exists")
     return self.db[resource].find_one({"_id": obj_id}, mask), 200
예제 #20
0
 def update_subdocument_array(self, obj_id, data, sub_obj_id, resource = None, subresource = None, projection = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400, "Invalid " + resource + " id")
     sub_obj_id = convertToObjectId(sub_obj_id)
     if not sub_obj_id:
         raise BussinessException("error",400,resource + subresource + " id")
     data = self.subresource_array_update_data_helper(data,subresource)
     result = self.db[resource].update_one({ subresource+"._id" :  sub_obj_id}, {'$set': data })
     if not result.matched_count:
         raise BussinessException("error",400,subresource + " not found")
     result = self.db[resource].find_one({ subresource+"._id" :  sub_obj_id}, mask)
     result = result.get(subresource,None)[0]
     if not result:
         raise BussinessException("error",400,resource + subresource + " not found")
     return result, 200
예제 #21
0
 def decode_token(token):
     try:
         decoded_token =  jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
         authz = Authz.getInstance()
         allow = authz.checkAuthz(request,decoded_token)
         if not allow:
             raise BussinessException("Forbidden",403,"No permission")
         return decoded_token
     except JWTError as e:
         six.raise_from(Unauthorized, e)
예제 #22
0
 def retrieve_subdocument_array(self, obj_id, sub_obj_id, resource = None, subresource = None, projection = None):
     resource = resource if resource else self.resource
     subresource = subresource if subresource else self.subresource
     mask = self.projection_helper(projection) if projection else self.mask
     obj_id = convertToObjectId(obj_id)
     if not obj_id:
         raise BussinessException("error",400,resource + "Invalid " + resource + " id")
     sub_obj_id = convertToObjectId(sub_obj_id)
     if not sub_obj_id:
         raise BussinessException("error",400,resource + "Invalid " + subresource + " id")
     print(subresource)
     result = self.db[resource].find_one({ subresource+"._id" :  sub_obj_id }, {subresource + ".$" : 1})
     # Using non-Index field to query. Use aggregate to improve performace.
     # query with parent index and then with sub index
     if not result:
         raise BussinessException("error",400,resource + " not found")
     result = result.get(subresource,None)[0]
     if not result:
         raise BussinessException("error",400,resource + " not found")
     return result, 200
예제 #23
0
    def uploadStatic(self,file,meta,owner,doc_prefix,unique,max):

        if file is None:
            raise BussinessException("error",400, "No file attached.")

        if owner is None:
            raise BussinessException("error",500,"Authz error; Contact Admin")

        if doc_prefix is None:
            raise BussinessException("error",500,"Authz error; Contact Admin")

        resource = self.__static_collection
        data = {}

        if file.filename == '':
            raise BussinessException("error",400, "No file selected")
        if not self.allowed_file(file.filename):
            raise BussinessException("error",400, "File format not allowed")

        # filenames can be dangerous, so use secure_filename
        meta['filename'] = secure_filename(file.filename)
        data['binary'] = file.read()
        data['meta'] = meta
        data['owner'] = owner

        if unique:     
            data['unique'] = unique

            try:
                # replace_one doc - https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.replace_one
                result = self.db[resource].replace_one({"unique": unique},data, True)
                if result.matched_count > 1:
                    pass # TODO log this part; dont throw error.
            except:
                raise BussinessException("error",500, "Upload document failed")

            obj_id = self.db[resource].find_one({"unique": unique}, {"_id": True})["_id"]
        
        else: 
             obj_id = self.db[resource].insert_one(data,{"_id": True}).inserted_id

        return "/"+doc_prefix+"/"+str(obj_id)