2022-07-11 04:40:18 +00:00
|
|
|
package session
|
2022-07-09 05:03:13 +00:00
|
|
|
|
|
|
|
import (
|
2022-07-11 04:40:18 +00:00
|
|
|
"encoding/gob"
|
|
|
|
"errors"
|
2022-07-09 05:03:13 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
|
|
"github.com/gorilla/sessions"
|
|
|
|
"github.com/markbates/goth/gothic"
|
|
|
|
)
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
const (
|
|
|
|
sessionCookie = "_gistea_session"
|
|
|
|
infoKey = "_gistea_info"
|
|
|
|
)
|
2022-07-09 05:03:13 +00:00
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
type Store struct {
|
2022-07-09 05:03:13 +00:00
|
|
|
Store sessions.Store
|
|
|
|
GiteaURL string
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
type Info struct {
|
2022-07-16 04:36:38 +00:00
|
|
|
User string
|
2022-07-11 04:40:18 +00:00
|
|
|
Org string
|
|
|
|
Token string
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
gob.Register(&Info{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Store) RequireAuth(next http.Handler) http.Handler {
|
2022-07-09 05:03:13 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
if _, ok := sess.Values[infoKey]; !ok {
|
2022-07-09 05:03:13 +00:00
|
|
|
gothic.BeginAuthHandler(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
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 {
|
2022-07-09 05:03:13 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
sess.Values[infoKey] = &Info{
|
2022-07-16 04:36:38 +00:00
|
|
|
User: profile.UserName,
|
2022-07-11 04:40:18 +00:00
|
|
|
Org: org,
|
|
|
|
Token: token,
|
2022-07-09 05:03:13 +00:00
|
|
|
}
|
2022-07-11 04:40:18 +00:00
|
|
|
return s.Store.Save(r, w, sess)
|
2022-07-09 05:03:13 +00:00
|
|
|
}
|
|
|
|
|
2022-07-16 04:36:38 +00:00
|
|
|
func (s *Store) Logout(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
sess, err := s.Store.Get(r, sessionCookie)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
sess.Options.MaxAge = -1
|
|
|
|
sess.Values = make(map[any]any)
|
|
|
|
return s.Store.Save(r, w, sess)
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
func (s *Store) Repos(r *http.Request) ([]*gitea.Repository, error) {
|
|
|
|
info, err := s.Info(r)
|
2022-07-09 05:03:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
client, err := gitea.NewClient(s.GiteaURL, gitea.SetToken(info.Token))
|
2022-07-09 05:03:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
repos, _, err := client.ListOrgRepos(info.Org, gitea.ListOrgReposOptions{})
|
2022-07-09 05:03:13 +00:00
|
|
|
return repos, err
|
|
|
|
}
|
|
|
|
|
2022-07-11 04:40:18 +00:00
|
|
|
func NewStore(sessionSecret, giteURL string) *Store {
|
2022-07-09 05:03:13 +00:00
|
|
|
store := sessions.NewCookieStore([]byte(sessionSecret))
|
2022-07-11 04:40:18 +00:00
|
|
|
return &Store{
|
2022-07-09 05:03:13 +00:00
|
|
|
Store: store,
|
|
|
|
GiteaURL: giteURL,
|
|
|
|
}
|
|
|
|
}
|