Skip to content

Commit fa60fd5

Browse files
committed
Refactor DI pattern of oauth package
1 parent c9d86b9 commit fa60fd5

File tree

63 files changed

+2607
-1500
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2607
-1500
lines changed

backend/.mockery.private.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,19 @@ packages:
2828
structname: '{{.InterfaceName}}Mock'
2929
pkgname: cache
3030
filename: "{{.InterfaceName}}_mock_test.go"
31+
32+
github.com/asgardeo/thunder/internal/oauth/oauth2/introspect:
33+
config:
34+
all: true
35+
dir: internal/oauth/oauth2/introspect
36+
structname: '{{.InterfaceName}}Mock'
37+
pkgname: introspect
38+
filename: "{{.InterfaceName}}_mock_test.go"
39+
40+
github.com/asgardeo/thunder/internal/oauth/oauth2/authz:
41+
config:
42+
all: true
43+
dir: internal/oauth/oauth2/authz
44+
structname: '{{.InterfaceName}}Mock'
45+
pkgname: authz
46+
filename: "{{.InterfaceName}}_mock_test.go"

backend/.mockery.public.yml

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -93,28 +93,12 @@ packages:
9393
pkgname: jwksmock
9494
filename: "{{.InterfaceName}}_mock.go"
9595

96-
github.com/asgardeo/thunder/internal/oauth/scope/provider:
96+
github.com/asgardeo/thunder/internal/oauth/scope:
9797
config:
9898
all: true
99-
dir: tests/mocks/oauth/scope/providermock
99+
dir: tests/mocks/oauth/scopemock
100100
structname: '{{.InterfaceName}}Mock'
101-
pkgname: providermock
102-
filename: "{{.InterfaceName}}_mock.go"
103-
104-
github.com/asgardeo/thunder/internal/oauth/scope/validator:
105-
config:
106-
all: true
107-
dir: tests/mocks/oauth/scope/validatormock
108-
structname: '{{.InterfaceName}}Mock'
109-
pkgname: validatormock
110-
filename: "{{.InterfaceName}}_mock.go"
111-
112-
github.com/asgardeo/thunder/internal/oauth/session/store:
113-
config:
114-
all: true
115-
dir: tests/mocks/oauth/session/storemock
116-
structname: '{{.InterfaceName}}Mock'
117-
pkgname: storemock
101+
pkgname: scopemock
118102
filename: "{{.InterfaceName}}_mock.go"
119103

120104
github.com/asgardeo/thunder/internal/oauth/oauth2/authz:
@@ -125,14 +109,6 @@ packages:
125109
pkgname: authzmock
126110
filename: "{{.InterfaceName}}_mock.go"
127111

128-
github.com/asgardeo/thunder/internal/oauth/oauth2/authz/store:
129-
config:
130-
all: true
131-
dir: tests/mocks/oauth/oauth2/authz/storemock
132-
structname: '{{.InterfaceName}}Mock'
133-
pkgname: storemock
134-
filename: "{{.InterfaceName}}_mock.go"
135-
136112
github.com/asgardeo/thunder/internal/oauth/oauth2/granthandlers:
137113
config:
138114
all: true
@@ -244,3 +220,11 @@ packages:
244220
structname: '{{.InterfaceName}}Mock'
245221
pkgname: httpmock
246222
filename: "{{.InterfaceName}}_mock.go"
223+
224+
github.com/asgardeo/thunder/internal/application:
225+
config:
226+
all: true
227+
dir: tests/mocks/applicationmock
228+
structname: '{{.InterfaceName}}Mock'
229+
pkgname: applicationmock
230+
filename: "{{.InterfaceName}}_mock.go"

