Просмотр исходного кода

basic api inventory implemented

ash 2 лет назад
Родитель
Сommit
24ae865395

+ 6 - 0
Backend/Sources/Model/model_manager.py

@@ -1,4 +1,5 @@
 from pyexpat import model
+from sys import modules
 from sqlalchemy.ext.declarative import DeclarativeMeta
 from sqlalchemy import null
 from utility.app_logging import *
@@ -22,14 +23,19 @@ def declare_model():
     # OpenISP Inventory Model
     import Modules.Inventory.inventory_model
 
+
+
 def init() :
     import Model.isp_model
     import persistence
+    import Modules.Inventory.inventory_model
     with persistence.get_Session_Instance() as sess : ##TODO maybe not the best place to perform that
         Item = sess.query(Model.isp_model.user_account).filter(Model.isp_model.user_account.nickname == "admin").first()
         if not isinstance(Item,Model.isp_model.user_account):
             Item = Model.isp_model.user_account(id = 1, nickname = "admin",description = "admin account", is_super_admin = True,password = generate_password_hash("aseqzdwxc"))
+            obj = Modules.Inventory.inventory_model.inventory_item(name = "mikrotik rb2011 saline 1",brand= "mikrotik",note="router saline2")
             sess.add(Item)
+            sess.add(obj)
             sess.commit()
             logger.debug("Admin account created")
         else :

+ 1 - 1
Backend/Sources/Modules/Inventory/inventory.py

@@ -94,7 +94,7 @@ def __getItem(id : int ,objectype) :
     with persistence.get_Session_Instance() as sess :
         Item = sess.query(objectype).filter(objectype.id == id).first()
         if not isinstance(Item,objectype):
-            raise BaseException("object not found with this id")
+            raise Exception("object not found with this id")
 
 
         return Item

+ 1 - 1
Backend/Sources/Modules/Inventory/inventory_model.py

@@ -11,7 +11,7 @@ __db_Base = persistence.get_db_base()
 class inventory_site(__db_Base):
     __tablename__      = "tInventory_sites"
     id                 = Column(Integer,Sequence('inventory_site_id_seq'), primary_key=True, nullable=False)
-    name               = Column(String(150))
+    name               = Column(String(150), nullable=False)
     address            = Column(String)
     gps_coordinates    = Column(String)
     note               = Column(String)

+ 110 - 1
Backend/Sources/Modules/Inventory/inventory_view.py

@@ -1,15 +1,25 @@
+import profile
 from Model.isp_model import user_account
 import View.view_privilege as view_privilege
 from utility.privilege_manager import *
 import persistence
 import Model.isp_model
+import Model.model_manager as model_manager
 import json
+import flask
+import View.view_manager as view
+import Modules.Inventory.inventory as inventory
+
+
+from flask import Blueprint
+inventory_blueprint = Blueprint('Inventory', __name__,url_prefix='/inventory')
+
+
 
 inventory_read_only_role  = Privilege_Role(name="read_only")
 inventory_admin_role      = Privilege_Role(name="admin")
 
 
-
 def init():
     inventory_privilege_domain = Privilege_Domain("inventory",description="privilege domain for inventory")
     view_privilege.manager.register_domain(inventory_privilege_domain)
@@ -18,3 +28,102 @@ def init():
     inventory_privilege_domain.include_role(inventory_admin_role,inventory_read_only_role)
 
 
