@@ -62,6 +62,15 @@ var authFieldKeys = []authFieldKey{
62
62
authFlowType ,
63
63
}
64
64
65
+ // All fields that are set when a user logs in
66
+ // These fields should match the ones in LoginUser, which is ensured by the tests
67
+ var loginAuthFieldKeys = []authFieldKey {
68
+ SESSION_EXPIRES_AT_UNIX ,
69
+ ACCESS_TOKEN ,
70
+ REFRESH_TOKEN ,
71
+ USER_EMAIL ,
72
+ }
73
+
65
74
func SetAuthFlow (value AuthFlow ) error {
66
75
return SetAuthField (authFlowType , string (value ))
67
76
}
@@ -105,6 +114,65 @@ func setAuthFieldInKeyring(activeProfile string, key authFieldKey, value string)
105
114
return keyring .Set (keyringService , string (key ), value )
106
115
}
107
116
117
+ func DeleteAuthField (key authFieldKey ) error {
118
+ activeProfile , err := config .GetProfile ()
119
+ if err != nil {
120
+ return fmt .Errorf ("get profile: %w" , err )
121
+ }
122
+ return deleteAuthFieldWithProfile (activeProfile , key )
123
+ }
124
+
125
+ func deleteAuthFieldWithProfile (profile string , key authFieldKey ) error {
126
+ err := deleteAuthFieldInKeyring (profile , key )
127
+ if err != nil {
128
+ // if the key is not found, we can ignore the error
129
+ if ! errors .Is (err , keyring .ErrNotFound ) {
130
+ errFallback := deleteAuthFieldInEncodedTextFile (profile , key )
131
+ if errFallback != nil {
132
+ return fmt .Errorf ("delete from keyring failed (%w), try deleting from encoded text file: %w" , err , errFallback )
133
+ }
134
+ }
135
+ }
136
+ return nil
137
+ }
138
+
139
+ func deleteAuthFieldInEncodedTextFile (activeProfile string , key authFieldKey ) error {
140
+ err := createEncodedTextFile (activeProfile )
141
+ if err != nil {
142
+ return err
143
+ }
144
+
145
+ textFileDir := config .GetProfileFolderPath (activeProfile )
146
+ textFilePath := filepath .Join (textFileDir , textFileName )
147
+
148
+ contentEncoded , err := os .ReadFile (textFilePath )
149
+ if err != nil {
150
+ return fmt .Errorf ("read file: %w" , err )
151
+ }
152
+ contentBytes , err := base64 .StdEncoding .DecodeString (string (contentEncoded ))
153
+ if err != nil {
154
+ return fmt .Errorf ("decode file: %w" , err )
155
+ }
156
+ content := map [authFieldKey ]string {}
157
+ err = json .Unmarshal (contentBytes , & content )
158
+ if err != nil {
159
+ return fmt .Errorf ("unmarshal file: %w" , err )
160
+ }
161
+
162
+ delete (content , key )
163
+
164
+ contentBytes , err = json .Marshal (content )
165
+ if err != nil {
166
+ return fmt .Errorf ("marshal file: %w" , err )
167
+ }
168
+ contentEncoded = []byte (base64 .StdEncoding .EncodeToString (contentBytes ))
169
+ err = os .WriteFile (textFilePath , contentEncoded , 0o600 )
170
+ if err != nil {
171
+ return fmt .Errorf ("write file: %w" , err )
172
+ }
173
+ return nil
174
+ }
175
+
108
176
func deleteAuthFieldInKeyring (activeProfile string , key authFieldKey ) error {
109
177
keyringServiceLocal := keyringService
110
178
if activeProfile != config .DefaultProfileName {
@@ -273,7 +341,32 @@ func GetProfileEmail(profile string) string {
273
341
return email
274
342
}
275
343
276
- func DeleteProfileFromKeyring (profile string ) error {
344
+ func LoginUser (email , accessToken , refreshToken , sessionExpiresAtUnix string ) error {
345
+ authFields := map [authFieldKey ]string {
346
+ SESSION_EXPIRES_AT_UNIX : sessionExpiresAtUnix ,
347
+ ACCESS_TOKEN : accessToken ,
348
+ REFRESH_TOKEN : refreshToken ,
349
+ USER_EMAIL : email ,
350
+ }
351
+
352
+ err := SetAuthFieldMap (authFields )
353
+ if err != nil {
354
+ return fmt .Errorf ("set auth fields: %w" , err )
355
+ }
356
+ return nil
357
+ }
358
+
359
+ func LogoutUser () error {
360
+ for _ , key := range loginAuthFieldKeys {
361
+ err := DeleteAuthField (key )
362
+ if err != nil {
363
+ return fmt .Errorf ("delete auth field \" %s\" : %w" , key , err )
364
+ }
365
+ }
366
+ return nil
367
+ }
368
+
369
+ func DeleteProfileAuth (profile string ) error {
277
370
err := config .ValidateProfile (profile )
278
371
if err != nil {
279
372
return fmt .Errorf ("validate profile: %w" , err )
@@ -284,12 +377,9 @@ func DeleteProfileFromKeyring(profile string) error {
284
377
}
285
378
286
379
for _ , key := range authFieldKeys {
287
- err := deleteAuthFieldInKeyring (profile , key )
380
+ err := deleteAuthFieldWithProfile (profile , key )
288
381
if err != nil {
289
- // if the key is not found, we can ignore the error
290
- if ! errors .Is (err , keyring .ErrNotFound ) {
291
- return fmt .Errorf ("delete auth field \" %s\" from keyring: %w" , key , err )
292
- }
382
+ return fmt .Errorf ("delete auth field \" %s\" : %w" , key , err )
293
383
}
294
384
}
295
385
0 commit comments