2021-09-03 16:47:37 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-09-16 08:09:51 +08:00
|
|
|
"encoding/json"
|
2021-09-03 16:47:37 +08:00
|
|
|
"fmt"
|
|
|
|
"html/template"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/gorilla/sessions"
|
|
|
|
"github.com/markbates/goth"
|
|
|
|
"github.com/markbates/goth/gothic"
|
|
|
|
"github.com/markbates/goth/providers/gitea"
|
|
|
|
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2023-02-05 14:34:48 +01:00
|
|
|
serviceName = "teabag"
|
2021-09-03 16:47:37 +08:00
|
|
|
msgTemplate = `<!DOCTYPE html><html><head></head><body>{{.}}</body></html>`
|
2021-09-16 08:09:51 +08:00
|
|
|
resTemplate = `
|
|
|
|
<!DOCTYPE html><html><head></head><body>
|
|
|
|
<script>
|
|
|
|
function recieveMsg(e) {
|
|
|
|
window.opener.postMessage("{{.OAuthResult}}", e.origin);
|
|
|
|
}
|
|
|
|
window.addEventListener("message", recieveMsg, false);
|
|
|
|
window.opener.postMessage("{{.Provider}}", "*");
|
|
|
|
</script>
|
|
|
|
</body></html>`
|
2021-09-03 16:47:37 +08:00
|
|
|
|
|
|
|
log *logrus.Entry
|
|
|
|
config *viper.Viper
|
|
|
|
)
|
|
|
|
|
|
|
|
func initConfig() {
|
|
|
|
config = viper.New()
|
2023-02-05 14:34:48 +01:00
|
|
|
config.SetConfigType("env")
|
|
|
|
config.SetConfigName("teabag")
|
|
|
|
config.AddConfigPath("./env/")
|
|
|
|
config.AddConfigPath("/etc/teabag/")
|
|
|
|
config.SetEnvPrefix("teabag")
|
2021-09-03 16:47:37 +08:00
|
|
|
config.AutomaticEnv()
|
|
|
|
|
|
|
|
if err := config.ReadInConfig(); err != nil {
|
2023-02-05 14:34:48 +01:00
|
|
|
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
|
|
|
log.Infoln("config file not found, falling back to evironment variables")
|
|
|
|
} else {
|
|
|
|
log.Fatalf("error loading configuration: %v", err)
|
|
|
|
}
|
2021-09-03 16:47:37 +08:00
|
|
|
}
|
2023-02-05 14:34:48 +01:00
|
|
|
|
2021-09-03 16:47:37 +08:00
|
|
|
}
|
|
|
|
|
2023-02-05 14:34:48 +01:00
|
|
|
func initProvider() {
|
2021-09-03 16:47:37 +08:00
|
|
|
var (
|
|
|
|
providers []goth.Provider
|
|
|
|
)
|
|
|
|
|
|
|
|
type settings struct {
|
2021-09-16 08:09:51 +08:00
|
|
|
key, secret, BaseURL, CallbackURL, AuthURI, AccessTokenURI, UserURI string
|
2021-09-03 16:47:37 +08:00
|
|
|
}
|
|
|
|
|
2023-02-05 14:34:48 +01:00
|
|
|
log.Info("initialising provider")
|
2021-09-03 16:47:37 +08:00
|
|
|
|
|
|
|
getProviderSetings := func(name string) settings {
|
2023-02-05 14:34:48 +01:00
|
|
|
baseURL := config.GetString(name + "_base_url")
|
2021-09-03 16:47:37 +08:00
|
|
|
return settings{
|
2023-02-05 14:34:48 +01:00
|
|
|
key: config.GetString(name + "_key"),
|
|
|
|
secret: config.GetString(name + "_secret"),
|
2021-09-16 08:09:51 +08:00
|
|
|
BaseURL: baseURL,
|
2023-02-05 14:34:48 +01:00
|
|
|
AuthURI: fmt.Sprintf("%s/%s", baseURL, config.GetString(name+"_auth_uri")),
|
|
|
|
AccessTokenURI: fmt.Sprintf("%s/%s", baseURL, config.GetString(name+"_token_uri")),
|
|
|
|
UserURI: fmt.Sprintf("%s/%s", baseURL, config.GetString(name+"_user_uri")),
|
|
|
|
CallbackURL: config.GetString("callback_uri"),
|
2021-09-03 16:47:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-05 14:34:48 +01:00
|
|
|
log.Info("- adding gitea connector")
|
|
|
|
var p goth.Provider
|
|
|
|
s := getProviderSetings("gitea")
|
|
|
|
if s.AuthURI != "" {
|
|
|
|
out, _ := json.MarshalIndent(s, "", " ")
|
|
|
|
log.Infof("-- with custom settings %s", string(out))
|
|
|
|
p = gitea.NewCustomisedURL(s.key, s.secret, s.CallbackURL, s.AuthURI, s.AccessTokenURI, s.UserURI)
|
|
|
|
} else {
|
|
|
|
p = gitea.New(s.key, s.secret, s.CallbackURL)
|
2021-09-03 16:47:37 +08:00
|
|
|
}
|
2023-02-05 14:34:48 +01:00
|
|
|
providers = append(providers, p)
|
2021-09-03 16:47:37 +08:00
|
|
|
|
2023-02-05 14:34:48 +01:00
|
|
|
gothic.Store = sessions.NewCookieStore([]byte(config.GetString("session_secret")))
|
2021-09-03 16:47:37 +08:00
|
|
|
goth.UseProviders(providers...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
log = logrus.New().WithFields(logrus.Fields{
|
|
|
|
"service": serviceName,
|
|
|
|
})
|
|
|
|
log.Info("starting up service")
|
|
|
|
|
|
|
|
initConfig()
|
2023-02-05 14:34:48 +01:00
|
|
|
initProvider()
|
2021-09-03 16:47:37 +08:00
|
|
|
|
|
|
|
r := mux.NewRouter()
|
|
|
|
|
|
|
|
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
t, _ := template.New("msg").Parse(msgTemplate)
|
|
|
|
t.Execute(w, fmt.Sprintf("Connected to %s", serviceName))
|
|
|
|
})
|
|
|
|
|
2023-02-05 14:34:48 +01:00
|
|
|
r.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
|
2021-09-03 16:47:37 +08:00
|
|
|
user, err := gothic.CompleteUserAuth(w, r)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("callback: CompleteUserAuth failed %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-02-05 14:34:48 +01:00
|
|
|
log.Infoln("logged in user to gitea")
|
2021-09-16 08:09:51 +08:00
|
|
|
t, _ := template.New("res").Parse(resTemplate)
|
2021-09-03 16:47:37 +08:00
|
|
|
|
2021-09-16 08:09:51 +08:00
|
|
|
data := struct {
|
|
|
|
Provider string
|
|
|
|
OAuthResult string
|
|
|
|
}{
|
2023-02-05 14:34:48 +01:00
|
|
|
Provider: fmt.Sprintf(`authorizing:gitea`),
|
|
|
|
OAuthResult: fmt.Sprintf(`authorization:gitea:%s:{"token":"%s", "provider":"%s"}`, "success", user.AccessToken, user.Provider),
|
2021-09-16 08:09:51 +08:00
|
|
|
}
|
|
|
|
t.Execute(w, data)
|
2021-09-03 16:47:37 +08:00
|
|
|
}).Methods("GET")
|
|
|
|
|
|
|
|
r.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
|
2023-02-05 14:34:48 +01:00
|
|
|
log.Infoln("handling auth provider request for gitea")
|
2021-09-16 08:09:51 +08:00
|
|
|
|
2021-09-03 16:47:37 +08:00
|
|
|
if gothUser, err := gothic.CompleteUserAuth(w, r); err == nil {
|
|
|
|
t, _ := template.New("msg").Parse(msgTemplate)
|
|
|
|
t.Execute(w, fmt.Sprintf("Connected to existing session with UserID '%s'", gothUser.UserID))
|
|
|
|
} else {
|
|
|
|
gothic.BeginAuthHandler(w, r)
|
|
|
|
}
|
|
|
|
}).Methods("GET")
|
|
|
|
|
2023-02-05 14:34:48 +01:00
|
|
|
r.HandleFunc("/logout", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
log.Infoln("logout from gitea")
|
2021-09-16 08:09:51 +08:00
|
|
|
|
2021-09-03 16:47:37 +08:00
|
|
|
gothic.Logout(w, r)
|
|
|
|
w.Header().Set("Location", "/")
|
|
|
|
w.WriteHeader(http.StatusTemporaryRedirect)
|
|
|
|
}).Methods("GET")
|
|
|
|
|
|
|
|
http.Handle("/", r)
|
|
|
|
|
|
|
|
log.Infof("listening on %s:%d",
|
2023-02-05 14:34:48 +01:00
|
|
|
config.GetString("host"),
|
|
|
|
config.GetInt("port"),
|
2021-09-03 16:47:37 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
srv := &http.Server{
|
|
|
|
Handler: r,
|
2023-02-05 14:34:48 +01:00
|
|
|
Addr: net.JoinHostPort(config.GetString("host"), config.GetString("port")),
|
2021-09-03 16:47:37 +08:00
|
|
|
WriteTimeout: 15 * time.Second,
|
|
|
|
ReadTimeout: 15 * time.Second,
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Fatal(srv.ListenAndServe())
|
|
|
|
}
|