Exemple #1
0
 def __init__(self, opts=None) -> None:
     super(CreateSwagger, self).__init__(opts)
     sys.path = ["", ".."] + sys.path[1:]
     self.info = {"openapi": "3.0.0"}
     url_patterns = get_settings_variable("URL_PATTERNS")
     swagger_info = get_settings_variable("SWAGGER")
     if not swagger_info:
         raise CraxImproperlyConfigured(
             "'SWAGGER' variable should"
             " be defined in configuration file to use Swagger")
     elif swagger_info.servers is None or swagger_info.basePath is None:
         raise CraxImproperlyConfigured(
             "'SWAGGER_HOST' and 'SWAGGER_BASE_PATH' should"
             " be defined in configuration file to use Swagger")
     self.base_path = swagger_info.basePath
     self.swagger_file = f"{BASE_URL}/crax/swagger/static/swagger.json"
     info = {
         k: v
         for k, v in swagger_info.__dict__.items()
         if k not in ["host", "basePath", "schemes"]
     }
     self.info["info"] = info
     self.info["host"] = swagger_info.host
     self.info["basePath"] = swagger_info.basePath
     self.info["servers"] = swagger_info.servers
     self.info["tags"] = []
     self.url_list = list(unpack_urls(url_patterns))
Exemple #2
0
async def login(request: Request, username: str,
                password: str) -> typing.Union[User, AnonymousUser]:
    secret = get_settings_variable("SECRET_KEY")
    signer = itsdangerous.TimestampSigner(str(secret))
    max_age = get_settings_variable("SESSION_EXPIRES", default=1209600)
    cookie_name = get_settings_variable("SESSION_COOKIE_NAME",
                                        default="session_id")

    if not secret:
        raise CraxImproperlyConfigured(
            '"SECRET_KEY" variable should be defined to use Authentication backends'
        )
    if hasattr(request, "cookies"):
        cookies = request.cookies
        if cookie_name in cookies:
            session_cookie = cookies[cookie_name]
            session_cookie = b64decode(session_cookie)
            user = signer.unsign(session_cookie, max_age=max_age)
            user = user.decode("utf-8")
            await set_user(request,
                           username,
                           password,
                           user_pk=int(user.split(":")[1]))
        else:
            await set_user(request, username, password)
    return request.user
Exemple #3
0
def create_password(password: str) -> str:
    secret = get_settings_variable("SECRET_KEY")
    if not secret:
        raise CraxImproperlyConfigured(
            '"SECRET_KEY" variable should be defined to use Authentication backends'
        )
    secret = secret.encode()
    hashed = hashlib.pbkdf2_hmac("sha256", password.encode(), secret, 100000)
    return hashed.hex()
Exemple #4
0
def check_password(hashed: str, password: str) -> bool:
    secret = get_settings_variable("SECRET_KEY")
    if not secret:
        raise CraxImproperlyConfigured(
            '"SECRET_KEY" variable should be defined to use Authentication backends'
        )
    secret = secret.encode()
    return hmac.compare_digest(
        bytearray.fromhex(hashed),
        hashlib.pbkdf2_hmac("sha256", password.encode(), secret, 100000),
    )
Exemple #5
0
def csrf_token():
    secret_key = get_settings_variable("SECRET_KEY")
    if secret_key is None:
        raise CraxImproperlyConfigured(
            '"SECRET_KEY" string should be defined in settings to use CSRF Protection'
        )

    signer = itsdangerous.TimestampSigner(str(secret_key))
    sign = signer.sign(str(int(time.time())))
    encoded = b64encode(sign)
    csrf_key = encoded.decode("utf-8")
    return csrf_key
Exemple #6
0
def create_session_signer() -> tuple:
    secret_key = get_settings_variable("SECRET_KEY")
    if secret_key is None:
        raise CraxImproperlyConfigured(
            '"SECRET_KEY" string should be defined in settings to use Crax Sessions'
        )
    signer = itsdangerous.TimestampSigner(
        str(secret_key), algorithm=itsdangerous.signer.HMACAlgorithm())
    max_age = get_settings_variable("SESSION_EXPIRES", default=1209600)
    cookie_name = get_settings_variable("SESSION_COOKIE_NAME",
                                        default="session_id")
    same_site = get_settings_variable("SAME_SITE_COOKIE_MODE", default="lax")
    return signer, max_age, cookie_name, same_site
Exemple #7
0
 def get_match(self, request: Request) -> Optional[typing.Callable]:
     scheme = request.scheme
     handler = None
     matched = False
     params = {}
     for url in self.urls:
         if isinstance(url, Url):
             find_path, path = self.create_path(url, request.path)
             if url.type_ == "re_path":
                 match = re.match(find_path, path)
                 if match:
                     params = match.groupdict()
                     matched = True
             else:
                 matched, params = self.check_len(url, path)
             if matched is True and scheme in url.scheme:
                 handler = self.handler
                 request.params = params
                 if url.masquerade is True:
                     if hasattr(handler, "scope"):
                         masqueraded = [
                             x for x in handler.scope
                             if x == request.path.split("/")[-1]
                         ]
                         if not masqueraded:
                             handler = DefaultError(
                                 request, CraxPathNotFound(request.path))
                         else:
                             handler.template = masqueraded[0]
                     else:
                         handler = DefaultError(
                             request, CraxPathNotFound(request.path))
         else:
             handler = DefaultError(
                 request,
                 CraxImproperlyConfigured(
                     f'{url} should be instance of "Url"'),
             )
     return handler
