forked from tangled.org/core
this repo has no description
1package state 2 3import ( 4 "net/http" 5 "strings" 6 7 "github.com/go-chi/chi/v5" 8 "github.com/gorilla/sessions" 9 "tangled.sh/tangled.sh/core/appview/issues" 10 "tangled.sh/tangled.sh/core/appview/middleware" 11 oauthhandler "tangled.sh/tangled.sh/core/appview/oauth/handler" 12 "tangled.sh/tangled.sh/core/appview/pipelines" 13 "tangled.sh/tangled.sh/core/appview/pulls" 14 "tangled.sh/tangled.sh/core/appview/repo" 15 "tangled.sh/tangled.sh/core/appview/settings" 16 "tangled.sh/tangled.sh/core/appview/spindles" 17 "tangled.sh/tangled.sh/core/appview/state/userutil" 18 "tangled.sh/tangled.sh/core/log" 19) 20 21func (s *State) Router() http.Handler { 22 router := chi.NewRouter() 23 middleware := middleware.New( 24 s.oauth, 25 s.db, 26 s.enforcer, 27 s.repoResolver, 28 s.idResolver, 29 s.pages, 30 ) 31 32 router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) { 33 pat := chi.URLParam(r, "*") 34 if strings.HasPrefix(pat, "did:") || strings.HasPrefix(pat, "@") { 35 s.UserRouter(&middleware).ServeHTTP(w, r) 36 } else { 37 // Check if the first path element is a valid handle without '@' or a flattened DID 38 pathParts := strings.SplitN(pat, "/", 2) 39 if len(pathParts) > 0 { 40 if userutil.IsHandleNoAt(pathParts[0]) { 41 // Redirect to the same path but with '@' prefixed to the handle 42 redirectPath := "@" + pat 43 http.Redirect(w, r, "/"+redirectPath, http.StatusFound) 44 return 45 } else if userutil.IsFlattenedDid(pathParts[0]) { 46 // Redirect to the unflattened DID version 47 unflattenedDid := userutil.UnflattenDid(pathParts[0]) 48 var redirectPath string 49 if len(pathParts) > 1 { 50 redirectPath = unflattenedDid + "/" + pathParts[1] 51 } else { 52 redirectPath = unflattenedDid 53 } 54 http.Redirect(w, r, "/"+redirectPath, http.StatusFound) 55 return 56 } 57 } 58 s.StandardRouter(&middleware).ServeHTTP(w, r) 59 } 60 }) 61 62 return router 63} 64 65func (s *State) UserRouter(mw *middleware.Middleware) http.Handler { 66 r := chi.NewRouter() 67 68 // strip @ from user 69 r.Use(middleware.StripLeadingAt) 70 71 r.With(mw.ResolveIdent()).Route("/{user}", func(r chi.Router) { 72 r.Get("/", s.Profile) 73 74 r.With(mw.ResolveRepo()).Route("/{repo}", func(r chi.Router) { 75 r.Use(mw.GoImport()) 76 77 r.Mount("/", s.RepoRouter(mw)) 78 r.Mount("/issues", s.IssuesRouter(mw)) 79 r.Mount("/pulls", s.PullsRouter(mw)) 80 r.Mount("/pipelines", s.PipelinesRouter(mw)) 81 82 // These routes get proxied to the knot 83 r.Get("/info/refs", s.InfoRefs) 84 r.Post("/git-upload-pack", s.UploadPack) 85 r.Post("/git-receive-pack", s.ReceivePack) 86 87 }) 88 }) 89 90 r.NotFound(func(w http.ResponseWriter, r *http.Request) { 91 s.pages.Error404(w) 92 }) 93 94 return r 95} 96 97func (s *State) StandardRouter(mw *middleware.Middleware) http.Handler { 98 r := chi.NewRouter() 99 100 r.Handle("/static/*", s.pages.Static()) 101 102 r.Get("/", s.Timeline) 103 104 r.Route("/knots", func(r chi.Router) { 105 r.Use(middleware.AuthMiddleware(s.oauth)) 106 r.Get("/", s.Knots) 107 r.Post("/key", s.RegistrationKey) 108 109 r.Route("/{domain}", func(r chi.Router) { 110 r.Post("/init", s.InitKnotServer) 111 r.Get("/", s.KnotServerInfo) 112 r.Route("/member", func(r chi.Router) { 113 r.Use(mw.KnotOwner()) 114 r.Get("/", s.ListMembers) 115 r.Put("/", s.AddMember) 116 r.Delete("/", s.RemoveMember) 117 }) 118 }) 119 }) 120 121 r.Route("/repo", func(r chi.Router) { 122 r.Route("/new", func(r chi.Router) { 123 r.Use(middleware.AuthMiddleware(s.oauth)) 124 r.Get("/", s.NewRepo) 125 r.Post("/", s.NewRepo) 126 }) 127 // r.Post("/import", s.ImportRepo) 128 }) 129 130 r.With(middleware.AuthMiddleware(s.oauth)).Route("/follow", func(r chi.Router) { 131 r.Post("/", s.Follow) 132 r.Delete("/", s.Follow) 133 }) 134 135 r.With(middleware.AuthMiddleware(s.oauth)).Route("/star", func(r chi.Router) { 136 r.Post("/", s.Star) 137 r.Delete("/", s.Star) 138 }) 139 140 r.With(middleware.AuthMiddleware(s.oauth)).Route("/react", func(r chi.Router) { 141 r.Post("/", s.React) 142 r.Delete("/", s.React) 143 }) 144 145 r.Route("/profile", func(r chi.Router) { 146 r.Use(middleware.AuthMiddleware(s.oauth)) 147 r.Get("/edit-bio", s.EditBioFragment) 148 r.Get("/edit-pins", s.EditPinsFragment) 149 r.Post("/bio", s.UpdateProfileBio) 150 r.Post("/pins", s.UpdateProfilePins) 151 }) 152 153 r.Mount("/settings", s.SettingsRouter()) 154 r.Mount("/spindles", s.SpindlesRouter()) 155 r.Mount("/", s.OAuthRouter()) 156 157 r.Get("/keys/{user}", s.Keys) 158 159 r.NotFound(func(w http.ResponseWriter, r *http.Request) { 160 s.pages.Error404(w) 161 }) 162 return r 163} 164 165func (s *State) OAuthRouter() http.Handler { 166 store := sessions.NewCookieStore([]byte(s.config.Core.CookieSecret)) 167 oauth := oauthhandler.New(s.config, s.pages, s.idResolver, s.db, s.sess, store, s.oauth, s.enforcer, s.posthog) 168 return oauth.Router() 169} 170 171func (s *State) SettingsRouter() http.Handler { 172 settings := &settings.Settings{ 173 Db: s.db, 174 OAuth: s.oauth, 175 Pages: s.pages, 176 Config: s.config, 177 } 178 179 return settings.Router() 180} 181 182func (s *State) SpindlesRouter() http.Handler { 183 logger := log.New("spindles") 184 185 spindles := &spindles.Spindles{ 186 Db: s.db, 187 OAuth: s.oauth, 188 Pages: s.pages, 189 Config: s.config, 190 Enforcer: s.enforcer, 191 IdResolver: s.idResolver, 192 Logger: logger, 193 } 194 195 return spindles.Router() 196} 197 198func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler { 199 issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog) 200 return issues.Router(mw) 201 202} 203 204func (s *State) PullsRouter(mw *middleware.Middleware) http.Handler { 205 pulls := pulls.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog) 206 return pulls.Router(mw) 207} 208 209func (s *State) RepoRouter(mw *middleware.Middleware) http.Handler { 210 repo := repo.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.posthog, s.enforcer) 211 return repo.Router(mw) 212} 213 214func (s *State) PipelinesRouter(mw *middleware.Middleware) http.Handler { 215 pipes := pipelines.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.posthog, s.enforcer) 216 return pipes.Router(mw) 217}