1
+ // Package entraid provides a credentials provider that manages token retrieval and notifies listeners
2
+ // of token updates. It implements the auth.StreamingCredentialsProvider interface and is designed
3
+ // for use with the Redis authentication system.
1
4
package entraid
2
5
3
6
import (
@@ -14,19 +17,20 @@ var _ auth.StreamingCredentialsProvider = (*entraidCredentialsProvider)(nil)
14
17
15
18
// entraidCredentialsProvider is a struct that implements the StreamingCredentialsProvider interface.
16
19
type entraidCredentialsProvider struct {
17
- options CredentialsProviderOptions
20
+ options CredentialsProviderOptions // Configuration options for the provider.
18
21
19
- tokenManager manager.TokenManager
20
- cancelTokenManager manager.CancelFunc
22
+ tokenManager manager.TokenManager // Manages token retrieval.
23
+ cancelTokenManager manager.CancelFunc // Function to cancel the token manager.
21
24
22
25
// listeners is a slice of listeners that are notified when the token manager receives a new token.
23
- listeners []auth.CredentialsListener
26
+ listeners []auth.CredentialsListener // Slice of listeners notified on token updates.
24
27
25
28
// rwLock is a mutex that is used to synchronize access to the listeners slice.
26
- rwLock sync.RWMutex
29
+ rwLock sync.RWMutex // Mutex for synchronizing access to the listeners slice.
27
30
}
28
31
29
32
// onTokenNext is a method that is called when the token manager receives a new token.
33
+ // It notifies all registered listeners with the new token.
30
34
func (e * entraidCredentialsProvider ) onTokenNext (t * token.Token ) {
31
35
e .rwLock .RLock ()
32
36
defer e .rwLock .RUnlock ()
@@ -37,7 +41,7 @@ func (e *entraidCredentialsProvider) onTokenNext(t *token.Token) {
37
41
}
38
42
39
43
// onTokenError is a method that is called when the token manager encounters an error.
40
- // It notifies all listeners with the error.
44
+ // It notifies all registered listeners with the error.
41
45
func (e * entraidCredentialsProvider ) onTokenError (err error ) {
42
46
e .rwLock .RLock ()
43
47
defer e .rwLock .RUnlock ()
@@ -48,11 +52,18 @@ func (e *entraidCredentialsProvider) onTokenError(err error) {
48
52
}
49
53
}
50
54
51
- // Subscribe subscribes to the credentials provider and returns a channel that will receive updates.
52
- // The first response is blocking, then data will notify the listener.
53
- // The listener will be notified with the credentials when they are available.
54
- // The listener will be notified with an error if there is an error obtaining the credentials.
55
- // The caller can cancel the subscription by calling the cancel function which is the second return value.
55
+ // Subscribe subscribes a listener to the credentials provider.
56
+ // It returns the current credentials, a cancel function to unsubscribe, and an error if the subscription fails.
57
+ //
58
+ // Parameters:
59
+ // - listener: The listener that will receive updates about token changes.
60
+ //
61
+ // Returns:
62
+ // - auth.Credentials: The current credentials for the listener.
63
+ // - auth.CancelProviderFunc: A function that can be called to unsubscribe the listener.
64
+ // - error: An error if the subscription fails, such as if the token cannot be retrieved.
65
+ //
66
+ // Note: If the listener is already subscribed, it will not receive duplicate notifications.
56
67
func (e * entraidCredentialsProvider ) Subscribe (listener auth.CredentialsListener ) (auth.Credentials , auth.CancelProviderFunc , error ) {
57
68
e .rwLock .Lock ()
58
69
// Check if the listener is already in the list of listeners.
@@ -83,17 +94,20 @@ func (e *entraidCredentialsProvider) Subscribe(listener auth.CredentialsListener
83
94
// Remove the listener from the list of listeners.
84
95
e .rwLock .Lock ()
85
96
defer e .rwLock .Unlock ()
97
+
86
98
for i , l := range e .listeners {
87
99
if l == listener {
88
100
e .listeners = append (e .listeners [:i ], e .listeners [i + 1 :]... )
89
101
break
90
102
}
91
103
}
104
+
105
+ // Clear the listeners slice if it's empty
92
106
if len (e .listeners ) == 0 {
107
+ e .listeners = make ([]auth.CredentialsListener , 0 )
93
108
if e .cancelTokenManager != nil {
94
109
defer func () {
95
110
e .cancelTokenManager = nil
96
- e .listeners = nil
97
111
}()
98
112
return e .cancelTokenManager ()
99
113
}
@@ -104,21 +118,21 @@ func (e *entraidCredentialsProvider) Subscribe(listener auth.CredentialsListener
104
118
return token , cancel , nil
105
119
}
106
120
107
- // NewCredentialsProvider creates a new credentials provider.
108
- // It takes a TokenManager and CredentialProviderOptions as arguments and returns a StreamingCredentialsProvider interface.
109
- // The TokenManager is used to obtain the token, and the CredentialProviderOptions contains options for the credentials provider.
110
- // The credentials provider is responsible for managing the credentials and refreshing them when necessary.
111
- // It returns an error if the token manager cannot be started.
121
+ // NewCredentialsProvider creates a new credentials provider with the specified token manager and options.
122
+ // It returns a StreamingCredentialsProvider interface and an error if the token manager cannot be started.
123
+ //
124
+ // Parameters:
125
+ // - tokenManager: The TokenManager used to obtain tokens.
126
+ // - options: Options for configuring the credentials provider.
112
127
//
113
- // This function is typically used when you need to create a custom credentials provider with a specific token manager.
114
- // For most use cases, it's recommended to use the type-specific constructors:
115
- // - NewManagedIdentityCredentialsProvider for managed identity authentication
116
- // - NewConfidentialCredentialsProvider for client secret or certificate authentication
117
- // - NewDefaultAzureCredentialsProvider for default Azure identity authentication
128
+ // Returns:
129
+ // - auth.StreamingCredentialsProvider: The newly created credentials provider.
130
+ // - error: An error if the token manager cannot be started.
118
131
func NewCredentialsProvider (tokenManager manager.TokenManager , options CredentialsProviderOptions ) (auth.StreamingCredentialsProvider , error ) {
119
132
cp := & entraidCredentialsProvider {
120
133
tokenManager : tokenManager ,
121
134
options : options ,
135
+ listeners : make ([]auth.CredentialsListener , 0 ),
122
136
}
123
137
cancelTokenManager , err := cp .tokenManager .Start (tokenListenerFromCP (cp ))
124
138
if err != nil {
0 commit comments