2023-03-12 16:00:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GoToSocial  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Copyright (C) GoToSocial Authors admin@gotosocial.org  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SPDX-License-Identifier: AGPL-3.0-or-later  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.  
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  auth  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/gin-contrib/sessions" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/gin-gonic/gin" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/google/uuid" 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-02 13:10:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									apiutil  "github.com/superseriousbusiness/gotosocial/internal/api/util" 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/config" 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/db" 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtserror" 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 13:49:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/oauth" 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/oidc" 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 18:29:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/validate" 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// extraInfo wraps a form-submitted username and transmitted name  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  extraInfo  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Username  string  ` form:"username" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Name      string  ` form:"name" `  // note that this is only used for re-rendering the page in case of an error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// CallbackGETHandler parses a token from an external auth provider.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( m  * Module )  CallbackGETHandler ( c  * gin . Context )  {  
						 
					
						
							
								
									
										
										
										
											2023-01-02 13:10:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! config . GetOIDCEnabled ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  errors . New ( "oidc is not enabled for this server" ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorNotFound ( err ,  err . Error ( ) ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-02 13:10:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									s  :=  sessions . Default ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check the query vs session state parameter to mitigate csrf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// https://auth0.com/docs/secure/attack-protection/state-parameters 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 16:43:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									returnedInternalState  :=  c . Query ( callbackStateParam ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  returnedInternalState  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "%s parameter not found on callback query" ,  callbackStateParam ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  err . Error ( ) ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 16:43:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									savedInternalStateI  :=  s . Get ( sessionInternalState ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									savedInternalState ,  ok  :=  savedInternalStateI . ( string ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 16:43:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "key %s was not found in session" ,  sessionInternalState ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  err . Error ( ) ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 16:43:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  returnedInternalState  !=  savedInternalState  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-28 16:43:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  errors . New ( "mismatch between callback state and saved state" ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorUnauthorized ( err ,  err . Error ( ) ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// retrieve stored claims using code 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									code  :=  c . Query ( callbackCodeParam ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  code  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "%s parameter not found on callback query" ,  callbackCodeParam ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  err . Error ( ) ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  errWithCode  :=  m . idp . HandleCallback ( c . Request . Context ( ) ,  code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  errWithCode  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  errWithCode ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// We can use the client_id on the session to retrieve 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// info about the app associated with the client_id 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									clientID ,  ok  :=  s . Get ( sessionClientID ) . ( string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  ||  clientID  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "key %s was not found in session" ,  sessionClientID ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  oauth . HelpfulAdvice ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-26 19:56:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									app  :=  & gtsmodel . Application { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  m . db . GetWhere ( c . Request . Context ( ) ,  [ ] db . Where { { Key :  sessionClientID ,  Value :  clientID } } ,  app ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										safe  :=  fmt . Sprintf ( "application for %s %s could not be retrieved" ,  sessionClientID ,  clientID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  errWithCode  gtserror . WithCode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  db . ErrNoEntries  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 13:49:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											errWithCode  =  gtserror . NewErrorBadRequest ( err ,  safe ,  oauth . HelpfulAdvice ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 13:49:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											errWithCode  =  gtserror . NewErrorInternalError ( err ,  safe ,  oauth . HelpfulAdvice ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  errWithCode ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									user ,  errWithCode  :=  m . fetchUserForClaims ( c . Request . Context ( ) ,  claims ,  net . IP ( c . ClientIP ( ) ) ,  app . ID ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  errWithCode  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  errWithCode ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  user  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// no user exists yet - let's ask them for their preferred username 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										instance ,  errWithCode  :=  m . processor . InstanceGetV1 ( c . Request . Context ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  errWithCode  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											apiutil . ErrorHandler ( c ,  errWithCode ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// store the claims in the session - that way we know the user is authenticated when processing the form later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . Set ( sessionClaims ,  claims ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . Set ( sessionAppID ,  app . ID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  s . Save ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											apiutil . ErrorHandler ( c ,  gtserror . NewErrorInternalError ( err ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . HTML ( http . StatusOK ,  "finalize.tmpl" ,  gin . H { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"instance" :           instance , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"name" :               claims . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"preferredUsername" :  claims . PreferredUsername , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									s . Set ( sessionUserID ,  user . ID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  s . Save ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorInternalError ( err ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-02 13:10:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . Redirect ( http . StatusFound ,  "/oauth" + OauthAuthorizePath ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// FinalizePOSTHandler registers the user after additional data has been provided  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( m  * Module )  FinalizePOSTHandler ( c  * gin . Context )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  sessions . Default ( c ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									form  :=  & extraInfo { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  c . ShouldBind ( form ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  oauth . HelpfulAdvice ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since we have multiple possible validation error, `validationError` is a shorthand for rendering them 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									validationError  :=  func ( err  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										instance ,  errWithCode  :=  m . processor . InstanceGetV1 ( c . Request . Context ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  errWithCode  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											apiutil . ErrorHandler ( c ,  errWithCode ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . HTML ( http . StatusOK ,  "finalize.tmpl" ,  gin . H { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"instance" :           instance , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"name" :               form . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"preferredUsername" :  form . Username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"error" :              err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if the username conforms to the spec 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  validate . Username ( form . Username ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										validationError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// see if the username is still available 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									usernameAvailable ,  err  :=  m . db . IsUsernameAvailable ( c . Request . Context ( ) ,  form . Username ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  oauth . HelpfulAdvice ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! usernameAvailable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										validationError ( fmt . Errorf ( "Username %s is already taken" ,  form . Username ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// retrieve the information previously set by the oidc logic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									appID ,  ok  :=  s . Get ( sessionAppID ) . ( string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "key %s was not found in session" ,  sessionAppID ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  oauth . HelpfulAdvice ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// retrieve the claims returned by the IDP. Having this present means that we previously already verified these claims 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									claims ,  ok  :=  s . Get ( sessionClaims ) . ( * oidc . Claims ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "key %s was not found in session" ,  sessionClaims ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorBadRequest ( err ,  oauth . HelpfulAdvice ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// we're now ready to actually create the user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									user ,  errWithCode  :=  m . createUserFromOIDC ( c . Request . Context ( ) ,  claims ,  form ,  net . IP ( c . ClientIP ( ) ) ,  appID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  errWithCode  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  errWithCode ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . Delete ( sessionClaims ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . Delete ( sessionAppID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . Set ( sessionUserID ,  user . ID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  s . Save ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . clearSession ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-02 14:08:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiutil . ErrorHandler ( c ,  gtserror . NewErrorInternalError ( err ) ,  m . processor . InstanceGetV1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-02 13:10:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . Redirect ( http . StatusFound ,  "/oauth" + OauthAuthorizePath ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( m  * Module )  fetchUserForClaims ( ctx  context . Context ,  claims  * oidc . Claims ,  ip  net . IP ,  appID  string )  ( * gtsmodel . User ,  gtserror . WithCode )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  claims . Sub  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  errors . New ( "no sub claim found - is your provider OIDC compliant?" ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  gtserror . NewErrorBadRequest ( err ,  err . Error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									user ,  err  :=  m . db . GetUserByExternalID ( ctx ,  claims . Sub ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  user ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-20 12:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  db . ErrNoEntries  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "error checking database for externalID %s: %s" ,  claims . Sub ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  gtserror . NewErrorInternalError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! config . GetOIDCLinkExisting ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// fallback to email if we want to link existing users 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									user ,  err  =  m . db . GetUserByEmailAddress ( ctx ,  claims . Email ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  db . ErrNoEntries  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "error checking database for email %s: %s" ,  claims . Email ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  gtserror . NewErrorInternalError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// at this point we have found a matching user but still need to link the newly received external ID 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									user . ExternalID  =  claims . Sub 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  m . db . UpdateUser ( ctx ,  user ,  "external_id" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  fmt . Errorf ( "error linking existing user %s: %s" ,  claims . Email ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  gtserror . NewErrorInternalError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  user ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( m  * Module )  createUserFromOIDC ( ctx  context . Context ,  claims  * oidc . Claims ,  extraInfo  * extraInfo ,  ip  net . IP ,  appID  string )  ( * gtsmodel . User ,  gtserror . WithCode )  {  
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// check if the email address is available for use; if it's not there's nothing we can so 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									emailAvailable ,  err  :=  m . db . IsEmailAvailable ( ctx ,  claims . Email ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  gtserror . NewErrorBadRequest ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! emailAvailable  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										help  :=  "The email address given to us by your authentication provider already exists in our records and the server administrator has not enabled account migration" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  gtserror . NewErrorConflict ( fmt . Errorf ( "email address %s is not available" ,  claims . Email ) ,  help ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if the user is in any recognised admin groups 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 17:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									adminGroups  :=  config . GetOIDCAdminGroups ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  admin  bool 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 17:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								LOOP :  
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  _ ,  g  :=  range  claims . Groups  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 17:37:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  ag  :=  range  adminGroups  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  strings . EqualFold ( g ,  ag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												admin  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break  LOOP 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-31 16:03:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// We still need to set *a* password even if it's not a password the user will end up using, so set something random. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We'll just set two uuids on top of each other, which should be long + random enough to baffle any attempts to crack. 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-31 16:03:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If the user ever wants to log in using gts password rather than oidc flow, they'll have to request a password reset, which is fine 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									password  :=  uuid . NewString ( )  +  uuid . NewString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-31 16:03:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Since this user is created via oidc, which has been set up by the admin, we can assume that the account is already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// implicitly approved, and that the email address has already been verified: otherwise, we end up in situations where 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the admin first approves the user in OIDC, and then has to approve them again in GoToSocial, which doesn't make sense. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// In other words, if a user logs in via OIDC, they should be able to use their account straight away. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// See: https://github.com/superseriousbusiness/gotosocial/issues/357 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requireApproval  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									emailVerified  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// create the user! this will also create an account and store it in the database so we don't need to do that here 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 14:15:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									user ,  err  :=  m . db . NewSignup ( ctx ,  extraInfo . Username ,  "" ,  requireApproval ,  claims . Email ,  password ,  ip ,  "" ,  appID ,  emailVerified ,  claims . Sub ,  admin ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-08 20:38:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  gtserror . NewErrorInternalError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 10:36:28 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  user ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}