1
1
import os
2
2
import re
3
3
from django .db import migrations
4
+ from django .db .models import Q
5
+
4
6
5
- """
6
- Add any OIDC providers from the environment variables to the database. The upgrade to
7
- [email protected] removed code from /settings/base.py that parsed OIDC settings from
8
- environment variables, so this migration is needed to avoid manually setting up OIDC
9
- providers from the admin. Adapted from:
10
- https://gitlab.com/glitchtip/glitchtip-backend/-/blob/master/users/migrations/0010_allauth_oidc_from_env_var.py?ref_type=heads
11
- """
12
7
def add_OIDC_settings_from_env (apps , schema_editor ):
8
+ """
9
+ Add any OIDC providers from the environment variables to the database. The upgrade to
10
+ [email protected] removed code from /settings/base.py that parsed OIDC settings from
11
+ environment variables, so this migration is needed to avoid manually setting up OIDC
12
+ providers from the admin. Adapted from:
13
+ https://gitlab.com/glitchtip/glitchtip-backend/-/blob/master/users/migrations/0010_allauth_oidc_from_env_var.py?ref_type=heads
14
+ """
13
15
SocialApp = apps .get_model ('socialaccount' , 'SocialApp' )
14
16
SocialAppCustomData = apps .get_model ('accounts' , 'SocialAppCustomData' )
15
17
@@ -31,24 +33,36 @@ def add_OIDC_settings_from_env(apps, schema_editor):
31
33
32
34
for index , app in enumerate (oidc_apps ):
33
35
app_id = app .get ('id' )
36
+
34
37
# the app needs a name to be editable in the admin - give it a default name if necessary
35
38
app_name = app .get ('name' , f'OIDC { index } ' )
36
39
app_settings = {'server_url' : app .get ('server_url' , None )}
40
+
37
41
# parse the tenant variable for microsoft OIDC providers - check for uppercase (old way) and lowercase (new way)
38
42
if app_tenant := app .get ('TENANT' , app .get ('tenant' , None )):
39
43
app_settings ['tenant' ] = app_tenant
40
- if app_id and app_settings ['server_url' ] and not (
41
- # if the app already exists, let's assume it's been configured
42
- SocialApp .objects .filter (provider_id = app_id ).exists ()
43
- ):
44
- db_social_app , created = SocialApp .objects .get_or_create (provider_id = app_id )
45
- db_social_app .provider = 'openid_connect'
46
- db_social_app .name = app_name
47
- db_social_app .client_id = app .get ('APP_client_id' , '' )
48
- db_social_app .secret = app .get ('APP_secret' , '' )
49
- db_social_app .key = app .get ('APP_key' , '' )
44
+
45
+ if app_id and app_settings ['server_url' ]:
46
+ db_social_app = SocialApp .objects .filter (
47
+ Q (provider = app_id ) |
48
+ Q (provider__iexact = 'openid_connect' , provider_id = app_id ) |
49
+ Q (provider = '' , name__iexact = app_name )
50
+ ).first ()
51
+ if not db_social_app :
52
+ db_social_app = SocialApp .objects .create ()
50
53
db_social_app .settings = app_settings
54
+ if not db_social_app .settings .get ('previous_provider' ):
55
+ db_social_app .settings ['previous_provider' ] = app_id
56
+ db_social_app .provider = 'openid_connect'
57
+ db_social_app .provider_id = app_id
58
+ # we don't want to overwrite the following settings if they're already defined
59
+ # on the social app we grabbed
60
+ db_social_app .name = db_social_app .name or app_name
61
+ db_social_app .client_id = db_social_app .client_id or app .get ('APP_client_id' , '' )
62
+ db_social_app .secret = db_social_app .secret or app .get ('APP_secret' , '' )
63
+ db_social_app .key = db_social_app .key or app .get ('APP_key' , '' )
51
64
db_social_app .save ()
65
+
52
66
# hide the OIDC provider from the login page, since it was already hidden
53
67
SocialAppCustomData .objects .get_or_create (social_app = db_social_app )
54
68
@@ -65,14 +79,24 @@ def add_OIDC_settings_from_env(apps, schema_editor):
65
79
ms_app .save ()
66
80
67
81
82
+ def revert_OIDC_provider_id (apps , schema_editor ):
83
+ SocialApp = apps .get_model ('socialaccount' , 'SocialApp' )
84
+
85
+ changed_apps = SocialApp .objects .filter (settings__has_key = 'previous_provider' )
86
+ for app in list (changed_apps ):
87
+ app .provider = app .settings ['previous_provider' ]
88
+ app .save ()
89
+
90
+
68
91
class Migration (migrations .Migration ):
69
92
dependencies = [
70
93
('socialaccount' , '0005_socialtoken_nullable_app' ),
71
- ('accounts' , '0005_do_nothing ' ),
94
+ ('accounts' , '0006_alter_emailcontent_unique_together ' ),
72
95
]
73
96
74
97
operations = [
75
98
migrations .RunPython (
76
- code = add_OIDC_settings_from_env , reverse_code = migrations .RunPython .noop
99
+ code = add_OIDC_settings_from_env ,
100
+ reverse_code = revert_OIDC_provider_id ,
77
101
)
78
102
]
0 commit comments