this repo has no description
1package state 2 3import ( 4 "log" 5 "net/http" 6 "time" 7 8 comatproto "github.com/bluesky-social/indigo/api/atproto" 9 "github.com/bluesky-social/indigo/xrpc" 10 "github.com/go-chi/chi/v5" 11 "github.com/sotangled/tangled/appview" 12 "github.com/sotangled/tangled/appview/auth" 13) 14 15type Middleware func(http.Handler) http.Handler 16 17func AuthMiddleware(s *State) Middleware { 18 return func(next http.Handler) http.Handler { 19 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 20 session, _ := s.auth.Store.Get(r, appview.SessionName) 21 authorized, ok := session.Values[appview.SessionAuthenticated].(bool) 22 if !ok || !authorized { 23 log.Printf("not logged in, redirecting") 24 http.Redirect(w, r, "/login", http.StatusTemporaryRedirect) 25 return 26 } 27 28 // refresh if nearing expiry 29 // TODO: dedup with /login 30 expiryStr := session.Values[appview.SessionExpiry].(string) 31 expiry, err := time.Parse(appview.TimeLayout, expiryStr) 32 if err != nil { 33 log.Println("invalid expiry time", err) 34 return 35 } 36 pdsUrl := session.Values[appview.SessionPds].(string) 37 did := session.Values[appview.SessionDid].(string) 38 refreshJwt := session.Values[appview.SessionRefreshJwt].(string) 39 40 if time.Now().After(expiry) { 41 log.Println("token expired, refreshing ...") 42 43 client := xrpc.Client{ 44 Host: pdsUrl, 45 Auth: &xrpc.AuthInfo{ 46 Did: did, 47 AccessJwt: refreshJwt, 48 RefreshJwt: refreshJwt, 49 }, 50 } 51 atSession, err := comatproto.ServerRefreshSession(r.Context(), &client) 52 if err != nil { 53 log.Println(err) 54 return 55 } 56 57 sessionish := auth.RefreshSessionWrapper{atSession} 58 59 err = s.auth.StoreSession(r, w, &sessionish, pdsUrl) 60 if err != nil { 61 log.Printf("failed to store session for did: %s\n: %s", atSession.Did, err) 62 return 63 } 64 65 log.Println("successfully refreshed token") 66 } 67 68 next.ServeHTTP(w, r) 69 }) 70 } 71} 72 73func RoleMiddleware(s *State, group string) Middleware { 74 return func(next http.Handler) http.Handler { 75 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 76 // requires auth also 77 actor := s.auth.GetUser(r) 78 if actor == nil { 79 // we need a logged in user 80 log.Printf("not logged in, redirecting") 81 http.Error(w, "Forbiden", http.StatusUnauthorized) 82 return 83 } 84 domain := chi.URLParam(r, "domain") 85 if domain == "" { 86 http.Error(w, "malformed url", http.StatusBadRequest) 87 return 88 } 89 90 ok, err := s.enforcer.E.HasGroupingPolicy(actor.Did, group, domain) 91 if err != nil || !ok { 92 // we need a logged in user 93 log.Printf("%s does not have perms of a %s in domain %s", actor.Did, group, domain) 94 http.Error(w, "Forbiden", http.StatusUnauthorized) 95 return 96 } 97 98 next.ServeHTTP(w, r) 99 }) 100 } 101}