Exemple #8
0
    def check_allowed(self, handler: typing.Callable):
        errors = None
        if self.request.user is not None:
            if hasattr(handler, "login_required"):
                login_required = handler.login_required
                if (
                    hasattr(self.request.user, "pk")
                    and self.request.user.pk == 0
                    and login_required is True
                ):
                    errors = {
                        "error_handler": CraxUnauthorized,
                        "error_message": self.request.path,
                        "status_code": 401,
                    }

            if hasattr(handler, "staff_only"):
                staff_only = handler.staff_only
                if self.request.user.is_staff is False and staff_only is True:
                    errors = {
                        "error_handler": CraxForbidden,
                        "error_message": self.request.path,
                        "status_code": 403,
                    }

            if hasattr(handler, "superuser_only"):
                superuser_only = handler.superuser_only
                if self.request.user.is_superuser is False and superuser_only is True:
                    errors = {
                        "error_handler": CraxForbidden,
                        "error_message": self.request.path,
                        "status_code": 403,
                    }
        if hasattr(handler, "methods") and self.request.scheme in [
            "http",
            "http.request",
        ]:
            if self.enable_csrf is True and self.request.method in ["POST", "PATCH"]:
                if hasattr(handler, "enable_csrf") and handler.enable_csrf is True:
                    if "csrf_token" not in self.request.post:
                        errors = {
                            "error_handler": CraxForbidden,
                            "error_message": "CSRF token missed",
                            "status_code": 403,
                        }
                    elif not self.request.post["csrf_token"]:
                        errors = {
                            "error_handler": CraxForbidden,
                            "error_message": "CSRF token is empty",
                            "status_code": 403,
                        }
                    else:
                        secret_key = get_settings_variable("SECRET_KEY")
                        if secret_key is None:
                            raise CraxImproperlyConfigured(
                                '"SECRET_KEY" string should be defined in settings to use CSRF Protection'
                            )
                        try:
                            token = self.request.post["csrf_token"]
                            signer = itsdangerous.TimestampSigner(str(secret_key))
                            max_age = get_settings_variable(
                                "SESSION_EXPIRES", default=1209600
                            )
                            session_cookie = b64decode(token)
                            signer.unsign(session_cookie, max_age=max_age)
                        except (
                            binascii.Error,
                            BadTimeSignature,
                            BadSignature,
                            SignatureExpired,
                        ):
                            errors = {
                                "error_handler": CraxForbidden,
                                "error_message": "CSRF token is incorrect",
                                "status_code": 403,
                            }
            if not self.request.method:  # pragma: no cover
                errors = {
                    "error_handler": CraxNoMethodGiven,
                    "error_message": handler,
                    "status_code": 500,
                }

            elif not handler.methods:
                errors = {
                    "error_handler": CraxEmptyMethods,
                    "error_message": handler,
                    "status_code": 500,
                }
            else:
                handler.methods += ["HEAD", "OPTIONS"]
                if self.request.method not in handler.methods:
                    errors = {
                        "error_handler": CraxMethodNotAllowed,
                        "error_message": handler,
                        "status_code": 405,
                    }
        return errors
Exemple #9
0
    def __init__(self, opts: typing.List[typing.Union[tuple]],
                 **kwargs) -> None:
        super(DataBaseCommands, self).__init__(opts)
        self.kwargs = kwargs
        self.db_map = {}
        self.db_keys = {}
        self.db_tables = []
        self.sorted_tables = []
        settings = os.environ.get("CRAX_SETTINGS", None)
        self.configuration = get_settings(settings=settings)
        required_params = ["BASE_URL", "APPLICATIONS", "DATABASES"]
        for x in required_params:
            if not hasattr(self.configuration, x):
                raise CraxImproperlyConfigured(
                    f"Missed required parameter {x}")
        self.project_applications = self.configuration.APPLICATIONS

        self.project_url = self.configuration.BASE_URL

        self.databases = self.configuration.DATABASES
        if not isinstance(self.databases, dict):
            raise CraxImproperlyConfigured(
                "DATABASES parameter should be a dict")

        elif settings is not None and "default" not in self.databases:
            raise CraxImproperlyConfigured(
                'DATABASES dictionary should contain "default" database')

        self.default_connection = None
        self.db_name = None

        self.config_file = "alembic.ini"
        self.alembic_dir = "alembic_env"
        self.migrations_dir = "migrations"

        db = self.get_option("database")
        if db is None:
            self.set_database("default")
        else:
            self.set_database(db)

        if hasattr(self.configuration, "MIDDLEWARE"):
            middleware = self.configuration.MIDDLEWARE
            check_auth = [
                x for x in middleware
                if x.split(".")[-1] == "SessionMiddleware"
                or x.split(".")[-1] == "AuthMiddleware"
            ]
            if len(check_auth) == 2 and self.db_name == "default":
                self.project_applications.append("crax.auth")
        apps = self.get_option("apps")
        self.applications = []

        if apps:
            applications = [
                x for x in self.project_applications
                if x in apps or x == "crax.auth"
            ]
        else:
            applications = self.project_applications

        for app in applications:
            if app != "crax.auth":
                if "models.py" in os.listdir(f'{self.project_url}/{app}'):
                    content = open(f'{self.project_url}/{app}/models.py',
                                   "r").read()
                    if content:
                        self.applications.append(app)
            else:
                self.applications.append(app)
        if self.db_name != "default" and "crax.auth" in self.applications:
            self.applications.remove("crax.auth")

        self.config = self.check_config()

        if self.config is not None:
            self.config.set_main_option(
                "version_locations",
                " ".join([
                    self.create_version_dir(app)
                    for app in self.project_applications
                ]),
            )

        os.environ["CRAX_DB_CONNECTION"] = self.default_connection
        os.environ["CRAX_FULL_METADATA"] = " ".join(self.project_applications)