1+ import logging
2+ import secrets
3+
14from django .contrib import messages
5+ from django .core .exceptions import ObjectDoesNotExist , ValidationError
6+ from django .db import IntegrityError
27from django .http import JsonResponse
38from django .shortcuts import get_object_or_404 , redirect , reverse
9+ from django .urls import reverse_lazy
410from django .utils .translation import gettext_lazy as _
511from django .views import View
6- from django .views .generic import FormView , TemplateView
12+ from django .views .generic import DeleteView , FormView , TemplateView
713
14+ from pretix .api .models import OAuthApplication
815from pretix .base .models import LogEntry , OrderPayment , OrderRefund
916from pretix .base .services .update_check import check_result_table , update_check
1017from pretix .base .settings import GlobalSettingsObject
1118from pretix .control .forms .global_settings import (
12- GlobalSettingsForm , UpdateSettingsForm ,
19+ GlobalSettingsForm , SSOConfigForm , UpdateSettingsForm ,
1320)
1421from pretix .control .permissions import (
1522 AdministratorPermissionRequiredMixin , StaffMemberRequiredMixin ,
1623)
1724
25+ logger = logging .getLogger (__name__ )
26+
1827
1928class GlobalSettingsView (AdministratorPermissionRequiredMixin , FormView ):
2029 template_name = 'pretixcontrol/global_settings.html'
@@ -26,13 +35,77 @@ def form_valid(self, form):
2635 return super ().form_valid (form )
2736
2837 def form_invalid (self , form ):
29- messages .error (self .request , _ ('Your changes have not been saved, see below for errors.' ))
38+ messages .error (
39+ self .request , _ ('Your changes have not been saved, see below for errors.' )
40+ )
3041 return super ().form_invalid (form )
3142
3243 def get_success_url (self ):
3344 return reverse ('control:admin.global.settings' )
3445
3546
47+ class SSOView (AdministratorPermissionRequiredMixin , FormView ):
48+ template_name = 'pretixcontrol/global_sso.html'
49+ form_class = SSOConfigForm
50+
51+ def get_context_data (self , ** kwargs ):
52+ context = super ().get_context_data (** kwargs )
53+ oauth_applications = OAuthApplication .objects .all ()
54+ context ['oauth_applications' ] = oauth_applications
55+ return context
56+
57+ def form_valid (self , form ):
58+ url = form .cleaned_data ['redirect_url' ]
59+
60+ try :
61+ result = self .create_oauth_application (url )
62+ except (IntegrityError , ValidationError , ObjectDoesNotExist ) as e :
63+ error_type = type (e ).__name__
64+ logger .error ('Error while creating OAuth2 application: %s - %s' , error_type , e )
65+ return self .render_to_response ({'error_message' : f'{ error_type } : { e } ' })
66+
67+ return self .render_to_response (self .get_context_data (form = form , result = result ))
68+
69+ def form_invalid (self , form ):
70+ messages .error (
71+ self .request , _ ('Your changes have not been saved, see below for errors.' )
72+ )
73+ return super ().form_invalid (form )
74+
75+ def get_success_url (self ):
76+ return reverse ('control:admin.global.sso' )
77+
78+ def create_oauth_application (self , redirect_uris ):
79+ application , created = OAuthApplication .objects .get_or_create (
80+ redirect_uris = redirect_uris ,
81+ defaults = {
82+ 'name' : "Talk SSO Client" ,
83+ 'client_type' : OAuthApplication .CLIENT_CONFIDENTIAL ,
84+ 'authorization_grant_type' : OAuthApplication .GRANT_AUTHORIZATION_CODE ,
85+ 'user' : None ,
86+ 'client_id' : secrets .token_urlsafe (32 ),
87+ 'client_secret' : secrets .token_urlsafe (64 ),
88+ 'hash_client_secret' : False ,
89+ 'skip_authorization' : True ,
90+ },
91+ )
92+
93+ return {
94+ "success_message" : (
95+ "Successfully created OAuth2 Application"
96+ if created
97+ else "OAuth2 Application with this redirect URI already exists"
98+ ),
99+ "client_id" : application .client_id ,
100+ "client_secret" : application .client_secret ,
101+ }
102+
103+
104+ class DeleteOAuthApplicationView (AdministratorPermissionRequiredMixin , DeleteView ):
105+ model = OAuthApplication
106+ success_url = reverse_lazy ('control:admin.global.sso' )
107+
108+
36109class UpdateCheckView (StaffMemberRequiredMixin , FormView ):
37110 template_name = 'pretixcontrol/global_update.html'
38111 form_class = UpdateSettingsForm
@@ -49,7 +122,9 @@ def form_valid(self, form):
49122 return super ().form_valid (form )
50123
51124 def form_invalid (self , form ):
52- messages .error (self .request , _ ('Your changes have not been saved, see below for errors.' ))
125+ messages .error (
126+ self .request , _ ('Your changes have not been saved, see below for errors.' )
127+ )
53128 return super ().form_invalid (form )
54129
55130 def get_context_data (self , ** kwargs ):
0 commit comments