# Generated by Django 3.1 on 2020-08-18 15:59 import django.db.models.deletion from django.apps.registry import Apps from django.conf import settings from django.db import migrations, models from django.db.backends.base.schema import BaseDatabaseSchemaEditor import passbook.core.models import passbook.lib.utils.time import passbook.providers.oauth2.generators SCOPE_OPENID_EXPRESSION = """# This is only required for OpenID Applications, but does not grant any information by itself. return {} """ SCOPE_EMAIL_EXPRESSION = """return { "email": user.email, "email_verified": True } """ SCOPE_PROFILE_EXPRESSION = """return { "name": user.name, "given_name": user.name, "family_name": "", "preferred_username": user.username, "nickname": user.username, } """ def create_default_scopes(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): ScopeMapping = apps.get_model("passbook_providers_oauth2", "ScopeMapping") ScopeMapping.objects.update_or_create( scope_name="openid", defaults={ "name": "Autogenerated OAuth2 Mapping: OpenID 'openid'", "scope_name": "openid", "description": "", "expression": SCOPE_OPENID_EXPRESSION, }, ) ScopeMapping.objects.update_or_create( scope_name="email", defaults={ "name": "Autogenerated OAuth2 Mapping: OpenID 'email'", "scope_name": "email", "description": "Email address", "expression": SCOPE_EMAIL_EXPRESSION, }, ) ScopeMapping.objects.update_or_create( scope_name="profile", defaults={ "name": "Autogenerated OAuth2 Mapping: OpenID 'profile'", "scope_name": "profile", "description": "General Profile Information", "expression": SCOPE_PROFILE_EXPRESSION, }, ) class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("passbook_core", "0007_auto_20200815_1841"), ("passbook_crypto", "0002_create_self_signed_kp"), ] operations = [ migrations.RunSQL( "DROP TABLE IF EXISTS passbook_providers_oauth_oauth2provider CASCADE;" ), migrations.RunSQL( "DROP TABLE IF EXISTS passbook_providers_oidc_openidprovider CASCADE;" ), migrations.CreateModel( name="OAuth2Provider", fields=[ ( "provider_ptr", models.OneToOneField( auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to="passbook_core.provider", ), ), ("name", models.TextField()), ( "client_type", models.CharField( choices=[ ("confidential", "Confidential"), ("public", "Public"), ], default="confidential", help_text="Confidential clients are capable of maintaining the confidentiality\n of their credentials. Public clients are incapable.", max_length=30, verbose_name="Client Type", ), ), ( "client_id", models.CharField( default=passbook.providers.oauth2.generators.generate_client_id, max_length=255, unique=True, verbose_name="Client ID", ), ), ( "client_secret", models.CharField( blank=True, default=passbook.providers.oauth2.generators.generate_client_secret, max_length=255, verbose_name="Client Secret", ), ), ( "response_type", models.TextField( choices=[ ("code", "code (Authorization Code Flow)"), ("id_token", "id_token (Implicit Flow)"), ("id_token token", "id_token token (Implicit Flow)"), ("code token", "code token (Hybrid Flow)"), ("code id_token", "code id_token (Hybrid Flow)"), ( "code id_token token", "code id_token token (Hybrid Flow)", ), ], default="code", help_text="Response Type required by the client.", ), ), ( "jwt_alg", models.CharField( choices=[ ("HS256", "HS256 (Symmetric Encryption)"), ("RS256", "RS256 (Asymmetric Encryption)"), ], default="RS256", help_text="Algorithm used to sign the JWT Token", max_length=10, verbose_name="JWT Algorithm", ), ), ( "redirect_uris", models.TextField( default="", help_text="Enter each URI on a new line.", verbose_name="Redirect URIs", ), ), ( "post_logout_redirect_uris", models.TextField( blank=True, default="", help_text="Enter each URI on a new line.", verbose_name="Post Logout Redirect URIs", ), ), ( "include_claims_in_id_token", models.BooleanField( default=True, help_text="Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint.", verbose_name="Include claims in id_token", ), ), ( "token_validity", models.TextField( default="minutes=10", help_text="Tokens not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).", validators=[passbook.lib.utils.time.timedelta_string_validator], ), ), ( "rsa_key", models.ForeignKey( help_text="Key used to sign the tokens. Only required when JWT Algorithm is set to RS256.", on_delete=django.db.models.deletion.CASCADE, to="passbook_crypto.certificatekeypair", verbose_name="RSA Key", blank=True, null=True, ), ), ], options={ "verbose_name": "OAuth2/OpenID Provider", "verbose_name_plural": "OAuth2/OpenID Providers", }, bases=("passbook_core.provider",), ), migrations.CreateModel( name="ScopeMapping", fields=[ ( "propertymapping_ptr", models.OneToOneField( auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to="passbook_core.propertymapping", ), ), ("scope_name", models.TextField(help_text="Scope used by the client")), ( "description", models.TextField( blank=True, help_text="Description shown to the user when consenting. If left empty, the user won't be informed.", ), ), ], options={ "verbose_name": "Scope Mapping", "verbose_name_plural": "Scope Mappings", }, bases=("passbook_core.propertymapping",), ), migrations.RunPython(create_default_scopes), migrations.CreateModel( name="RefreshToken", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "expires", models.DateTimeField( default=passbook.core.models.default_token_duration ), ), ("expiring", models.BooleanField(default=True)), ("_scope", models.TextField(default="", verbose_name="Scopes")), ( "access_token", models.CharField( max_length=255, unique=True, verbose_name="Access Token" ), ), ( "refresh_token", models.CharField( max_length=255, unique=True, verbose_name="Refresh Token" ), ), ("_id_token", models.TextField(verbose_name="ID Token")), ( "provider", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to="passbook_providers_oauth2.oauth2provider", ), ), ( "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name="User", ), ), ], options={ "verbose_name": "Token", "verbose_name_plural": "Tokens", }, ), migrations.CreateModel( name="AuthorizationCode", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "expires", models.DateTimeField( default=passbook.core.models.default_token_duration ), ), ("expiring", models.BooleanField(default=True)), ("_scope", models.TextField(default="", verbose_name="Scopes")), ( "code", models.CharField(max_length=255, unique=True, verbose_name="Code"), ), ( "nonce", models.CharField( blank=True, default="", max_length=255, verbose_name="Nonce" ), ), ( "is_open_id", models.BooleanField( default=False, verbose_name="Is Authentication?" ), ), ( "code_challenge", models.CharField( max_length=255, null=True, verbose_name="Code Challenge" ), ), ( "code_challenge_method", models.CharField( max_length=255, null=True, verbose_name="Code Challenge Method" ), ), ( "provider", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to="passbook_providers_oauth2.oauth2provider", ), ), ( "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name="User", ), ), ], options={ "verbose_name": "Authorization Code", "verbose_name_plural": "Authorization Codes", }, ), ]