@rivascva/dt-idl 1.1.95 → 1.1.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/go/auth/utils.go +3 -3
- package/go/request/auth_transport.go +91 -0
- package/package.json +1 -1
package/go/auth/utils.go
CHANGED
|
@@ -33,8 +33,8 @@ func CanActorAccessResourcesForUser(ctx context.Context, userId string) (bool, e
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
//
|
|
37
|
-
func
|
|
36
|
+
// CanActorAccessAllResources checks if the actor is allowed to access all resources.
|
|
37
|
+
func CanActorAccessAllResources(ctx context.Context) (bool, error) {
|
|
38
38
|
// get the actor id from the context
|
|
39
39
|
actorId, err := utils.GetActorIdFromContext(ctx)
|
|
40
40
|
if err != nil {
|
|
@@ -47,7 +47,7 @@ func CanActorAccessResourcesForAll(ctx context.Context) (bool, error) {
|
|
|
47
47
|
return false, fmt.Errorf("failed to get the token type from the context: %w", err)
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// check if the actor is
|
|
50
|
+
// check if the actor is a service
|
|
51
51
|
switch tokenType {
|
|
52
52
|
case "user":
|
|
53
53
|
return false, nil
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
package request
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"net/http"
|
|
6
|
+
"sync"
|
|
7
|
+
"time"
|
|
8
|
+
|
|
9
|
+
"github.com/RivasCVA/dt-idl/go/auth"
|
|
10
|
+
"github.com/golang-jwt/jwt/v5"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
type AuthTransport struct {
|
|
14
|
+
mu sync.RWMutex
|
|
15
|
+
transport http.RoundTripper
|
|
16
|
+
service string
|
|
17
|
+
secret string
|
|
18
|
+
token *jwt.Token
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func (t *AuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
22
|
+
// get the token
|
|
23
|
+
t.mu.RLock()
|
|
24
|
+
token := t.token
|
|
25
|
+
t.mu.RUnlock()
|
|
26
|
+
|
|
27
|
+
// get the token expiration time
|
|
28
|
+
expirationTime := time.Time{}
|
|
29
|
+
if token != nil {
|
|
30
|
+
e, err := token.Claims.GetExpirationTime()
|
|
31
|
+
if err != nil {
|
|
32
|
+
return nil, fmt.Errorf("failed to get the expiration time from the token: %w", err)
|
|
33
|
+
}
|
|
34
|
+
expirationTime = e.Time
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// check if the token is expired or close to expiring
|
|
38
|
+
if expirationTime.Before(time.Now().Add(time.Minute)) {
|
|
39
|
+
err := t.setNewToken()
|
|
40
|
+
if err != nil {
|
|
41
|
+
return nil, fmt.Errorf("failed to set a new token: %w", err)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// perform the request
|
|
46
|
+
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", t.token.Raw))
|
|
47
|
+
resp, err := t.transport.RoundTrip(req)
|
|
48
|
+
if err != nil {
|
|
49
|
+
return nil, err
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// check if the request failed due to an authorization error.
|
|
53
|
+
// this should ideally not happen since we are setting a new token if the current one is expired or close to expiring,
|
|
54
|
+
// but it is still possible for the token to be revoked.
|
|
55
|
+
if resp != nil && resp.StatusCode == http.StatusUnauthorized {
|
|
56
|
+
// set a new token
|
|
57
|
+
err := t.setNewToken()
|
|
58
|
+
if err != nil {
|
|
59
|
+
return nil, fmt.Errorf("failed to set a new token: %w", err)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// retry the request
|
|
63
|
+
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", t.token.Raw))
|
|
64
|
+
return t.transport.RoundTrip(req)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// return the original response
|
|
68
|
+
return resp, err
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
func (t *AuthTransport) setNewToken() error {
|
|
72
|
+
t.mu.Lock()
|
|
73
|
+
defer t.mu.Unlock()
|
|
74
|
+
|
|
75
|
+
// create a new service token
|
|
76
|
+
rawToken, err := auth.NewServiceToken(t.secret, t.service, t.service, auth.DefaultServiceTokenDuration)
|
|
77
|
+
if err != nil {
|
|
78
|
+
return fmt.Errorf("failed to create a new service token: %w", err)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// validate the token
|
|
82
|
+
token, err := auth.ValidateToken(rawToken, t.secret)
|
|
83
|
+
if err != nil {
|
|
84
|
+
return fmt.Errorf("failed to validate the new token: %w", err)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// set the new token
|
|
88
|
+
t.token = token
|
|
89
|
+
|
|
90
|
+
return nil
|
|
91
|
+
}
|