backend/cmd/server/servicemanager.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/asgardeo/thunder/internal/group"
3030
"github.com/asgardeo/thunder/internal/idp"
3131
"github.com/asgardeo/thunder/internal/notification"
32+
"github.com/asgardeo/thunder/internal/oauth"
3233
"github.com/asgardeo/thunder/internal/ou"
3334
"github.com/asgardeo/thunder/internal/system/jwt"
3435
"github.com/asgardeo/thunder/internal/system/log"
@@ -63,24 +64,15 @@ func registerServices(mux *http.ServeMux) {
6364

6465
_ = flowexec.Initialize(mux, flowMgtService, applicationService)
6566

67+
// Initialize OAuth services.
68+
oauth.Initialize(mux, applicationService, userService, jwtService)
69+
6670
// TODO: Legacy way of initializing services. These need to be refactored in the future aligning to the
6771
// dependency injection pattern used above.
6872

6973
// Register the health service.
7074
services.NewHealthCheckService(mux)
7175

72-
// Register the token service.
73-
services.NewTokenService(mux)
74-
75-
// Register the authorization service.
76-
services.NewAuthorizationService(mux)
77-
78-
// Register the JWKS service.
79-
services.NewJWKSAPIService(mux)
80-
81-
// Register the introspection service.
82-
services.NewIntrospectionAPIService(mux)
83-
8476
// Register the authentication service.
8577
services.NewAuthenticationService(mux)
8678
}

backend/internal/oauth/init.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
// Package oauth provides centralized initialization for all OAuth-related services.
20+
package oauth
21+
22+
import (
23+
"net/http"
24+
25+
"github.com/asgardeo/thunder/internal/application"
26+
"github.com/asgardeo/thunder/internal/oauth/jwks"
27+
"github.com/asgardeo/thunder/internal/oauth/oauth2/granthandlers"
28+
"github.com/asgardeo/thunder/internal/oauth/oauth2/introspect"
29+
"github.com/asgardeo/thunder/internal/oauth/oauth2/token"
30+
"github.com/asgardeo/thunder/internal/oauth/scope"
31+
"github.com/asgardeo/thunder/internal/system/jwt"
32+
"github.com/asgardeo/thunder/internal/user"
33+
)
34+
35+
// Initialize initializes all OAuth-related services and registers their routes.
36+
func Initialize(
37+
mux *http.ServeMux,
38+
applicationService application.ApplicationServiceInterface,
39+
userService user.UserServiceInterface,
40+
jwtService jwt.JWTServiceInterface,
41+
) {
42+
jwks.Initialize(mux)
43+
grantHandlerProvider := granthandlers.Initialize(mux, jwtService, userService, applicationService)
44+
scopeValidator := scope.Initialize()
45+
token.Initialize(mux, applicationService, grantHandlerProvider, scopeValidator)
46+
introspect.Initialize(mux, jwtService)
47+
}

backend/internal/oauth/jwks/constants/constants.go renamed to backend/internal/oauth/jwks/constants.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
* under the License.
1717
*/
1818

19-
// Package constants defines the constants used in the JWKS service.
20-
package constants
19+
package jwks
2120

2221
import "github.com/asgardeo/thunder/internal/system/error/serviceerror"
2322

backend/internal/oauth/jwks/handler/handler.go renamed to backend/internal/oauth/jwks/handler.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,32 @@
1616
* under the License.
1717
*/
1818

19-
// Package handler provides the HTTP handler for retrieving JSON Web Key Sets (JWKS).
20-
package handler
19+
package jwks
2120

2221
import (
2322
"encoding/json"
2423
"net/http"
2524

26-
"github.com/asgardeo/thunder/internal/oauth/jwks"
2725
serverconst "github.com/asgardeo/thunder/internal/system/constants"
2826
"github.com/asgardeo/thunder/internal/system/error/apierror"
2927
"github.com/asgardeo/thunder/internal/system/error/serviceerror"
3028
"github.com/asgardeo/thunder/internal/system/log"
3129
)
3230