+    declare_route()
+    view.register_blueprint(inventory_blueprint)
+
+"""
+# INVENTORY
+inventory/items - GET -> get all items
+inventory/item - POST create items
+inventory/item/<item_id> - GET get item by id
+inventory/item/<item_id> - UPDATE  item by id
+inventory/item/<item_id> - DELETE item by id
+
+inventory/sites - GET -> get all site
+inventory/site - POST create site
+inventory/site/<site_id> - GET get site by id
+inventory/site/<site_id> - UPDATE  site by id
+inventory/site/<site_id> - DELETE site by id
+
+inventory/contacts - GET -> get all contact
+inventory/contact - POST create contact
+inventory/contact/<contact_id> - GET get contact by id
+inventory/contact/<contact_id> - UPDATE  contact by id
+inventory/contact/<contact_id> - DELETE contact by id
+
+inventory/groups - GET -> get all groups with items array id
+inventory/group - POST create group with items ids
+inventory/group/<contact_id> - GET get group by id
+inventory/group/<contact_id>/item/<item_id> - POST  add item to group
+inventory/group/<contact_id>/item/<item_id> - DELETE  delete item to group
+inventory/group/<contact_id> - DELETE group by id
+"""
+
+def declare_route() :
+
+    #the order of decorator are important
+    @inventory_blueprint.route('/items',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_all_items() :
+        ret = list()
+        for item in inventory.get_all_inventory_items() :
+            ret.append(model_manager.ModelObjectToJsonString(item))
+
+        return flask.jsonify(ret)
+
+
+    @inventory_blueprint.route('/sites',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_all_sites() :
+        ret = list()
+        for item in inventory.get_all_inventory_sites() :
+            ret.append(model_manager.ModelObjectToJsonString(item))
+
+        return flask.jsonify(ret)
+
+
+    @inventory_blueprint.route('/contacts',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_all_contacts() :
+        ret = list()
+        for item in inventory.get_all_inventory_contacts() :
+            ret.append(model_manager.ModelObjectToJsonString(item))
+
+        return flask.jsonify(ret)
+
+
+    @inventory_blueprint.route('/groups',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_all_groups() :
+        ret = list()
+        for item in inventory.get_all_inventory_groups() :
+            ret.append(model_manager.ModelObjectToJsonString(item))
+
+        return flask.jsonify(ret)
+
+
+    @inventory_blueprint.route('/item/<int:itemID>',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_item(itemID : int) :
+        return model_manager.ModelObjectToJsonString(inventory.get_inventory_item(itemID))
+
+
+    @inventory_blueprint.route('/site/<int:siteID>',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_site(siteID : int) :
+        return model_manager.ModelObjectToJsonString(inventory.get_inventory_site(siteID))
+
+
+
+    @inventory_blueprint.route('/contact/<int:contactID>',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_contact(contactID : int) :
+        return model_manager.ModelObjectToJsonString(inventory.get_inventory_contact(contactID))
+
+
+    @inventory_blueprint.route('/group/<int:groupID>',methods = ['GET'])
+    @view_privilege.manager.require_authorization(required_role=inventory_read_only_role,get_privilege_func=view.get_user_privilege)
+    def get_group(groupID : int) :
+        return model_manager.ModelObjectToJsonString(inventory.get_inventory_group(groupID))
+
+

+ 11 - 0
Backend/Sources/View/view_error_management.py

@@ -18,5 +18,16 @@ def define_error_management(app) :
     def handle_privilege_error(err) :
         """Return JSON instead of HTML for any other server error"""
         logger.error(f"PrivilegeError Exception: {str(err)}")
+        response = {"authorization error ": str(err) }
+        return jsonify(response), 500
+
+
+    @app.errorhandler(Exception)
+    def handle_privilege_error(err) :
+        """Return JSON instead of HTML for any other server error"""
+        logger.error(f"Exception: {str(err)}")
         response = {"error": str(err) }
         return jsonify(response), 500
+
+
+

+ 35 - 29
Backend/Sources/View/view_manager.py

@@ -55,40 +55,51 @@ def get_user_privilege() :
 
 
 def init() :
+    privileges.init()
+    view_error_management.define_error_management(__app__)
 
-    @__app__.before_request
-    def before_request_func():
 
-        global __id_counter__
-        logger.debug("before_request processing")
-        logger.debug("request from " + request.remote_addr)
-        logger.debug("request header" + str(request.headers.__dict__))
 
-        if request.json :
-            logger.debug("request json body : " + str(request.json))
+@__app__.before_request
+def before_request_func():
 
+    global __id_counter__
+    logger.debug("before_request processing")
+    logger.debug("request from " + request.remote_addr)
+    logger.debug("request header" + str(request.headers.__dict__))
 
-        if not "client_id" in session :
-            session["client_id"] = str(__id_counter__)
-        logger.debug("client_id is " + session["client_id"])
-        __id_counter__ = __id_counter__ + 1
+    if request.json :
+        logger.debug("request json body : " + str(request.json))
 
 
-        if not request.path == "/api/login" and not "username" in session :
-            logger.warning("Unauthorized client with id " + session["client_id"] + " try to access application")
-            resp = jsonify({'message' : 'Unauthorized'})
-            resp.status_code = 401
-            return resp
+    if not "client_id" in session :
+        session["client_id"] = str(__id_counter__)
+    logger.debug("client_id is " + session["client_id"])
+    __id_counter__ = __id_counter__ + 1
 
-        if "username" in session :
-            logger.debug("request from  " + session["username"])
 
+    if not request.path == "/api/login" and not "username" in session :
+        logger.warning("Unauthorized client with id " + session["client_id"] + " try to access application")
+        resp = jsonify({'message' : 'Unauthorized'})
+        resp.status_code = 401
+        return resp
 
+    if "username" in session :
+        logger.debug("request from  " + session["username"])
 
+@__app__.after_request
+def after_request(response):
+    header = response.headers
+
+    # adding this to the header to allow cross origin
+    # for exemple origin cross origin is when website with javascript has it's server (origin 1)
+    # and the javascript call some request on another server (origin 2), typically our API.
+    header['Access-Control-Allow-Origin'] = '*'
+    header['Access-Control-Allow-Methods'] = 'GET,HEAD,OPTIONS,POST,PUT'
+    header['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
+    return response
 
-    privileges.init()
 
-    view_error_management.define_error_management(__app__)
 
 @__app__.route('/api/login',methods = ['POST'])
 def login():
@@ -138,13 +149,7 @@ def routes():
     return jsonify(routes)
 
 
-@__app__.after_request
-def after_request(response):
-    header = response.headers
-    header['Access-Control-Allow-Origin'] = '*'
-    header['Access-Control-Allow-Methods'] = 'GET,HEAD,OPTIONS,POST,PUT'
-    header['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
-    return response
+
 
 
 def run() :
@@ -161,7 +166,8 @@ def stop() :
     logger.info('View server stopped')
 
 
-def add_blueprint(blueprint : flask.Blueprint) :
+def register_blueprint(blueprint : flask.Blueprint) :
+    logger.info("registering view (blueprint) : '" + blueprint.name + "' with prefix '" + blueprint.url_prefix +"'")
     __app__.register_blueprint(blueprint)
 
 @privileges.manager.require_authorization(required_role=inventory_view.inventory_read_only_role,get_privilege_func=get_user_privilege)

+ 4 - 1
Backend/Sources/View/view_privilege.py

@@ -4,7 +4,7 @@ import persistence
 from Model.isp_model import user_account
 
 manager = Privilege_Manager()
-privileges_users : set[ Privilege_Manager.Privilege_User] = set()
+privileges_users : set[Privilege_Manager.Privilege_User] = set()
 
 
 def init() :
@@ -31,6 +31,9 @@ def load_privilege_data() :
                 roles_string.append(manager.get_role_domain(role).name + ' : ' + role.name)
             logger.debug("roles found : " + str(roles_string))
 
+            if privileges.is_super_admin :
+                logger.debug("user is Super Admin !")
+
 
 def get_privileges_from_user(user_id : int) :
     for user in privileges_users :

+ 3 - 1
Backend/Sources/utility/privilege_manager.py

@@ -316,7 +316,7 @@ class Privilege_Manager :
         def wrapper_of_wrap(f) :
             def wrap(*args, **kwargs):
                 if not self.is_role_registered(required_role) :
-                    raise BaseException("role is not registered anywhere")
+                    raise BaseException("required role is not registered anywhere")
                 logger.debug("checking authorization with roles for function " + f.__name__ + ": " )
                 logger.debug("required role :  " + required_role.name )
                 privileges : Privilege_Manager.Privilege_User = get_privilege_func()
@@ -338,6 +338,8 @@ class Privilege_Manager :
                     raise PrivilegeError("Access Denied")
                 return raiser(*args, **kwargs)
 
+            #we change the name of the function, for flash bluerprint, as we cannot register two function with the same name.
+            wrap.__name__ = f.__name__ + "_authorization_wrap"
             return wrap
 
         return wrapper_of_wrap

+ 19 - 0
Backend/create_venv.py

@@ -0,0 +1,19 @@
+import venv
+import pathlib
+import os
+
+import subprocess
+import sys
+
+
+
+
+
+venv.create(env_dir=pathlib.Path().absolute(),with_pip=True)
+
+path = pathlib.Path("requirement.txt")
+
+if path.is_file() :
+    subprocess.check_call([sys.executable, "-m", "pip", "install", "-r","requirement.txt"])
+else :
+    raise ("requirement.txt doesn't exist in script folder !!")

BIN
Backend/requirements.txt


BIN
requirements.txt