Commit 24d0cc0c authored by arun.uday's avatar arun.uday

Merge branch '1-arun-uday-asset-manager-v1-0' into 'master'

1 arun uday asset manager v1 0

See merge request !4
parents a8343237 a0a786d6
......@@ -4,12 +4,25 @@ DB_NAME=userDB
REDIS_URI=redis://127.0.0.1:6379
REDIS_LOGIN_DB=10
SERVICE_HOST=127.0.0.1
SERVICE_HOST=0.0.0.0
SERVICE_PORT=8671
PROJECT_NAME=AssetManager
BASE_PATH=scripts/
SUB_PATH=log/
ENCODING_TYPE=utf-8
KEY_ENCRYPTION=kliLensKLiLensKL
SECRET_KEY=09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
ENCODING_TYPE=utf-8
\ No newline at end of file
EMAIL_SENDER=arun.send.email@gmail.com
EMAIL_SMTP=smtp.gmail.com
EMAIL_PORT=465
EMAIL_PASSWORD=gpphuiweedqukchf
HTML_LINK=scripts/utils/link_email.html
RESET_ENDPOINT=http://localhost:8671/asset_manager_api/v1/login/reset?token
CLIENT_ID=1060631831358-a21djaa3hm165a8976fnmo1lerujs5p6.apps.googleusercontent.com
LOG_PATH=log
LOG_LEVEL=INFO
BACKUP_COUNT=100
MAX_BYTES=5
......@@ -38,5 +38,5 @@ if __name__ == "__main__":
# starting the app
uvicorn.run("main:app", host=arguments["bind"], port=int(arguments["port"]))
except Exception as e:
logger.exception(e)
logger.exception(f'Services Failed with error {e}')
[project_name]
PROJECT_NAME = AssetManager
2023-04-04 20:12:33 - INFO - [MainThread:<module>(): 37] - App Starting at 0.0.0.0:8671
2023-04-04 20:08:30 - INFO - [MainThread:<module>(): 37] - App Starting at 0.0.0.0:8671
2023-04-04 20:07:39 - INFO - [MainThread:<module>(): 37] - App Starting at 0.0.0.0:8671
2023-04-04 20:06:55 - INFO - [MainThread:<module>(): 37] - App Starting at 0.0.0.0:8671
2023-04-04 20:06:23 - INFO - [MainThread:<module>(): 37] - App Starting at 0.0.0.0:8671
2023-04-04 20:06:10 - INFO - [MainThread:<module>(): 37] - App Starting at 0.0.0.0:8671
uvicorn==0.21.1
python-dotenv~=1.0.0
pydantic~=1.10.6
pydantic==1.10.7
fastapi==0.95.0
passlib~=1.7.4
pymongo~=4.3.3
......@@ -9,4 +9,7 @@ email-validator~=1.3.1
pycryptodomex~=3.17
PyJWT~=2.6.0
validate_email~=1.3
redis~=4.5.2
\ No newline at end of file
redis==4.5.4
google~=3.0.0
google-auth~=2.17.1
requests~=2.28.2
\ No newline at end of file
......@@ -14,8 +14,17 @@ class _Services(BaseSettings):
CORS_ALLOW_CREDENTIALS: bool = True
CORS_ALLOW_METHODS: list[str] = ["GET", "POST", "DELETE", "PUT"]
CORS_ALLOW_HEADERS: list[str] = ["*"]
LOG_LEVEL: Literal["INFO", "DEBUG", "ERROR", "QTRACE"] = "INFO"
ENABLE_FILE_LOGGING: bool = False
LOG_LEVEL: str
BACKUP_COUNT: int
MAX_BYTES: int
ENABLE_FILE_LOGGING: bool = True
EMAIL_SENDER: str
EMAIL_SMTP: str
EMAIL_PORT: int
EMAIL_PASSWORD: str
HTML_LINK: str
RESET_ENDPOINT: str
DATE_TIME = '%Y-%m-%d %H:%M:%S'
class _Databases(BaseSettings):
......@@ -25,21 +34,18 @@ class _Databases(BaseSettings):
REDIS_LOGIN_DB: int
class _BasePathConf(BaseSettings):
BASE_PATH: str = "scripts/"
class _PathConf:
BASE_PATH: pathlib.Path = pathlib.Path(_BasePathConf().BASE_PATH)
LOG_PATH: pathlib.Path = BASE_PATH / "log/"
class _PathConf(BaseSettings):
LOG_PATH: str
class _Secrets(BaseSettings):
ACCESS_TOKEN_EXPIRE_MINUTES = 30
ACCESS_TOKEN_EXPIRE_MINUTES = 480
TOKEN_EXPIRE_TIME = 5
leeway_in_minutes: int = 10
KEY_ENCRYPTION = "kliLensKLiLensKL"
KEY_ENCRYPTION: str
CLIENT_ID: str
issuer: str = "iotManager"
SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
SECRET_KEY: str
ALGORITHM = "HS256"
......
class ApiEndPoints:
# Main root
root = "/asset_manager_api"
# version
version = "/v1"
# common
submit: str = "/submit"
add: str = "/add"
view: str = "/view"
add: str = "/adduser"
view: str = "/table_body"
table_actions: str = "/table_actions"
update: str = "/update"
delete: str = "/delete"
header: str = "/table_header"
download: str = "/download"
search: str = "/search"
forgot: str = "/forgot"
reset: str = "/reset"
logout: str = "/logout"
# login-management
asset_manager_login: str = "/login"
asset_manager_submit: str = asset_manager_login + submit
asset_manager_forgot: str = asset_manager_login + forgot
asset_manager_reset: str = asset_manager_login + reset
# user-management
asset_manager_user_management: str = "/users"
asset_manager_user_add: str = asset_manager_user_management + add
asset_manager_user_view: str = asset_manager_user_management + view
asset_manager_user_header: str = asset_manager_user_management + header
asset_manager_user_table_actions: str = asset_manager_user_management + table_actions
asset_manager_user_update: str = asset_manager_user_management + update
asset_manager_user_delete: str = asset_manager_user_management + delete
asset_manager_user_search: str = asset_manager_user_management + search
asset_manager_user_logout: str = asset_manager_user_management + logout
asset_manager_user_reset: str = asset_manager_user_management + reset
# dashboard-management
asset_manager_dashboard: str = "/dashboard"
asset_manager_dashboard_download_header: str = asset_manager_dashboard + download + header
asset_manager_dashboard_download: str = asset_manager_dashboard + download
class Validations:
email = "user@example.com"
from fastapi.responses import JSONResponse
from fastapi import status
from scripts.logging.logger import logger
from scripts.schemas.default_responses import DefaultResponse
from scripts.utils.response_utils import ResponseData
obj_download_util = ResponseData()
# download header and row data
class DashboardManagement:
def __init__(self):
self.download_files = obj_download_util.download_file_data()
def download_header(self):
try:
# header contents
data = {
"actions": [
{
"class": "fa-download",
"action": "download",
"tooltip": "Download"
}
],
"columnDefs": [
{
"headerName": "File Name",
"field": "file_name",
"key": "file_name",
"flex": 0,
"width": 1010
}],
}
# column urls
column_urls = [{"file_name": key, "file_url": value} for key, value in self.download_files.items()]
data["rowData"] = column_urls
return JSONResponse(
content=DefaultResponse(status="success", message="Fetched Successfully",
data=data).dict(),
status_code=status.HTTP_200_OK)
except Exception as e:
logger.exception(e)
This diff is collapsed.
......@@ -19,37 +19,45 @@ class NormalLogin:
self.dt = datetime.now()
self.time_dt = datetime.now()
# user data validation
@staticmethod
def user_data_validation(email, password) -> dict | None:
def user_data_validation(email, password) -> dict | None:
try:
# checking for valid username
if email == "" or validate_email(email) is not True:
return {"message": ErrorMessages.ERROR_INVALID_EMAIL, "data": email}
return ErrorMessages.ERROR_INVALID_EMAIL
# checking for valid password
if password == "":
return {"message": ErrorMessages.ERROR_INVALID_PASSWORD, "data": password}
return ErrorMessages.ERROR_INVALID_PASSWORD
return None
except Exception as e:
logger.exception(e)
# db validation
def db_data_validation(self, login_type, email):
try:
# fetching the data based on the username
self.db_user_data = MongoUser().fetch_one_user_details(email)
self.db_user_data = MongoUser().fetch_one_user_details({"email": email})
# if the user is not available
if not self.db_user_data:
return False, {"message": ErrorMessages.ERROR_UNAUTHORIZED_USER_LOGIN,
"data": {"username": email}}
return False, ErrorMessages.ERROR_ACCOUNT_DOESNT_EXIST
# if the user is not registered through normal login
if self.db_user_data["login_type"] != login_type:
return False, {"message": ErrorMessages.ERROR_LOGIN_TYPE_INVALID,
"data": {"username": email, "Use Login": self.db_user_data["login_type"]}}
return False, ErrorMessages.ERROR_ACCESS_DENIED
try:
response = {"user_id": self.db_user_data["user_id"], "name": self.db_user_data["name"],
"email": email,
"user_role": self.db_user_data["user_role"]}
except KeyError:
response = {"user_id": self.db_user_data["user_id"],
"email": email,
"user_role": self.db_user_data["user_role"]}
# if the user exist
return None, {"message": True}
return None, response
except Exception as e:
logger.exception(e)
# matching the password
def db_password_matching(self, login_type, user_data, password):
try:
# getting the response after checking for the user data in db
......@@ -59,24 +67,31 @@ class NormalLogin:
return response, message
# if the user exists in db then password is matched
if not self.pwd_context.verify(password, self.db_user_data["password"]):
return False, {"message": ErrorMessages.ERROR_PASSWORD_MISMATCH,
"data": {"username": user_data.email}}
return False, ErrorMessages.ERROR_PASSWORD_MISMATCH
# if the password is correct
return None, {"username": user_data.email, "role": self.db_user_data["user_role"]}
return None, message
except Exception as e:
logger.exception(e)
@staticmethod
def update_pic(obj_mongo_user, info_data):
if not obj_mongo_user.update_user({"email": info_data["email"]},
{"name": info_data["name"], "pic_url": info_data["picture"]}):
return None
return True
# cookie and token creation
@staticmethod
def generate_cookie_tokens(user_data, request):
try:
# creating the access token
access_token = create_token(
user_id=user_data.email,
ip=request.ip_address
access_token, exp = create_token(
user_id=user_data["user_id"],
ip=request.client.host
)
# returning the login token
if access_token:
return {"user_id": access_token, "token_type": "bearer"}
return access_token, exp
else:
return None
except Exception as e:
......
......@@ -6,6 +6,7 @@ collection_name = DatabaseConstants.collection_user_details
class UserDetailsKeys:
KEY_USER_ID = "user_id"
KEY_NAME = "name"
KEY_EMAIL = "email"
KEY_PASSWORD = "password"
......@@ -17,6 +18,7 @@ class UserDetailsKeys:
class MongoUser(CollectionBaseClass):
key_name = UserDetailsKeys.KEY_NAME
key_user_id = UserDetailsKeys.KEY_USER_ID
key_email = UserDetailsKeys.KEY_EMAIL
key_password = UserDetailsKeys.KEY_PASSWORD
key_user_role = UserDetailsKeys.KEY_USER_ROLE
......@@ -28,28 +30,37 @@ class MongoUser(CollectionBaseClass):
super().__init__(mongo_client, Databases.DB_NAME, collection_name)
# fetching the user details based on the email id
def fetch_one_user_details(self, email):
if user := self.find_one(query={self.key_email: email}):
def fetch_one_user_details(self, query):
if user := self.find_one(query=query):
return user
return None
def fetch_all_user_details(self):
if user := self.find(query={}, filter_dict={'_id': 0,
"login_type": 0,
"is_alive": 0,
"password": 0,
"created_at": 0,
"updated_at": 0}):
# fetching the user data
def fetch_all_user_details(self, query, filter_data):
if user := self.find(query=query, filter_dict=filter_data):
return user
return None
# inserting the user
def insert_new_user(self, data):
if user := self.insert_one(data=data):
return user
return None
# updating the login time
def update_user(self, update, query):
if user := self.update_one(query=update, data=query):
def update_user(self, query, update):
if user := self.update_one(query=query, data=update):
return user
return None
# deleting users
def delete_user(self, query):
if user := self.delete_one(query=query):
return user
return None
# for filtering
def filter_data_aggregate(self, pipeline):
if user := self.aggregate(pipelines=pipeline):
return user
return None
......@@ -4,14 +4,20 @@ class ErrorMessages:
# Authorization Errors
ERROR_AUTH_FAILED = "Authentication Failed. Please verify token"
ERROR_INVALID_LOGIN = "Your are not authorized to view this website."
ERROR_ACCOUNT_DOESNT_EXIST = "Account Does Not Exist"
ERROR_UNAUTHORIZED_USER_LOGIN = "Account is not available"
ERROR_UNAUTHORIZED_ACCESS = "Your are not authorized to view this page"
ERROR_LOGIN_TYPE_INVALID = "Invalid Login Method"
ERROR_ACCESS_DENIED = "Access Denied!"
ERROR_USER_NOT_REGISTERED = "Account is not registered in the portal."
ERROR_PASSWORD_MISMATCH = "Passwords Authentication Failed. Please enter the correct password"
ERROR_PASSWORD_MISMATCH = "Please enter the correct password"
ERROR_TOKEN_GENERATION = "Unsuccessful token generation"
ERROR_STORING_DATA = "New user registration failed"
ERROR_EMAIL_EXIST = "Email Id exists"
ERROR_IN_FETCHING = "Details cannot be fetched"
ERROR_IN_UPDATING = "Error in Updating"
ERROR_INVALID_REQUEST = "Invalid Request"
ERROR_USER_SESSION = "Not The Users Session"
ERROR_TOKEN_EXPIRED = "Google Token Expired"
# Data Validation
ERROR_INVALID_PASSWORD = "Invalid Password"
......@@ -19,3 +25,6 @@ class ErrorMessages:
ERROR_INVALID_EMAIL = "Invalid Email Id"
ERROR_INVALID_PHONE_NUMBER = "Invalid Phone Number"
ERROR_INVALID_USER_ROLE = "Invalid User Role"
ERROR_USER_ID_DOESNT_EXIST = "User Id doesn't exist"
ERROR_USER_ID = "User Id Not Required"
ERROR_INVALID_TOKEN = "Invalid Token"
This source diff could not be displayed because it is too large. You can view the blob instead.
import logging
import os
from logging.handlers import RotatingFileHandler
import pathlib
from logging import StreamHandler
from logging.handlers import RotatingFileHandler, SocketHandler
from scripts.config import Services, PathConf
def get_logger():
"""
Creates a rotating log
"""
__logger__ = logging.getLogger('')
def read_configuration():
return {
"name": Services.PROJECT_NAME,
"handlers": [
{"type": "RotatingFileHandler", "max_bytes": Services.MAX_BYTES, "back_up_count": Services.BACKUP_COUNT},
{"type": "StreamHandler", "name": Services.PROJECT_NAME},
],
}
def init_logger():
logging_config = read_configuration()
# setting the logger level
"""
Creates a rotating log
"""
__logger__ = logging.getLogger(Services.PROJECT_NAME)
__logger__.setLevel(Services.LOG_LEVEL)
# creating the format for the log
log_formatter = "%(asctime)s - %(levelname)-6s - [%(threadName)5s:%(funcName)5s(): %(lineno)s] - %(message)s"
time_format = "%Y-%m-%d %H:%M:%S"
# getting the path for the logger
file_path = PathConf.LOG_PATH
# setting the format
formatter = logging.Formatter(log_formatter, time_format)
# creating the folder if not exist
if not os.path.exists(file_path):
os.makedirs(file_path)
# joining the path
log_file = os.path.join(f"{file_path}/{Services.PROJECT_NAME}log.log")
# creating rotating file handler with max byte as 1
temp_handler = RotatingFileHandler(log_file, maxBytes=1)
# setting the formatter
temp_handler.setFormatter(formatter)
# setting the handler
__logger__.addHandler(temp_handler)
for each_handler in logging_config["handlers"]:
if (
each_handler["type"] in ["RotatingFileHandler"]
and Services.ENABLE_FILE_LOGGING
):
pathlib.Path(PathConf.LOG_PATH).mkdir(parents=True, exist_ok=True)
log_file = pathlib.Path(PathConf.LOG_PATH, f"{Services.PROJECT_NAME}.log")
temp_handler = RotatingFileHandler(
log_file,
maxBytes=each_handler["max_bytes"],
backupCount=each_handler["back_up_count"],
)
temp_handler.setFormatter(formatter)
elif each_handler["type"] in ["SocketHandler"]:
temp_handler = SocketHandler(each_handler["host"], each_handler["port"])
elif each_handler["type"] in ["StreamHandler"]:
temp_handler = StreamHandler()
temp_handler.setFormatter(formatter)
else:
temp_handler = None
__logger__.addHandler(temp_handler)
return __logger__
logger = get_logger()
logger = init_logger()
......@@ -5,12 +5,17 @@ from pydantic import BaseModel
# default responses
class DefaultResponse(BaseModel):
status: bool = True
message: Optional[str]
status: str
message: str
data: Optional[Any]
class DefaultSuccessResponse(BaseModel):
status: str
message: str
# default failure responses
class DefaultFailureResponse(DefaultResponse):
status: bool = False
error: Any
class DefaultFailureResponse(BaseModel):
status: str
message: Any
......@@ -5,8 +5,10 @@ from pydantic import BaseModel
# model for login request
class LoginRequest(BaseModel):
email: str
password: str
login_type: str
email: Optional[str] = None
password: Optional[str] = None
id_token: Optional[str] = None
class RegistrationData(BaseModel):
......@@ -16,3 +18,34 @@ class RegistrationData(BaseModel):
phone_number: Optional[str]
login_type: str
user_role: str
class UserActions(BaseModel):
action: str
user_id: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
password: Optional[str]
phone_number: Optional[str] = None
login_type: Optional[str] = None
user_role: Optional[str] = None
class UsersFilter(BaseModel):
name: Optional[str] = None
email: Optional[str] = None
user_role: Optional[str] = None
class ResetPassword(BaseModel):
user_id: str
old_password: Optional[str] = None
new_password: str
class UserIDValidation(BaseModel):
user_id: str
class EmailValidation(BaseModel):
email: str
from fastapi import APIRouter
from scripts.constants.api import ApiEndPoints
from scripts.services import v1
router = APIRouter()
router = APIRouter(prefix=ApiEndPoints.root)
# routing to the V1 router
router.include_router(v1.router)
......@@ -3,6 +3,6 @@ from scripts.constants.api import ApiEndPoints
from scripts.services.v1 import iot_manager_services
# creating the api router with version as the prefix
router = APIRouter()
router = APIRouter(prefix=ApiEndPoints.version)
# routing to the service api
router.include_router(iot_manager_services.router)
This diff is collapsed.
This diff is collapsed.
......@@ -57,3 +57,6 @@ class MongoStageCreator:
def sort_stage(self, stage: dict) -> dict:
return self.add_stage("$sort", stage)
def regex_stage(self, stage: dict) -> dict:
return self.add_stage("$regex", stage)
......@@ -3,15 +3,8 @@ import re
from scripts.logging.logger import logger
# for data validations
class RegexValidation:
@staticmethod
def first_name_validation(first_name):
try:
regex = re.fullmatch('([A-Za-z ]{1,100})', str(first_name))
return regex
except Exception as e:
logger.error(f'An Error While listing the home plans {str(e)}')
@staticmethod
def name_validation(name):
try:
......@@ -29,10 +22,11 @@ class RegexValidation:
logger.error(f'An Error While listing the home plans {str(e)}')
@staticmethod
def email_validation(email):
def password_validation(password):
try:
regex = r'\b[A-Za-z0-9._%+-]+@([A-Za-z0-9.-]{5,20})+\.[A-Z|a-z]{3}\b'
if re.fullmatch(regex, email):
return regex
password_regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+={}[\]:;\"\'|,.<>\/?]).{8,15}$'
if re.search(password_regex, password):
return False
except Exception as e:
logger.error(f'An Error While listing the home plans {str(e)}')
\ No newline at end of file
logger.error(f'An Error While listing the home plans {str(e)}')
# response data utils
class ResponseData:
@staticmethod
def user_view_header():
header = {
"actions": [
{
"class": "fa-pencil",
"action": "edit",
"tooltip": "Edit"
},
{
"class": "fa-trash",
"action": "delete",
"tooltip": "Delete"
},
], "externalActions": [
{
"type": "button",
"action": "addnew",
"label": "Create User"
}
], "columnDefs": [
{
"headerName": "User Name",
"field": "email",
"key": "email"
},
{
"headerName": "Name",
"field": "name",
"key": "name"
},
{
"headerName": "Role",
"field": "user_role",
"key": "user_role",
"width": 150,
"flex": 0
}
],
}
return header
# download api util
@staticmethod
def download_file_data():
data = {
"SCN101-Manual (Local Config with IoTSetupUI)":
"https://ilens.io/DownloadFiles/SCN_Device_Configuration_Page_Updates_4_7.pdf",
"SCN101 Firmware 4.7 Updates":
"https://ilens.io/DownloadFiles/SCN101Manual.pdf",
"IoTSetupUI":
"https://ilens.io/DownloadFiles/IoTsetupUI-V1.6.zip",
"CP2102 SCN Windows USB Driver":
"https://ilens.io/DownloadFiles/CP2102_Windows.zip",
"SCNFirmwareBurner":
"https://ilens.io/DownloadFiles/flash_download_tool_v3.8.5.zip",
"SCN101A Firmware - V2.7 (Board: 1.4, 1.6 and 4MB Part.) ":
"https://ilens.io/DownloadFiles/SCN101_Firmware_V2_7_B1_6.bin",
"SCN101A Firmware - V2.8 (Board: 1.4, 1.6 and 4MB Part.) ":
"https://ilens.io/DownloadFiles/SCN101_Firmware_V2_8_B1_6.bin",
"SCN101A4G (SCN Relay, 4G, SCN201 and SCN101L) Firmware - V4.5 (16MB Part.) ":
"https://ilens.io/DownloadFiles/SCN101_R_A4G_SCN201_Firmware_V4_5.bin",
"SCN101A4G (SCN Relay, 4G, SCN201 and SCN101L) Firmware - V4.6 (16MB Part.) ":
"https://ilens.io/DownloadFiles/SCN101_R_A4G_SCN201_Firmware_V4_6.bin",
"SCN101A4G (SCN Relay, 4G, SCN201 and SCN101L) Firmware - V4.7 (16MB Part.) ":
"https://ilens.io/DownloadFiles/SCN101_R_A4G_SCN201_Firmware_V4_7.bin",
"P10_LED_Driver_V2.1 (Board 1.1)":
"https://ilens.io/DownloadFiles/P10_LED_Driver_V2.1.bin",
"SCN-LED Reset Firmware (Board 1.1)":
"https://ilens.io/DownloadFiles/SCN-LED_Reset.bin",
"SCN Reset Firmware (Partition: 4MB)":
"https://ilens.io/DownloadFiles/SCN_Reset_4MB_Part.bin",
"SCN Reset Firmware (Partition: 16MB)":
"https://ilens.io/DownloadFiles/SCN_Reset_16MB_Part.bin"
}
return data
from datetime import datetime, timedelta
import uuid
from datetime import datetime, timedelta, timezone
from scripts.config import Secrets
from scripts.database.mongo.mongo_db import MongoUser
......@@ -12,15 +13,19 @@ mongo_user = MongoUser()
def create_token(
user_id,
ip,
login_token=None,
age=Secrets.ACCESS_TOKEN_EXPIRE_MINUTES,
):
"""
This method is to create a cookie
"""
uid = login_token
if not uid:
uid = str(uuid.uuid4()).replace("-", "")
# creating the payload
payload = {"ip": ip, "user_id": user_id, "token": Secrets.SECRET_KEY, "age": age}
payload = {"ip": ip, "user_id": user_id, "token": Secrets.SECRET_KEY, "uid": uid, "age": age}
# getting the current time
current_time = datetime.now()
current_time = datetime.now(timezone.utc)
# generating the expiry time of the token
exp = current_time + timedelta(minutes=age)
# creating the dictionary with issuer and expiry time
......@@ -28,12 +33,9 @@ def create_token(
_payload = payload | _extras
# encoding the token
new_token = jwt.encode(_payload)
# Add session to redis
login_db.set(user_id, new_token)
login_db.expire(user_id, timedelta(minutes=age))
login_db.set(uid, new_token)
login_db.expire(uid, timedelta(minutes=age))
# Add updated time to mongo db
mongo_user.update_user({"email": user_id}, {"updated_at": current_time})
return user_id
mongo_user.update_user({"user_id": user_id}, {"updated_at": current_time})
return uid, exp
from typing import Optional
from scripts.database.mongo.mongo_db import MongoUser
from scripts.schemas.project_schema import ResetPassword
obj_mongo_user = MongoUser()
class AuthorizeAccess:
@staticmethod
# authorize the user
def admin_authorize(request):
user_data = obj_mongo_user.fetch_one_user_details(request.login_token)
if user_data["user_role"] != "super admin":
try:
# returning the user details
user_data = obj_mongo_user.fetch_one_user_details({"user_id": request.user_id})
if user_data["user_role"] != "super_admin":
return False
return True
except TypeError:
return False
return True
@staticmethod
def login_authorize(request, reset_data: Optional[ResetPassword] = None):
if reset_data is not None:
if reset_data.user_id != request.user_id:
return False
return True
if request.user_id:
return True
return False
......@@ -4,7 +4,6 @@ from fastapi.security import APIKeyCookie
from fastapi.security.api_key import APIKeyBase
from pydantic import BaseModel, Field
from scripts.config import Services
from scripts.database.redis.redis_conn import login_db
from scripts.errors import ErrorMessages
from scripts.logging.logger import logger
......@@ -50,16 +49,8 @@ class _CookieAuthentication(APIKeyBase):
login_token = cookies.get(self.cookie_name) or request.headers.get(
self.cookie_name
)
if not login_token or login_token != Services.PROJECT_NAME:
if not login_token:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
# if the cookie name is same as the service name
if login_token == Services.PROJECT_NAME:
return MetaInfoSchema(
ip_address=request.client.host, # type: ignore
login_token=cookies.get("login-token"),
)
# getting the token stored in redis based on the cookie value
if not login_token:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
jwt_token = self.login_redis.get(login_token)
if not jwt_token:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
......@@ -83,7 +74,6 @@ class _CookieAuthentication(APIKeyBase):
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token doesn't have required fields",
)
return MetaInfoSchema(
user_id=user_id,
ip_address=request.client.host, # type: ignore
......
......@@ -6,6 +6,7 @@ from scripts.config import Secrets, Services
from scripts.logging.logger import logger
# utility for the password
class EncryptDecryptPassword:
def __init__(self):
self.pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
......@@ -37,7 +38,12 @@ class EncryptDecryptPassword:
except Exception as e:
logger.exception(e)
# encrypting the password
def password_encrypt(self, password):
# decrypting the UI password
decrypted_password = self.password_decrypt(password)
hashed_password = self.pwd_context.hash(decrypted_password)
# hashing the decrypted password
if decrypted_password is None:
return None
hashed_password = self.pwd_context.hash(decrypted_password.split("\"")[1])
return hashed_password
......@@ -6,9 +6,10 @@ from scripts.errors import ErrorMessages
from scripts.logging.logger import logger
# user data validations
class UserDataValidations:
@staticmethod
def data_validation(user_data, method, feature):
def register_data_validation(user_data, method, feature):
try:
if user_data.name == "":
return False, {"message": ErrorMessages.ERROR_INVALID_NAME,
......@@ -18,14 +19,27 @@ class UserDataValidations:
user_data.email) is not True:
return False, {"message": ErrorMessages.ERROR_INVALID_EMAIL, "data": user_data.email}
# checking for valid password
if method == 'normal':
if method == 'general':
if user_data.password == "" or user_data.password == "string":
return False, {"message": ErrorMessages.ERROR_INVALID_PASSWORD, "data": user_data.password}
# Validate phone number
if user_data.phone_number == "":
return False, {"message": ErrorMessages.ERROR_INVALID_PHONE_NUMBER,
"data": user_data.phone_number}
if user_data.user_role == "" and method == 'normal' and feature == 'register':
if user_data.user_role == "" and method == 'general' and feature == 'register':
return False, {"message": ErrorMessages.ERROR_INVALID_USER_ROLE,
"data": user_data.phone_number}
return True, None
except Exception as e:
logger.exception(e)
@staticmethod
def update_data_validation(user_data):
try:
if user_data.name == "":
return False, {"message": ErrorMessages.ERROR_INVALID_NAME,
"data": user_data.phone_number}
if user_data.user_role == "":
return False, {"message": ErrorMessages.ERROR_INVALID_USER_ROLE,
"data": user_data.phone_number}
return True, None
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment