Skip to content

Commit 065f6c8

Browse files
committed
api refactor, enabling way to get valid token from client secret provider
1 parent c60ceb2 commit 065f6c8

5 files changed

+178
-175
lines changed

api_client.go

+43-10
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@ import (
88
"net/url"
99
"path"
1010
"strings"
11+
"time"
1112

1213
"github.com/dgrijalva/jwt-go/v4"
1314
"github.com/google/go-querystring/query"
1415
"github.com/hashicorp/go-cleanhttp"
1516
)
1617

1718
const (
19+
HTTPpHeaderAuthorization = "Authorization"
20+
1821
// grant type values
1922
GrantTypeCode = "code"
2023
GrantTypeUMA2Ticket = "urn:ietf:params:oauth:grant-type:uma-ticket"
@@ -27,6 +30,25 @@ const (
2730
UMA2ResponseModeDecision = "decision"
2831
UMA2ResponseModePermissions = "permissions"
2932

33+
DecisionStrategyUnanimous = "UNANIMOUS"
34+
DecisionStrategyAffirmative = "AFFIRMATIVE"
35+
DecisionStrategyPositive = "POSITIVE"
36+
37+
PermissionTypeResource = "resource"
38+
PermissionTypeRole = "role"
39+
40+
PolicyTypeRole = "role"
41+
PolicyTypeJavascript = "js"
42+
PolicyTypeTime = "time"
43+
44+
LogicPositive = "POSITIVE"
45+
LogicNegative = "NEGATIVE"
46+
47+
// DefaultTokenExpirationMargin will be used if you do not specify your own ExpiryMargin key in the config
48+
DefaultTokenExpirationMargin = 2 * time.Second
49+
)
50+
51+
const (
3052
// cache stuff
3153
pkKeyPrefix = "pk"
3254
pkKeyFormat = pkKeyPrefix + "\n%s\n%s\n%s"
@@ -38,7 +60,6 @@ const (
3860
httpHeaderContentType = "Content-Type"
3961
httpHeaderValueJSON = "application/json"
4062
httpHeaderValueFormURLEncoded = "application/x-www-form-urlencoded"
41-
HTTPpHeaderAuthorization = "Authorization"
4263
httpHeaderAuthorizationBearerPrefix = "Bearer"
4364
httpHeaderAuthorizationBasicPrefix = "Basic"
4465
httpHeaderAuthValueFormat = "%s %s"
@@ -91,6 +112,18 @@ const (
91112
kcPathPartUsers = "users"
92113
)
93114

115+
var ErrTokenExpired = errors.New("token has expired")
116+
117+
func IsTokenExpiredErr(err error) bool {
118+
for err != nil {
119+
if errors.Is(err, ErrTokenExpired) {
120+
return true
121+
}
122+
err = errors.Unwrap(err)
123+
}
124+
return false
125+
}
126+
94127
// DebugConfig
95128
//
96129
// This type contains configuration options that provide additional utility during testing or development, but should
@@ -211,7 +244,7 @@ func (c *APIClient) Do(ctx context.Context, req *APIRequest, mutators ...APIRequ
211244
}
212245

213246
// Call is a helper method that wraps the creation of an *APIRequest type and executes it.
214-
func (c *APIClient) Call(ctx context.Context, ap AuthProvider, method, requestURL string, body interface{}, mutators ...APIRequestMutator) (*http.Response, error) {
247+
func (c *APIClient) Call(ctx context.Context, ap AuthenticationProvider, method, requestURL string, body interface{}, mutators ...APIRequestMutator) (*http.Response, error) {
215248
var (
216249
req *APIRequest
217250
err error
@@ -227,7 +260,7 @@ func (c *APIClient) Call(ctx context.Context, ap AuthProvider, method, requestUR
227260
am []APIRequestMutator
228261
err error
229262
)
230-
if am, err = ap.AuthMutators(ctx, c); err != nil {
263+
if am, err = ap.RequestMutators(ctx, c); err != nil {
231264
return nil, err
232265
}
233266
mutators = requestMutators(mutators, am...)
@@ -408,7 +441,7 @@ func (c *APIClient) keyFunc(ctx context.Context) jwt.Keyfunc {
408441
}
409442
}
410443

411-
func (c *APIClient) openIDConnectToken(ctx context.Context, realmName string, ap AuthProvider, req *OpenIDConnectTokenRequest, mutators ...APIRequestMutator) (interface{}, error) {
444+
func (c *APIClient) openIDConnectToken(ctx context.Context, realmName string, ap AuthenticationProvider, req *OpenIDConnectTokenRequest, mutators ...APIRequestMutator) (interface{}, error) {
412445
var (
413446
body url.Values
414447
resp *http.Response
@@ -458,18 +491,18 @@ func (c *APIClient) realmsURL(realmName string, bits ...string) string {
458491
return fmt.Sprintf(kcURLPathRealmsFormat, c.authServerURL, realmName, path.Join(bits...))
459492
}
460493

461-
func (c *APIClient) callRealms(ctx context.Context, realmName string, ap AuthProvider, method, requestPath string, body interface{}, mutators ...APIRequestMutator) (*http.Response, error) {
494+
func (c *APIClient) callRealms(ctx context.Context, realmName string, ap AuthenticationProvider, method, requestPath string, body interface{}, mutators ...APIRequestMutator) (*http.Response, error) {
462495
return c.Call(ctx, ap, method, c.realmsURL(realmName, requestPath), body, mutators...)
463496
}
464497

465498
// AdminAPIClient is a simple extension of the base APIClient, adding /admin api calls
466499
type AdminAPIClient struct {
467500
*APIClient
468501
realmName string
469-
ap AuthProvider
502+
ap AuthenticationProvider
470503
}
471504

472-
func NewAdminAPIClient(config *APIClientConfig, realmName string, ap AuthProvider, mutators ...ConfigMutator) (*AdminAPIClient, error) {
505+
func NewAdminAPIClient(config *APIClientConfig, realmName string, ap AuthenticationProvider, mutators ...ConfigMutator) (*AdminAPIClient, error) {
473506
var (
474507
c *APIClient
475508
err error
@@ -492,19 +525,19 @@ func NewAdminAPIClientWithProvider(cp CombinedProvider, realmName string, mutato
492525

493526
func NewAdminAPIClientWithInstallDocument(id *InstallDocument, realmName string, mutators ...ConfigMutator) (*AdminAPIClient, error) {
494527
// todo: support ID's for things other than a confidential client
495-
ctp, err := NewConfidentialClientAuthProvider(&ConfidentialClientAuthProviderConfig{InstallDocument: id})
528+
ctp, err := NewClientSecretAuthenticationProvider(NewClientSecretConfigWithInstallDocument(id))
496529
if err != nil {
497530
return nil, err
498531
}
499532
return NewAdminAPIClientWithProvider(ctp, realmName, mutators...)
500533
}
501534

502535
// AdminClient returns a new AdminAPIClient for the provided realm (does not have to be the same as the auth'd realm)
503-
func (c *APIClient) AdminClient(realmName string, ap AuthProvider) *AdminAPIClient {
536+
func (c *APIClient) AdminClient(realmName string, ap AuthenticationProvider) *AdminAPIClient {
504537
return &AdminAPIClient{APIClient: c, realmName: realmName, ap: ap}
505538
}
506539

507-
func (c *AdminAPIClient) AuthProvider() AuthProvider {
540+
func (c *AdminAPIClient) AuthProvider() AuthenticationProvider {
508541
return c.ap
509542
}
510543

api_client_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ package keycloak_test
7070
// return configs
7171
//}
7272
//
73-
//func newClient(t *testing.T, testConfig *testConfig, mutators ...keycloak.ConfigMutator) (*keycloak.APIClient, keycloak.AuthProvider) {
73+
//func newClient(t *testing.T, testConfig *testConfig, mutators ...keycloak.ConfigMutator) (*keycloak.APIClient, keycloak.AuthenticationProvider) {
7474
// t.Helper()
7575
// var (
7676
// cl *keycloak.APIClient
77-
// ap keycloak.AuthProvider
77+
// ap keycloak.AuthenticationProvider
7878
// err error
7979
// )
8080
//
@@ -102,9 +102,9 @@ package keycloak_test
102102
//
103103
// if testConfig.ClientConfig.Cred != nil {
104104
// if testConfig.ClientConfig.Cred.BearerToken != "" {
105-
// ap = keycloak.NewBearerTokenAuthProvider(testConfig.ClientConfig.Cred.BearerToken)
105+
// ap = keycloak.NewBearerTokenProvider(testConfig.ClientConfig.Cred.BearerToken)
106106
// } else if testConfig.ClientConfig.Cred.InstallDocument != nil {
107-
// ap, err = keycloak.NewConfidentialClientAuthProvider(&keycloak.ConfidentialClientAuthProviderConfig{
107+
// ap, err = keycloak.NewClientSecretAuthenticationProvider(&keycloak.ClientSecretProviderConfig{
108108
// InstallDocument: testConfig.ClientConfig.Cred.InstallDocument,
109109
// })
110110
// } else {

api_models.go

-16
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,6 @@ import (
77
"time"
88
)
99

10-
const (
11-
DecisionStrategyUnanimous = "UNANIMOUS"
12-
DecisionStrategyAffirmative = "AFFIRMATIVE"
13-
DecisionStrategyPositive = "POSITIVE"
14-
15-
PermissionTypeResource = "resource"
16-
PermissionTypeRole = "role"
17-
18-
PolicyTypeRole = "role"
19-
PolicyTypeJavascript = "js"
20-
PolicyTypeTime = "time"
21-
22-
LogicPositive = "POSITIVE"
23-
LogicNegative = "NEGATIVE"
24-
)
25-
2610
type KeyValueMap map[string]string
2711
type KeyValuesMap map[string][]string
2812

0 commit comments

Comments
 (0)