33-
// JWKSHandler handles requests for the JSON Web Key Set (JWKS).
34-
type JWKSHandler struct {
35-
jwksService jwks.JWKSServiceInterface
31+
// jwksHandler handles requests for the JSON Web Key Set (JWKS).
32+
type jwksHandler struct {
33+
jwksService JWKSServiceInterface
3634
}
3735

38-
// NewJWKSHandler creates a new instance of JWKSHandler.
39-
func NewJWKSHandler() *JWKSHandler {
40-
return &JWKSHandler{
41-
jwksService: jwks.NewJWKSService(),
36+
// newJWKSHandler creates a new instance of jwksHandler.
37+
func newJWKSHandler(jwksService JWKSServiceInterface) *jwksHandler {
38+
return &jwksHandler{
39+
jwksService: jwksService,
4240
}
4341
}
4442

4543
// HandleJWKSRequest handles the HTTP request to retrieve the JSON Web Key Set (JWKS).
46-
func (h *JWKSHandler) HandleJWKSRequest(w http.ResponseWriter, r *http.Request) {
44+
func (h *jwksHandler) HandleJWKSRequest(w http.ResponseWriter, r *http.Request) {
4745
logger := log.GetLogger().With(log.String(log.LoggerKeyComponentName, "JWKSHandler"))
4846

4947
jwksResponse, svcErr := h.jwksService.GetJWKS()
@@ -64,7 +62,7 @@ func (h *JWKSHandler) HandleJWKSRequest(w http.ResponseWriter, r *http.Request)
6462
}
6563

6664
// handleError handles errors by writing an appropriate error response to the HTTP response writer.
67-
func (h *JWKSHandler) handleError(w http.ResponseWriter, logger *log.Logger,
65+
func (h *jwksHandler) handleError(w http.ResponseWriter, logger *log.Logger,
6866
svcErr *serviceerror.ServiceError) {
6967
w.Header().Set(serverconst.ContentTypeHeaderName, serverconst.ContentTypeJSON)
7068

backend/internal/system/services/jwksservice.go renamed to backend/internal/oauth/jwks/init.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,32 @@
1616
* under the License.
1717
*/
1818

19-
package services
19+
package jwks
2020

2121
import (
2222
"net/http"
2323

24-
"github.com/asgardeo/thunder/internal/oauth/jwks/handler"
2524
"github.com/asgardeo/thunder/internal/system/middleware"
2625
)
2726

28-
// JWKSAPIService defines the API service for handling JWKS requests.
29-
type JWKSAPIService struct {
30-
jwksHandler *handler.JWKSHandler
27+
// Initialize initializes the JWKS service and registers its routes.
28+
func Initialize(mux *http.ServeMux) JWKSServiceInterface {
29+
// Initialize the JWKS service
30+
jwksService := newJWKSService()
31+
jwksHandler := newJWKSHandler(jwksService)
32+
registerRoutes(mux, jwksHandler)
33+
return jwksService
3134
}
3235

33-
// NewJWKSAPIService creates a new instance of JWKSAPIService.
34-
func NewJWKSAPIService(mux *http.ServeMux) ServiceInterface {
35-
instance := &JWKSAPIService{
36-
jwksHandler: handler.NewJWKSHandler(),
37-
}
38-
instance.RegisterRoutes(mux)
39-
40-
return instance
41-
}
42-
43-
// RegisterRoutes registers the routes for the JWKSAPIService.
44-
func (s *JWKSAPIService) RegisterRoutes(mux *http.ServeMux) {
36+
// registerRoutes registers the routes for the JWKSAPIService.
37+
func registerRoutes(mux *http.ServeMux, jwksHandler *jwksHandler) {
4538
opts := middleware.CORSOptions{
4639
AllowedMethods: "GET, OPTIONS",
4740
AllowedHeaders: "Content-Type, Authorization",
4841
AllowCredentials: true,
4942
}
5043
mux.HandleFunc(middleware.WithCORS("GET /oauth2/jwks",
51-
s.jwksHandler.HandleJWKSRequest, opts))
44+
jwksHandler.HandleJWKSRequest, opts))
5245
mux.HandleFunc(middleware.WithCORS("OPTIONS /oauth2/jwks",
5346
func(w http.ResponseWriter, r *http.Request) {
5447
w.WriteHeader(http.StatusNoContent)

backend/internal/oauth/jwks/model/model.go renamed to backend/internal/oauth/jwks/model.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
* under the License.
1717
*/
1818

19-
// Package model defines the data structures used in the JWKS service.
20-
package model
19+
package jwks
2120

2221
// JWKS defines the structure of a JSON Web Key Set.
2322
type JWKS struct {

backend/internal/oauth/jwks/service.go

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,52 +29,45 @@ import (
2929
// Use crypto/sha1 only for JWKS x5t as required by spec for thumbprint.
3030
"crypto/sha1" //nolint:gosec
3131

32-
"github.com/asgardeo/thunder/internal/cert"
33-
"github.com/asgardeo/thunder/internal/oauth/jwks/constants"
34-
"github.com/asgardeo/thunder/internal/oauth/jwks/model"
3532
"github.com/asgardeo/thunder/internal/system/config"
3633
"github.com/asgardeo/thunder/internal/system/crypto/hash"
3734
"github.com/asgardeo/thunder/internal/system/error/serviceerror"
3835
)
3936

4037
// JWKSServiceInterface defines the interface for JWKS service.
4138
type JWKSServiceInterface interface {
42-
GetJWKS() (*model.JWKSResponse, *serviceerror.ServiceError)
39+
GetJWKS() (*JWKSResponse, *serviceerror.ServiceError)
4340
}
4441

45-
// JWKSService implements the JWKSServiceInterface.
46-
type JWKSService struct {
47-
SystemCertService cert.SystemCertificateServiceInterface
48-
}
42+
// jwksService implements the JWKSServiceInterface.
43+
type jwksService struct{}
4944

50-
// NewJWKSService creates a new instance of JWKSService.
51-
func NewJWKSService() JWKSServiceInterface {
52-
return &JWKSService{
53-
SystemCertService: cert.NewSystemCertificateService(),
54-
}
45+
// newJWKSService creates a new instance of JWKSService.
46+
func newJWKSService() JWKSServiceInterface {
47+
return &jwksService{}
5548
}
5649

5750
// GetJWKS retrieves the JSON Web Key Set (JWKS) from the server's TLS certificate.
58-
func (s *JWKSService) GetJWKS() (*model.JWKSResponse, *serviceerror.ServiceError) {
51+
func (s *jwksService) GetJWKS() (*JWKSResponse, *serviceerror.ServiceError) {
5952
certConfig := config.GetThunderRuntime().CertConfig
6053

6154
kid := certConfig.CertKid
6255
if kid == "" {
63-
return nil, constants.ErrorCertificateKidNotFound
56+
return nil, ErrorCertificateKidNotFound
6457
}
6558

6659
tlsConfig := certConfig.TLSConfig
6760
if tlsConfig == nil {
68-
return nil, constants.ErrorTLSConfigNotFound
61+
return nil, ErrorTLSConfigNotFound
6962
}
7063
if len(tlsConfig.Certificates) == 0 || len(tlsConfig.Certificates[0].Certificate) == 0 {
71-
return nil, constants.ErrorNoCertificateFound
64+
return nil, ErrorNoCertificateFound
7265
}
7366

7467
certData := tlsConfig.Certificates[0].Certificate[0]
7568
parsedCert, err := x509.ParseCertificate(certData)
7669
if err != nil {
77-
svcErr := constants.ErrorWhileParsingCertificate
70+
svcErr := ErrorWhileParsingCertificate
7871
svcErr.ErrorDescription = err.Error()
7972
return nil, svcErr
8073
}
@@ -87,7 +80,7 @@ func (s *JWKSService) GetJWKS() (*model.JWKSResponse, *serviceerror.ServiceError
8780
x5t := base64.StdEncoding.EncodeToString(sha1Sum[:])
8881
x5tS256 := hash.GenerateThumbprint(parsedCert.Raw)
8982

90-
var jwks model.JWKS
83+
var jwks JWKS
9184
switch pub := parsedCert.PublicKey.(type) {
9285
case *rsa.PublicKey:
9386
encodeBase64URL := func(b []byte) string {
@@ -107,7 +100,7 @@ func (s *JWKSService) GetJWKS() (*model.JWKSResponse, *serviceerror.ServiceError
107100
}
108101
eEnc := encodeBase64URL(eBytes)
109102

110-
jwks = model.JWKS{
103+
jwks = JWKS{
111104
Kid: kid,
112105
Kty: "RSA",
113106
Use: "sig",
@@ -135,7 +128,7 @@ func (s *JWKSService) GetJWKS() (*model.JWKSResponse, *serviceerror.ServiceError
135128
alg = "ES512"
136129
}
137130

138-
jwks = model.JWKS{
131+
jwks = JWKS{
139132
Kid: kid,
140133
Kty: "EC",
141134
Use: "sig",
@@ -148,10 +141,10 @@ func (s *JWKSService) GetJWKS() (*model.JWKSResponse, *serviceerror.ServiceError
148141
X5tS256: x5tS256,
149142
}
150143
default:
151-
return nil, constants.ErrorUnsupportedPublicKeyType
144+
return nil, ErrorUnsupportedPublicKeyType
152145
}
153146

154-
return &model.JWKSResponse{
155-
Keys: []model.JWKS{jwks},
147+
return &JWKSResponse{
148+
Keys: []JWKS{jwks},
156149
}, nil
157150
}

0 commit comments

Comments
 (0)