oauth: add gitlab

This commit is contained in:
Adhityaa Chandrasekar 2019-02-22 21:54:08 -05:00
parent c07f3e8b9f
commit 3e5c1c2656
8 changed files with 183 additions and 1 deletions

4
api/Gopkg.lock generated
View File

@ -124,11 +124,12 @@
[[projects]]
branch = "master"
digest = "1:82e6e4dc5ab71680d89684e4649be630fdeeaf81feb8e88e4a56273a0cd4d966"
digest = "1:341ceeee37101c62dae441691406bf4ecc71bbeb7b424417879fe88d9f88f487"
name = "golang.org/x/oauth2"
packages = [
".",
"github",
"gitlab",
"google",
"internal",
"jws",
@ -173,6 +174,7 @@
"golang.org/x/net/html",
"golang.org/x/oauth2",
"golang.org/x/oauth2/github",
"golang.org/x/oauth2/gitlab",
"golang.org/x/oauth2/google",
]
solver-name = "gps-cdcl"

View File

@ -53,6 +53,9 @@ func configParse() error {
"TWITTER_KEY": "",
"TWITTER_SECRET": "",
"GITLAB_KEY": "",
"GITLAB_SECRET": "",
}
for key, value := range defaults {

View File

@ -19,5 +19,9 @@ func oauthConfigure() error {
return err
}
if err := gitlabOauthConfigure(); err != nil {
return err
}
return nil
}

42
api/oauth_gitlab.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/gitlab"
"os"
)
var gitlabConfig *oauth2.Config
func gitlabOauthConfigure() error {
gitlabConfig = nil
if os.Getenv("GITLAB_KEY") == "" && os.Getenv("GITLAB_SECRET") == "" {
return nil
}
if os.Getenv("GITLAB_KEY") == "" {
logger.Errorf("COMMENTO_GITLAB_KEY not configured, but COMMENTO_GITLAB_SECRET is set")
return errorOauthMisconfigured
}
if os.Getenv("GITLAB_SECRET") == "" {
logger.Errorf("COMMENTO_GITLAB_SECRET not configured, but COMMENTO_GITLAB_KEY is set")
return errorOauthMisconfigured
}
logger.Infof("loading gitlab OAuth config")
gitlabConfig = &oauth2.Config{
RedirectURL: os.Getenv("ORIGIN") + "/api/oauth/gitlab/callback",
ClientID: os.Getenv("GITLAB_KEY"),
ClientSecret: os.Getenv("GITLAB_SECRET"),
Scopes: []string{
"read_user",
},
Endpoint: gitlab.Endpoint,
}
configuredOauths = append(configuredOauths, "gitlab")
return nil
}

View File

@ -0,0 +1,96 @@
package main
import (
"encoding/json"
"fmt"
"golang.org/x/oauth2"
"io/ioutil"
"net/http"
)
func gitlabCallbackHandler(w http.ResponseWriter, r *http.Request) {
commenterToken := r.FormValue("state")
code := r.FormValue("code")
_, err := commenterGetByCommenterToken(commenterToken)
if err != nil && err != errorNoSuchToken {
fmt.Fprintf(w, "Error: %s\n", err.Error())
return
}
token, err := gitlabConfig.Exchange(oauth2.NoContext, code)
if err != nil {
fmt.Fprintf(w, "Error: %s", err.Error())
return
}
resp, err := http.Get("https://gitlab.com/api/v4/user?access_token=" + token.AccessToken)
if err != nil {
fmt.Fprintf(w, "Error: %s", err.Error())
return
}
logger.Infof("%v", resp.StatusCode)
defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(w, "Error: %s", errorCannotReadResponse.Error())
return
}
user := make(map[string]interface{})
if err := json.Unmarshal(contents, &user); err != nil {
fmt.Fprintf(w, "Error: %s", errorInternal.Error())
return
}
if user["email"] == nil {
fmt.Fprintf(w, "Error: no email address returned by Gitlab")
return
}
email := user["email"].(string)
if user["name"] == nil {
fmt.Fprintf(w, "Error: no name returned by Gitlab")
return
}
name := user["name"].(string)
link := "undefined"
if user["web_url"] != nil {
link = user["web_url"].(string)
}
photo := "undefined"
if user["avatar_url"] != nil {
photo = user["avatar_url"].(string)
}
c, err := commenterGetByEmail("gitlab", email)
if err != nil && err != errorNoSuchCommenter {
fmt.Fprintf(w, "Error: %s", err.Error())
return
}
var commenterHex string
// TODO: in case of returning users, update the information we have on record?
if err == errorNoSuchCommenter {
commenterHex, err = commenterNew(email, name, link, photo, "gitlab", "")
if err != nil {
fmt.Fprintf(w, "Error: %s", err.Error())
return
}
} else {
commenterHex = c.CommenterHex
}
if err := commenterSessionUpdate(commenterToken, commenterHex); err != nil {
fmt.Fprintf(w, "Error: %s", err.Error())
return
}
fmt.Fprintf(w, "<html><script>window.parent.close()</script></html>")
}

View File

@ -0,0 +1,25 @@
package main
import (
"fmt"
"net/http"
)
func gitlabRedirectHandler(w http.ResponseWriter, r *http.Request) {
if gitlabConfig == nil {
logger.Errorf("gitlab oauth access attempt without configuration")
fmt.Fprintf(w, "error: this website has not configured gitlab OAuth")
return
}
commenterToken := r.FormValue("commenterToken")
_, err := commenterGetByCommenterToken(commenterToken)
if err != nil && err != errorNoSuchToken {
fmt.Fprintf(w, "error: %s\n", err.Error())
return
}
url := gitlabConfig.AuthCodeURL(commenterToken)
http.Redirect(w, r, url, http.StatusFound)
}

View File

@ -41,6 +41,9 @@ func apiRouterInit(router *mux.Router) error {
router.HandleFunc("/api/oauth/twitter/redirect", twitterRedirectHandler).Methods("GET")
router.HandleFunc("/api/oauth/twitter/callback", twitterCallbackHandler).Methods("GET")
router.HandleFunc("/api/oauth/gitlab/redirect", gitlabRedirectHandler).Methods("GET")
router.HandleFunc("/api/oauth/gitlab/callback", gitlabCallbackHandler).Methods("GET")
router.HandleFunc("/api/comment/new", commentNewHandler).Methods("POST")
router.HandleFunc("/api/comment/list", commentListHandler).Methods("POST")
router.HandleFunc("/api/comment/count", commentCountHandler).Methods("POST")

View File

@ -32,5 +32,12 @@
font-size: 13px;
width: 70px;
}
.commento-gitlab-button {
background: #fc6d26;
text-transform: uppercase;
font-size: 13px;
width: 70px;
}
}
}