Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2

oauth: integrate multi-account into session management

authored by lewis.moe and committed by tangled.org bbd871a7 c8458e89

+80 -6
+14 -2
appview/oauth/handler.go
··· 55 55 ctx := r.Context() 56 56 l := o.Logger.With("query", r.URL.Query()) 57 57 58 + authReturn := o.GetAuthReturn(r) 59 + _ = o.ClearAuthReturn(w, r) 60 + 58 61 sessData, err := o.ClientApp.ProcessCallback(ctx, r.URL.Query()) 59 62 if err != nil { 60 63 var callbackErr *oauth.AuthRequestCallbackError ··· 73 70 74 71 if err := o.SaveSession(w, r, sessData); err != nil { 75 72 l.Error("failed to save session", "data", sessData, "err", err) 76 - http.Redirect(w, r, "/login?error=session", http.StatusFound) 73 + errorCode := "session" 74 + if errors.Is(err, ErrMaxAccountsReached) { 75 + errorCode = "max_accounts" 76 + } 77 + http.Redirect(w, r, fmt.Sprintf("/login?error=%s", errorCode), http.StatusFound) 77 78 return 78 79 } 79 80 ··· 95 88 } 96 89 } 97 90 98 - http.Redirect(w, r, "/", http.StatusFound) 91 + redirectURL := "/" 92 + if authReturn.ReturnURL != "" { 93 + redirectURL = authReturn.ReturnURL 94 + } 95 + 96 + http.Redirect(w, r, redirectURL, http.StatusFound) 99 97 } 100 98 101 99 func (o *OAuth) addToDefaultSpindle(did string) {
+66 -4
appview/oauth/oauth.go
··· 98 98 } 99 99 100 100 func (o *OAuth) SaveSession(w http.ResponseWriter, r *http.Request, sessData *oauth.ClientSessionData) error { 101 - // first we save the did in the user session 102 101 userSession, err := o.SessStore.Get(r, SessionName) 103 102 if err != nil { 104 103 return err ··· 107 108 userSession.Values[SessionPds] = sessData.HostURL 108 109 userSession.Values[SessionId] = sessData.SessionID 109 110 userSession.Values[SessionAuthenticated] = true 110 - return userSession.Save(r, w) 111 + 112 + if err := userSession.Save(r, w); err != nil { 113 + return err 114 + } 115 + 116 + handle := "" 117 + resolved, err := o.IdResolver.ResolveIdent(r.Context(), sessData.AccountDID.String()) 118 + if err == nil && resolved.Handle.String() != "" { 119 + handle = resolved.Handle.String() 120 + } 121 + 122 + registry := o.GetAccounts(r) 123 + if err := registry.AddAccount(sessData.AccountDID.String(), handle, sessData.SessionID); err != nil { 124 + return err 125 + } 126 + return o.SaveAccounts(w, r, registry) 111 127 } 112 128 113 129 func (o *OAuth) ResumeSession(r *http.Request) (*oauth.ClientSession, error) { ··· 177 163 return errors.Join(err1, err2) 178 164 } 179 165 166 + func (o *OAuth) SwitchAccount(w http.ResponseWriter, r *http.Request, targetDid string) error { 167 + registry := o.GetAccounts(r) 168 + account := registry.FindAccount(targetDid) 169 + if account == nil { 170 + return fmt.Errorf("account not found in registry: %s", targetDid) 171 + } 172 + 173 + did, err := syntax.ParseDID(targetDid) 174 + if err != nil { 175 + return fmt.Errorf("invalid DID: %w", err) 176 + } 177 + 178 + sess, err := o.ClientApp.ResumeSession(r.Context(), did, account.SessionId) 179 + if err != nil { 180 + registry.RemoveAccount(targetDid) 181 + _ = o.SaveAccounts(w, r, registry) 182 + return fmt.Errorf("session expired for account: %w", err) 183 + } 184 + 185 + userSession, err := o.SessStore.Get(r, SessionName) 186 + if err != nil { 187 + return err 188 + } 189 + 190 + userSession.Values[SessionDid] = sess.Data.AccountDID.String() 191 + userSession.Values[SessionPds] = sess.Data.HostURL 192 + userSession.Values[SessionId] = sess.Data.SessionID 193 + userSession.Values[SessionAuthenticated] = true 194 + 195 + return userSession.Save(r, w) 196 + } 197 + 198 + func (o *OAuth) RemoveAccount(w http.ResponseWriter, r *http.Request, targetDid string) error { 199 + registry := o.GetAccounts(r) 200 + account := registry.FindAccount(targetDid) 201 + if account == nil { 202 + return nil 203 + } 204 + 205 + did, err := syntax.ParseDID(targetDid) 206 + if err == nil { 207 + _ = o.ClientApp.Logout(r.Context(), did, account.SessionId) 208 + } 209 + 210 + registry.RemoveAccount(targetDid) 211 + return o.SaveAccounts(w, r, registry) 212 + } 213 + 180 214 type User struct { 181 215 Did string 182 216 Pds string ··· 243 181 } 244 182 245 183 func (o *OAuth) GetDid(r *http.Request) string { 246 - if u := o.GetUser(r); u != nil { 247 - return u.Did 184 + if u := o.GetMultiAccountUser(r); u != nil { 185 + return u.Did() 248 186 } 249 187 250 188 return ""