package session import ( "encoding/gob" "errors" "fmt" "net/http" "code.gitea.io/sdk/gitea" "github.com/gorilla/sessions" "github.com/markbates/goth/gothic" ) const ( sessionCookie = "_gistea_session" infoKey = "_gistea_info" ) type Store struct { Store sessions.Store GiteaURL string } type Info struct { Org string Token string } func init() { gob.Register(&Info{}) } func (s *Store) RequireAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { sess, err := s.Store.Get(r, sessionCookie) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if _, ok := sess.Values[infoKey]; !ok { gothic.BeginAuthHandler(w, r) return } next.ServeHTTP(w, r) }) } func (s *Store) Info(r *http.Request) (*Info, error) { sess, err := s.Store.Get(r, sessionCookie) if err != nil { return nil, err } if infoAny, ok := sess.Values[infoKey]; ok { if info, ok := infoAny.(*Info); ok { return info, nil } } return nil, errors.New("could not get session info") } func (s *Store) HasAuth(r *http.Request) bool { i, _ := s.Info(r) return i != nil } func (s *Store) CompleteAuth(w http.ResponseWriter, r *http.Request, token string) error { client, err := gitea.NewClient(s.GiteaURL, gitea.SetToken(token)) if err != nil { return err } profile, _, err := client.GetMyUserInfo() if err != nil { return err } org := fmt.Sprintf("%s-gists", profile.UserName) _, resp, err := client.GetOrg(org) if err != nil { if resp != nil && resp.StatusCode == http.StatusNotFound { if _, _, err := client.CreateOrg(gitea.CreateOrgOption{ Name: org, Visibility: gitea.VisibleTypePublic, }); err != nil { return err } } else { return err } } sess, err := s.Store.New(r, sessionCookie) if err != nil { return err } sess.Values[infoKey] = &Info{ Org: org, Token: token, } return s.Store.Save(r, w, sess) } func (s *Store) Repos(r *http.Request) ([]*gitea.Repository, error) { info, err := s.Info(r) if err != nil { return nil, err } client, err := gitea.NewClient(s.GiteaURL, gitea.SetToken(info.Token)) if err != nil { return nil, err } repos, _, err := client.ListOrgRepos(info.Org, gitea.ListOrgReposOptions{}) return repos, err } func NewStore(sessionSecret, giteURL string) *Store { store := sessions.NewCookieStore([]byte(sessionSecret)) return &Store{ Store: store, GiteaURL: giteURL, } }