@@ -62,6 +62,15 @@ var authFieldKeys = []authFieldKey{
6262 authFlowType ,
6363}
6464
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+
6574func SetAuthFlow (value AuthFlow ) error {
6675 return SetAuthField (authFlowType , string (value ))
6776}
@@ -105,6 +114,65 @@ func setAuthFieldInKeyring(activeProfile string, key authFieldKey, value string)
105114 return keyring .Set (keyringService , string (key ), value )
106115}
107116
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+
108176func deleteAuthFieldInKeyring (activeProfile string , key authFieldKey ) error {
109177 keyringServiceLocal := keyringService
110178 if activeProfile != config .DefaultProfileName {
@@ -273,7 +341,32 @@ func GetProfileEmail(profile string) string {
273341 return email
274342}
275343
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 {
277370 err := config .ValidateProfile (profile )
278371 if err != nil {
279372 return fmt .Errorf ("validate profile: %w" , err )
@@ -284,12 +377,9 @@ func DeleteProfileFromKeyring(profile string) error {
284377 }
285378
286379 for _ , key := range authFieldKeys {
287- err := deleteAuthFieldInKeyring (profile , key )
380+ err := deleteAuthFieldWithProfile (profile , key )
288381 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 )
293383 }
294384 }
295385
0 commit comments