This commit is contained in:
Melon 2022-03-26 00:26:20 +00:00
parent 0a570ff948
commit d217b4d53b
Signed by: melon
GPG Key ID: CAE347AC84024FAE
2 changed files with 94 additions and 25 deletions

View File

@ -26,11 +26,11 @@ type Module struct {
type giteaKeyType int type giteaKeyType int
const ( const (
GITEA_KEY_OAUTH_CLIENT = giteaKeyType(iota) KeyOauthClient = giteaKeyType(iota)
GITEA_KEY_USER KeyUser
GITEA_KEY_STATE KeyState
GITEA_KEY_ACCESS_TOKEN KeyAccessToken
GITEA_KEY_REFRESH_TOKEN KeyRefreshToken
) )
func New() *Module { func New() *Module {
@ -56,7 +56,7 @@ func (m *Module) SetupModule(router *mux.Router, cb func(cb func(http.ResponseWr
func (m *Module) getClient(cb func(http.ResponseWriter, *http.Request, *utils.State, *gitea.Client)) func(rw http.ResponseWriter, req *http.Request) { func (m *Module) getClient(cb func(http.ResponseWriter, *http.Request, *utils.State, *gitea.Client)) func(rw http.ResponseWriter, req *http.Request) {
return m.sessionWrapper(func(rw http.ResponseWriter, req *http.Request, state *utils.State) { return m.sessionWrapper(func(rw http.ResponseWriter, req *http.Request, state *utils.State) {
if v, ok := utils.GetStateValue[*gitea.Client](state, GITEA_KEY_OAUTH_CLIENT); ok { if v, ok := utils.GetStateValue[*gitea.Client](state, KeyOauthClient); ok {
cb(rw, req, state, v) cb(rw, req, state, v)
return return
} }
@ -67,22 +67,50 @@ func (m *Module) getClient(cb func(http.ResponseWriter, *http.Request, *utils.St
func (m *Module) homepage(rw http.ResponseWriter, req *http.Request, state *utils.State, giteaClient *gitea.Client) { func (m *Module) homepage(rw http.ResponseWriter, req *http.Request, state *utils.State, giteaClient *gitea.Client) {
myUser, _, err := giteaClient.GetMyUserInfo() myUser, _, err := giteaClient.GetMyUserInfo()
if err != nil { if err != nil {
state.Del(GITEA_KEY_OAUTH_CLIENT) state.Del(KeyOauthClient)
http.Error(rw, err.Error(), http.StatusInternalServerError) http.Error(rw, err.Error(), http.StatusInternalServerError)
return return
} }
fmt.Println("Username:", myUser.UserName)
orgs, _, err := giteaClient.ListMyOrgs(gitea.ListOrgsOptions{}) orgs, _, err := giteaClient.ListMyOrgs(gitea.ListOrgsOptions{})
if err != nil { if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError) http.Error(rw, err.Error(), http.StatusInternalServerError)
return return
} }
fmt.Println("Orgs:", orgs)
orgSimple := make([]struct{ Name string }, len(orgs)) orgSimple := make([]struct{ Name string }, len(orgs))
for i, j := range orgs { for i, j := range orgs {
orgSimple[i] = struct{ Name string }{j.UserName} orgSimple[i] = struct{ Name string }{j.UserName}
} }
selOrg := ""
repoSimple := make([]struct{ Name string }, 0)
selRepo := ""
refSimple := make([]struct{ Name string }, 0)
q := req.URL.Query()
if q.Has("org") {
selOrg = q.Get("org")
repos, _, err := giteaClient.ListOrgRepos(selOrg, gitea.ListOrgReposOptions{ListOptions: gitea.ListOptions{Page: 0, PageSize: 100}})
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
repoSimple = make([]struct{ Name string }, len(repos))
for i, j := range repos {
repoSimple[i] = struct{ Name string }{Name: j.Name}
}
if q.Has("repo") {
selRepo = q.Get("repo")
refs, _, err := giteaClient.GetRepoRefs(selOrg, selRepo, "heads")
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
refSimple = make([]struct{ Name string }, len(refs))
for i, ref := range refs {
refSimple[i] = struct{ Name string }{Name: ref.Ref}
}
}
}
tmp, err := template.New("homepage").Parse(indexTemplate) tmp, err := template.New("homepage").Parse(indexTemplate)
if err != nil { if err != nil {
@ -91,12 +119,20 @@ func (m *Module) homepage(rw http.ResponseWriter, req *http.Request, state *util
} }
err = tmp.Execute(rw, struct { err = tmp.Execute(rw, struct {
Username string Username string
Orgs []struct { Orgs []struct{ Name string }
Name string Repos []struct{ Name string }
} SelOrg string
ShowOrg bool
SelRepo string
ShowRepo bool
}{ }{
Username: myUser.UserName, Username: myUser.UserName,
Orgs: orgSimple, Orgs: orgSimple,
Repos: repoSimple,
SelOrg: selOrg,
SelRepo: selRepo,
ShowOrg: selOrg != "",
ShowRepo: selRepo != "",
}) })
if err != nil { if err != nil {
fmt.Println("Template execute error:", err) fmt.Println("Template execute error:", err)
@ -105,14 +141,14 @@ func (m *Module) homepage(rw http.ResponseWriter, req *http.Request, state *util
} }
func (m *Module) loginPage(rw http.ResponseWriter, req *http.Request, state *utils.State) { func (m *Module) loginPage(rw http.ResponseWriter, req *http.Request, state *utils.State) {
if myUser, ok := utils.GetStateValue[*string](state, GITEA_KEY_USER); ok { if myUser, ok := utils.GetStateValue[*string](state, KeyUser); ok {
if myUser != nil { if myUser != nil {
http.Redirect(rw, req, "/gitea", http.StatusTemporaryRedirect) http.Redirect(rw, req, "/gitea", http.StatusTemporaryRedirect)
return return
} }
} }
if flowState, ok := utils.GetStateValue[uuid.UUID](state, GITEA_KEY_STATE); ok { if flowState, ok := utils.GetStateValue[uuid.UUID](state, KeyState); ok {
q := req.URL.Query() q := req.URL.Query()
if q.Has("code") && q.Has("state") { if q.Has("code") && q.Has("state") {
if q.Get("state") == flowState.String() { if q.Get("state") == flowState.String() {
@ -126,7 +162,9 @@ func (m *Module) loginPage(rw http.ResponseWriter, req *http.Request, state *uti
fmt.Println("Create client error:", err) fmt.Println("Create client error:", err)
return return
} }
state.Put(GITEA_KEY_OAUTH_CLIENT, c) state.Put(KeyOauthClient, c)
state.Put(KeyAccessToken, exchange.AccessToken)
state.Put(KeyRefreshToken, exchange.RefreshToken)
http.Redirect(rw, req, "/gitea", http.StatusTemporaryRedirect) http.Redirect(rw, req, "/gitea", http.StatusTemporaryRedirect)
return return
} }
@ -136,7 +174,7 @@ func (m *Module) loginPage(rw http.ResponseWriter, req *http.Request, state *uti
} }
flowState := uuid.New() flowState := uuid.New()
state.Put(GITEA_KEY_STATE, flowState) state.Put(KeyState, flowState)
http.Redirect(rw, req, m.oauthClient.AuthCodeURL(flowState.String(), oauth2.AccessTypeOffline), http.StatusTemporaryRedirect) http.Redirect(rw, req, m.oauthClient.AuthCodeURL(flowState.String(), oauth2.AccessTypeOffline), http.StatusTemporaryRedirect)
} }

View File

@ -2,17 +2,48 @@
<html> <html>
<head> <head>
<title>Gitea | Melon Tools</title> <title>Gitea | Melon Tools</title>
<style>
.page-content {
display: flex;
flex-direction: row;
align-items: flex-start;
}
</style>
</head> </head>
<body> <body>
<h1>Gitea | Melon Tools</h1> <h1>Gitea | Melon Tools</h1>
<div> <div class="page-content">
<div>
<p>Select repository source:</p> <p>Select repository source:</p>
<ul> <ul>
<li>{{.Username}} (my user account)</li> <li>
<a href="?org={{.Username}}">{{.Username}} (my user account)</a>
</li>
{{range .Orgs}} {{range .Orgs}}
<li>{{.Name}}</li> <li>
<a href="?org={{.Name}}">{{.Name}}</a>
</li>
{{end}} {{end}}
</ul> </ul>
</div>
{{if .ShowOrg}}
<div>
<p>Select repository:</p>
<ul>
{{range .Repos}}
<li>
<a href="?org={{$.SelOrg}}&repo={{.Name}}">{{$.SelOrg}}/{{.Name}}</a>
</li>
{{end}}
</ul>
</div>
{{end}}
{{if .ShowRepo}}
<div>
<p>Repository details:</p>
<p>Go import: go get {{.SelRepo.Full}}</p>
</div>
{{end}}
</div> </div>
</body> </body>
</html> </html>