@@ -4,8 +4,10 @@ import (
44	"crypto/rand" 
55	"encoding/hex" 
66	"encoding/json" 
7+ 	"io" 
78	"log/slog" 
89	"net/http" 
10+ 	"sync" 
911	"time" 
1012
1113	"github.com/ory/fosite" 
@@ -29,6 +31,7 @@ type OAuthHandler struct {
2931	KCManager       * kc.Manager 
3032	Logger          * slog.Logger 
3133	AppConfig       AppConfig 
34+ 	clientRegMutex  sync.Mutex 
3235}
3336
3437// AppConfig holds configuration required by the OAuth handlers. 
@@ -51,6 +54,29 @@ func NewOAuthHandler(provider fosite.OAuth2Provider, store *oauth.InMemoryStore,
5154// Authorize is the handler for the /authorize endpoint. 
5255func  (h  * OAuthHandler ) Authorize (w  http.ResponseWriter , r  * http.Request ) {
5356	ctx  :=  r .Context ()
57+ 	clientID  :=  r .URL .Query ().Get ("client_id" )
58+ 	redirectURI  :=  r .URL .Query ().Get ("redirect_uri" )
59+ 
60+ 	if  clientID  ==  ""  ||  redirectURI  ==  ""  {
61+ 		http .Error (w , "Missing required parameters" , http .StatusBadRequest )
62+ 		return 
63+ 	}
64+ 
65+ 	// Auto-register client if not found 
66+ 	h .clientRegMutex .Lock ()
67+ 	defer  h .clientRegMutex .Unlock ()
68+ 	if  _ , err  :=  h .FositeStore .GetClient (ctx , clientID ); err  !=  nil  {
69+ 		autoClient  :=  & fosite.DefaultClient {
70+ 			ID :           clientID ,
71+ 			Public :       true ,
72+ 			RedirectURIs : []string {redirectURI },
73+ 			GrantTypes :   fosite.Arguments {"authorization_code" , "refresh_token" },
74+ 			Scopes :       fosite.Arguments {"default" , "openid" },
75+ 		}
76+ 		h .FositeStore .AddClient (autoClient )
77+ 	}
78+ 
79+ 	// Process authorization request 
5480	ar , err  :=  h .FositeProvider .NewAuthorizeRequest (ctx , r )
5581	if  err  !=  nil  {
5682		h .FositeProvider .WriteAuthorizeError (ctx , w , ar , err )
@@ -181,48 +207,34 @@ func (h *OAuthHandler) Callback(w http.ResponseWriter, r *http.Request) {
181207
182208// Register is the handler for the /register endpoint. 
183209func  (h  * OAuthHandler ) Register (w  http.ResponseWriter , r  * http.Request ) {
184- 	client  :=  & fosite.DefaultClient {
185- 		GrantTypes :    fosite.Arguments {"authorization_code" , "refresh_token" , "client_credentials" },
186- 		ResponseTypes : fosite.Arguments {"code" , "id_token" },
187- 		Scopes :        fosite.Arguments {"openid" , "offline" },
188- 	}
189- 
190- 	decoder  :=  json .NewDecoder (r .Body )
191- 	var  registrationRequest  struct  {
210+ 	body , _  :=  io .ReadAll (r .Body )
211+ 	var  req  struct  {
192212		ClientName    string    `json:"client_name"` 
193213		RedirectURIs  []string  `json:"redirect_uris"` 
194- 		GrantTypes    []string  `json:"grant_types"` 
195- 	}
196- 	if  err  :=  decoder .Decode (& registrationRequest ); err  !=  nil  {
197- 		http .Error (w , "Invalid request body" , http .StatusBadRequest )
198- 		return 
199- 	}
200- 
201- 	client .ID  =  "client-"  +  mustGenerateRandomString (12 )
202- 	client .RedirectURIs  =  registrationRequest .RedirectURIs 
203- 	if  len (registrationRequest .GrantTypes ) >  0  {
204- 		client .GrantTypes  =  registrationRequest .GrantTypes 
205214	}
215+ 	json .Unmarshal (body , & req )
206216
207- 	secret  :=  "secret-"  +  mustGenerateRandomString (24 )
208- 	hashedSecret , err  :=  oauth .HashSecret (secret )
209- 	if  err  !=  nil  {
210- 		http .Error (w , "Internal Server Error" , http .StatusInternalServerError )
211- 		return 
217+ 	client  :=  & fosite.DefaultClient {
218+ 		ID :            "client-"  +  mustGenerateRandomString (12 ),
219+ 		Secret :        []byte ("secret-"  +  mustGenerateRandomString (24 )),
220+ 		RedirectURIs :  req .RedirectURIs ,
221+ 		GrantTypes :    fosite.Arguments {"authorization_code" , "refresh_token" },
222+ 		ResponseTypes : fosite.Arguments {"code" },
223+ 		Scopes :        fosite.Arguments {"openid" , "openid" },
212224	}
213- 	client .Secret  =  hashedSecret 
214225
215226	h .FositeStore .AddClient (client )
216227	h .Logger .Info ("Successfully registered new dynamic client" , "client_id" , client .ID )
217228
218229	w .Header ().Set ("Content-Type" , "application/json" )
219230	w .WriteHeader (http .StatusCreated )
220231	json .NewEncoder (w ).Encode (map [string ]interface {}{
221- 		"client_id" :                client .GetID () ,
222- 		"client_secret" :            secret ,
232+ 		"client_id" :                client .ID ,
233+ 		"client_secret" :            client . Secret ,
223234		"grant_types" :              client .GetGrantTypes (),
224- 		"redirect_uris" :            client .GetRedirectURIs (),
225- 		"client_name" :              registrationRequest .ClientName ,
235+ 		"scopes_supported" :         []string {"default" , "openid" },
236+ 		"redirect_uris" :            client .RedirectURIs ,
237+ 		"client_name" :              req .ClientName ,
226238		"client_id_issued_at" :      time .Now ().Unix (),
227239		"client_secret_expires_at" : 0 ,
228240	})
@@ -237,7 +249,7 @@ func (h *OAuthHandler) Discovery(w http.ResponseWriter, r *http.Request) {
237249		"token_endpoint" :         issuer  +  "/token" ,
238250		"jwks_uri" :               issuer  +  "/.well-known/jwks.json" , // Placeholder 
239251		"registration_endpoint" :  issuer  +  "/register" ,
240- 		"scopes_supported" :       []string {"openid" ,  "offline" },
252+ 		"scopes_supported" :       []string {"openid" },
241253		"response_types_supported" : []string {
242254			"code" ,
243255			"id_token" ,
@@ -266,7 +278,7 @@ func (h *OAuthHandler) ProtectedResourceMetadata(w http.ResponseWriter, r *http.
266278		"authorization_servers" : []string {
267279			issuer ,
268280		},
269- 		"scopes_supported" :         []string {"default" , "offline"  ,  " openid" },
281+ 		"scopes_supported" :         []string {"default" , "openid" },
270282		"bearer_methods_supported" : []string {"header" },
271283	}
272284
0 commit comments