codekingpro/portable-devtools
114k
1##########################################################################2#3# pgAdmin 4 - PostgreSQL Tools4#5# Copyright (C) 2013 - 2024, The pgAdmin Development Team6# This software is released under the PostgreSQL Licence7#8##########################################################################9 10"""External 2FA Authentication Registry."""11from abc import abstractmethod, abstractproperty12from typing import Union13 14import flask15 16from pgadmin.utils.dynamic_registry import create_registry_metaclass17 18 19"""20class: MultiFactorAuthRegistry21 22An registry factory for the multi-factor authentication methods.23"""24 25 26@classmethod27def load_modules(cls, app=None):28 submodules = []29 from . import authenticator as module30 submodules.append(module)31 32 from . import email as module33 submodules.append(module)34 35 from . import utils as module36 submodules.append(module)37 38 from . import views as module39 submodules.append(module)40 41 for module in submodules:42 if "init_app" in module.__dict__.keys():43 module.__dict__["init_app"](app)44 45 46MultiFactorAuthRegistry = create_registry_metaclass(47 'MultiFactorAuthRegistry', __package__, load_modules=load_modules,48 decorate_as_module=True49)50 51 52class BaseMFAuth(metaclass=MultiFactorAuthRegistry):53 """54 Base Multi-Factor Authentication (MFA) class55 56 A Class implements this class will be registered with57 the registry class 'MultiFactorAuthRegistry', and it will be automatically58 available as a MFA method.59 """60 61 @property62 @abstractmethod63 def name(self) -> str:64 """65 Represents the short name for the authentiation method. It can be used66 in the MFA_SUPPORTED_METHODS parameter in the configuration as a67 supported authentication method.68 69 Returns:70 str: Short name for this authentication method71 72 NOTE: Name must not contain special characters73 """74 pass75 76 @property77 @abstractmethod78 def label(self) -> str:79 """80 Represents the user visible name for the authentiation method. It will81 be visible on the authentication page and registration page.82 83 Returns:84 str: Value for the UI for the authentication method85 """86 pass87 88 @property89 def icon(self) -> str:90 """91 A url for the icon for the authentication method.92 93 Returns:94 str: Value for the UI for the authentication method95 """96 return ""97 98 @property99 def validate_script(self) -> Union[str, None]:100 """101 A url route for the javscript required for the auth method.102 103 Override this method for the auth methods, when it required a104 javascript on the authentication page.105 106 Returns:107 Union[str, None]: Url for the auth method or None108 """109 return None110 111 @abstractmethod112 def validate(self, **kwargs) -> str:113 """114 Validate the code/password sent using the HTTP request during the115 authentication process.116 117 If the validation is not done successfully for some reason, it must118 raise a ValidationException exception.119 120 Parameters:121 kwargs: data sent during the authentication process122 123 Raises:124 ValidationException: Raises when code/otp is not valid125 """126 pass127 128 @abstractmethod129 def validation_view(self) -> str:130 """131 Authenction route (view) for the auth method.132 """133 pass134 135 @abstractmethod136 def registration_view(self, form_data) -> str:137 """138 Registration View for the auth method.139 140 Must override this for rendering the registration page for the auth141 method.142 143 Args:144 form_data (dict): Form data sent from the registration page.145 """146 pass147 148 def register_url_endpoints(self, blueprint: flask.Blueprint) -> None:149 """150 Register the URL end-points for the auth method (special case).151 152 Args:153 blueprint (flask.Blueprint): MFA blueprint for registering the154 end-point for the method155 156 157 NOTE: Override this method only when there is special need to expose158 an url end-point for the auth method.159 """160 pass161 162 def to_dict(self) -> dict:163 """164 A diction representation for the auth method.165 166 Returns:167 dict (id, label, icon): Diction representation for an auth method.168 """169 return {170 "id": self.name,171 "label": self.label,172 "icon": self.icon,173 }174 175 def validation_view_dict(self, selected_mfa: str) -> dict:176 """177 A diction representation for the auth method to be used on the178 registration page.179 180 Returns:181 dict: Diction representation for an auth method to be used on the182 regisration page.183 """184 res = self.to_dict()185 186 res['view'] = self.validation_view()187 res['selected'] = selected_mfa == self.name188 res['script'] = self.validate_script189 190 return res191 