-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathjwt.go
129 lines (105 loc) · 3.9 KB
/
jwt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package frame
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
)
// RegisterForJwt function hooks in jwt client registration to make sure service is authenticated
func (s *Service) RegisterForJwt(ctx context.Context) error {
oauth2Config, ok := s.Config().(ConfigurationOAUTH2)
if ok {
oauth2ServiceAdminHost := oauth2Config.GetOauth2ServiceAdminURI()
clientSecret := oauth2Config.GetOauth2ServiceClientSecret()
oauth2Audience := oauth2Config.GetOauth2ServiceAudience()
if oauth2ServiceAdminHost != "" && clientSecret != "" {
audienceList := strings.Split(oauth2Audience, ",")
jwtClient, err := s.RegisterForJwtWithParams(ctx, oauth2ServiceAdminHost, s.Name(), clientSecret,
"", audienceList, map[string]string{})
if err != nil {
return err
}
s.jwtClient = jwtClient
s.jwtClientSecret = clientSecret
}
}
return nil
}
// RegisterForJwtWithParams registers the supplied details for ability to generate access tokens.
// This is useful for situations where one may need to register external applications for access token generation
func (s *Service) RegisterForJwtWithParams(ctx context.Context,
oauth2ServiceAdminHost string, clientName string, clientSecret string,
scope string, audienceList []string, metadata map[string]string) (map[string]any, error) {
oauth2AdminURI := fmt.Sprintf("%s%s", oauth2ServiceAdminHost, "/admin/clients")
oauth2AdminIDUri := fmt.Sprintf("%s?client_name=%s", oauth2AdminURI, url.QueryEscape(clientName))
status, response, err := s.InvokeRestService(ctx, http.MethodGet, oauth2AdminIDUri, nil, nil)
if err != nil {
s.L(ctx).WithError(err).Error("could not get existing clients")
return nil, err
}
if status > 299 || status < 200 {
s.L(ctx).
WithField("status", status).
WithField("result", string(response)).
Error(" invalid response from oauth2 server")
return nil, fmt.Errorf("invalid existing clients check response : %s", response)
}
var existingClients []map[string]any
err = json.Unmarshal(response, &existingClients)
if err != nil {
s.L(ctx).WithError(err).WithField("payload", string(response)).
Error("could not unmarshal existing clients")
return nil, err
}
if len(existingClients) > 0 {
return existingClients[0], nil
}
metadata["cc_bot"] = "true"
payload := map[string]any{
"client_name": url.QueryEscape(clientName),
"client_secret": url.QueryEscape(clientSecret),
"grant_types": []string{"client_credentials"},
"metadata": metadata,
"audience": audienceList,
"token_endpoint_auth_method": "client_secret_post",
}
if scope != "" {
payload["scope"] = scope
}
status, response, err = s.InvokeRestService(ctx, http.MethodPost, oauth2AdminURI, payload, nil)
if err != nil {
s.L(ctx).WithError(err).Error("could not create a new client")
return nil, err
}
if status > 299 || status < 200 {
s.L(ctx).
WithField("status", status).
WithField("result", string(response)).
Error(" invalid response from server")
return nil, fmt.Errorf("invalid registration response : %s", response)
}
var newClient map[string]any
err = json.Unmarshal(response, &newClient)
if err != nil {
s.L(ctx).WithError(err).Error("could not un marshal new client")
return nil, err
}
return newClient, nil
}
// UnRegisterForJwt utilizing client id we de register external applications for access token generation
func (s *Service) UnRegisterForJwt(ctx context.Context,
oauth2ServiceAdminHost string, clientID string) error {
oauth2AdminURI := fmt.Sprintf("%s%s/%s", oauth2ServiceAdminHost, "/admin/clients", clientID)
status, result, err := s.InvokeRestService(ctx, http.MethodDelete, oauth2AdminURI, make(map[string]any), nil)
if err != nil {
s.L(ctx).
WithError(err).
WithField("status", status).
WithField("result", string(result)).
Error(" invalid response from server")
return err
}
return nil
}