diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d4147ca --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +# Makefile for cleaning packaging files and directories + +.PHONY: clean-package clean-build clean + +# Clean distribution artifacts (dist/ and *.egg-info) +clean-package: + rm -rf dist + rm -rf *.egg-info + rm -rf src/*.egg-info + +# Clean all Python build artifacts (dist, egg-info, pyc, and cache files) +clean-build: clean-package + find . -name "__pycache__" -type d -exec rm -rf {} + + find . -name "*.pyc" -exec rm -f {} + + find . -name "*.pyo" -exec rm -f {} + + +# Alias to clean everything +clean: clean-build \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index e0dc16d..ed9ea87 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "myauth" -version = "0.2.0" # Start with an initial version +version = "0.3.0" description = "A reusable, modular authentication system for FastAPI applications with pluggable database backends." readme = "README.md" authors = [ @@ -78,6 +78,9 @@ dev = [ # Setuptools configuration # This section tells the build system where to find your package code # ------------------------------------------------------------------- -[tool.setuptools] -package-dir = {"" = "src"} -packages = ["my_auth"] \ No newline at end of file +#[tool.setuptools] +#package-dir = {"myauth" = "src"} +#packages = ["my_auth"] + +[tool.setuptools.package-dir] +myauth = "src/myauth" \ No newline at end of file diff --git a/src/my_auth/api/__init__.py b/src/my_auth/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/my_auth/core/__init__.py b/src/my_auth/core/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/my_auth/email/__init__.py b/src/my_auth/email/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/my_auth/models/__init__.py b/src/my_auth/models/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/my_auth/persistence/__init__.py b/src/my_auth/persistence/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/myauth/__init__.py b/src/myauth/__init__.py new file mode 100644 index 0000000..d7c98f9 --- /dev/null +++ b/src/myauth/__init__.py @@ -0,0 +1,6 @@ +from .factory import create_sqlite_auth_service, create_app_router_for_sqlite + +__all__ = [ + 'create_sqlite_auth_service', + 'create_app_router_for_sqlite', +] diff --git a/src/myauth/api/__init__.py b/src/myauth/api/__init__.py new file mode 100644 index 0000000..17d4842 --- /dev/null +++ b/src/myauth/api/__init__.py @@ -0,0 +1,3 @@ +from .routes import create_auth_router + +__all__ = ["create_auth_router"] \ No newline at end of file diff --git a/src/my_auth/api/routes.py b/src/myauth/api/routes.py similarity index 100% rename from src/my_auth/api/routes.py rename to src/myauth/api/routes.py diff --git a/src/myauth/core/__init__.py b/src/myauth/core/__init__.py new file mode 100644 index 0000000..a397d03 --- /dev/null +++ b/src/myauth/core/__init__.py @@ -0,0 +1,5 @@ +from .auth import AuthService +from .password import PasswordManager +from .token import TokenManager + +__all__ = ["AuthService", "PasswordManager", "TokenManager"] diff --git a/src/my_auth/core/auth.py b/src/myauth/core/auth.py similarity index 97% rename from src/my_auth/core/auth.py rename to src/myauth/core/auth.py index 48fe85a..c311e10 100644 --- a/src/my_auth/core/auth.py +++ b/src/myauth/core/auth.py @@ -14,7 +14,7 @@ from .token import TokenManager from ..persistence.base import UserRepository, TokenRepository from ..models.user import UserCreate, UserInDB, UserUpdate from ..models.token import AccessTokenResponse, TokenData -from ..email.base import EmailService +from ..emailing.base import EmailService from ..exceptions import ( InvalidCredentialsError, UserNotFoundError, diff --git a/src/my_auth/core/password.py b/src/myauth/core/password.py similarity index 100% rename from src/my_auth/core/password.py rename to src/myauth/core/password.py diff --git a/src/my_auth/core/token.py b/src/myauth/core/token.py similarity index 100% rename from src/my_auth/core/token.py rename to src/myauth/core/token.py diff --git a/src/myauth/emailing/__init__.py b/src/myauth/emailing/__init__.py new file mode 100644 index 0000000..ecce53e --- /dev/null +++ b/src/myauth/emailing/__init__.py @@ -0,0 +1,4 @@ +from .base import EmailService +from .smtp import SMTPEmailService + +__all__ = ["EmailService", "SMTPEmailService"] diff --git a/src/my_auth/email/base.py b/src/myauth/emailing/base.py similarity index 100% rename from src/my_auth/email/base.py rename to src/myauth/emailing/base.py diff --git a/src/my_auth/email/smtp.py b/src/myauth/emailing/smtp.py similarity index 100% rename from src/my_auth/email/smtp.py rename to src/myauth/emailing/smtp.py diff --git a/src/my_auth/exceptions.py b/src/myauth/exceptions.py similarity index 100% rename from src/my_auth/exceptions.py rename to src/myauth/exceptions.py diff --git a/src/myauth/factory.py b/src/myauth/factory.py new file mode 100644 index 0000000..b14955a --- /dev/null +++ b/src/myauth/factory.py @@ -0,0 +1,79 @@ +from typing import Optional + +from .core import AuthService +from .core.password import PasswordManager +from .core.token import TokenManager +from .emailing.base import EmailService + + +def create_sqlite_auth_service(db_path: str, + jwt_secret: str, + email_service: Optional[EmailService], + password_manager: PasswordManager = None, + token_manager: TokenManager = None, + ): + """ + Creates and configures an authentication service using SQLite as the underlying + data store. + + This function is responsible for setting up the necessary repositories + and managers required for the AuthService. It uses SQLite repositories + for user and token data and initializes the required managers for password + and token processing, as well as an optional email service. + + :param db_path: Path to the SQLite database file used to persist authentication + data. + :type db_path: str + :param jwt_secret: Secret key used to encode and decode JSON Web Tokens (JWTs). + :type jwt_secret: str + :param email_service: Optional email service instance for managing email-based + communication. + :type email_service: Optional[EmailService] + :param password_manager: Optional custom PasswordManager instance responsible for + password-related operations. Defaults to a new instance. + :type password_manager: PasswordManager + :param token_manager: Optional custom TokenManager instance responsible for token + generation and verification. Defaults to a new instance + configured with `jwt_secret`. + :type token_manager: TokenManager + :return: A fully configured instance of AuthService with the specified + repositories and managers. + :rtype: AuthService + """ + from my_auth.persistence.sqlite import SQLiteUserRepository + from my_auth.persistence.sqlite import SQLiteTokenRepository + user_repository = SQLiteUserRepository(db_path) + token_repository = SQLiteTokenRepository(db_path) + password_manager = password_manager or PasswordManager() + token_manager = token_manager or TokenManager(jwt_secret) + + auth_service = AuthService( + user_repository=user_repository, + token_repository=token_repository, + password_manager=password_manager, + token_manager=token_manager, + email_service=email_service) + + return auth_service + + +def create_app_router_for_sqlite(db_path: str, + jwt_secret: str, + email_service: Optional[EmailService] = None): + """ + Creates an application router designed to use with an SQLite database backend. + This function initializes an authentication service using the provided database + path and JWT secret, optionally integrating an email service for email-based + authentication functionalities. The authentication service is then used to + create an application router for handling authentication-related API routes. + + :param db_path: Path to the SQLite database file. + :param jwt_secret: A secret string used for signing and verifying JWT tokens. + :param email_service: An optional email service instance for managing email-related + communication and functionalities during authentication. + :return: An application router configured for handling authentication API routes. + """ + auth_service = create_sqlite_auth_service( + db_path, jwt_secret, email_service) + from my_auth.api.routes import create_auth_router + return create_auth_router(auth_service) diff --git a/src/my_auth/__init__.py b/src/myauth/models/__init__.py similarity index 100% rename from src/my_auth/__init__.py rename to src/myauth/models/__init__.py diff --git a/src/my_auth/models/email_verification.py b/src/myauth/models/email_verification.py similarity index 93% rename from src/my_auth/models/email_verification.py rename to src/myauth/models/email_verification.py index 07290f5..2642101 100644 --- a/src/my_auth/models/email_verification.py +++ b/src/myauth/models/email_verification.py @@ -7,7 +7,7 @@ reset operations including request and confirmation models. from pydantic import BaseModel, EmailStr, field_validator -from my_auth.models.validators import validate_password_strength +from ..models.validators import validate_password_strength class EmailVerificationRequest(BaseModel): diff --git a/src/my_auth/models/token.py b/src/myauth/models/token.py similarity index 100% rename from src/my_auth/models/token.py rename to src/myauth/models/token.py diff --git a/src/my_auth/models/user.py b/src/myauth/models/user.py similarity index 94% rename from src/my_auth/models/user.py rename to src/myauth/models/user.py index c6a40a3..ea05f79 100644 --- a/src/my_auth/models/user.py +++ b/src/myauth/models/user.py @@ -10,7 +10,7 @@ from typing import Optional from pydantic import BaseModel, EmailStr, Field, field_validator -from my_auth.models.validators import validate_password_strength, validate_username_not_empty +from ..models.validators import validate_password_strength, validate_username_not_empty class UserBase(BaseModel): diff --git a/src/my_auth/models/validators.py b/src/myauth/models/validators.py similarity index 100% rename from src/my_auth/models/validators.py rename to src/myauth/models/validators.py diff --git a/src/myauth/persistence/__init__.py b/src/myauth/persistence/__init__.py new file mode 100644 index 0000000..ca45ce9 --- /dev/null +++ b/src/myauth/persistence/__init__.py @@ -0,0 +1,6 @@ +from .sqlite import UserRepository, TokenRepository + +__all__ = [ + "UserRepository", + "TokenRepository", +] diff --git a/src/my_auth/persistence/base.py b/src/myauth/persistence/base.py similarity index 100% rename from src/my_auth/persistence/base.py rename to src/myauth/persistence/base.py diff --git a/src/my_auth/persistence/sqlite.py b/src/myauth/persistence/sqlite.py similarity index 100% rename from src/my_auth/persistence/sqlite.py rename to src/myauth/persistence/sqlite.py