got auth flow working with indieauth
This commit is contained in:
parent
2d551b4e37
commit
53ef48df37
|
@ -14,12 +14,25 @@ var config *viper.Viper
|
||||||
func Init(env string) {
|
func Init(env string) {
|
||||||
var err error
|
var err error
|
||||||
config = viper.New()
|
config = viper.New()
|
||||||
|
|
||||||
|
config.SetDefault("indieauth.clientName", "https://indiescrobble.club")
|
||||||
|
config.SetDefault("indieauth.redirectURL", "http://localhost:3000/auth")
|
||||||
|
config.SetDefault("indieauth.oauthSubject", "IndieScrobble OAuth Client")
|
||||||
|
config.SetDefault("indieauth.oauthCookieName","indiescrobble-oauth")
|
||||||
|
config.SetDefault("indieauth.sessionSubject", "IndieScrobble Session")
|
||||||
|
|
||||||
config.SetConfigType("yaml")
|
config.SetConfigType("yaml")
|
||||||
config.SetConfigName(env)
|
config.SetConfigName(env)
|
||||||
config.AddConfigPath("../config/")
|
config.AddConfigPath("../config/")
|
||||||
config.AddConfigPath("config/")
|
config.AddConfigPath("config/")
|
||||||
|
|
||||||
err = config.ReadInConfig()
|
err = config.ReadInConfig()
|
||||||
|
|
||||||
|
if config.GetString("jwt.signKey") == ""{
|
||||||
|
log.Fatal("You must set a JWT sign key (jwt.signKey in config yaml)")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
config.BindEnv("server.port","PORT")
|
config.BindEnv("server.port","PORT")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
server:
|
server:
|
||||||
port: ":8081"
|
port: ":8081"
|
||||||
|
|
||||||
static_path: ./static
|
static_path: ./static
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
signKey: "profiteroles"
|
||||||
|
verifyKey: "topSecret"
|
|
@ -1,20 +1,286 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.jamesravey.me/ravenscroftj/indiescrobble/config"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-chi/jwtauth/v5"
|
||||||
|
"github.com/hacdias/indieauth"
|
||||||
|
"github.com/lestrrat-go/jwx/jwt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type IndieAuthManager struct {
|
||||||
|
iac *indieauth.Client
|
||||||
|
jwtAuth *jwtauth.JWTAuth
|
||||||
|
}
|
||||||
|
|
||||||
func IndieAuthLoginPost(c *gin.Context) {
|
func NewIndieAuthManager() *IndieAuthManager{
|
||||||
|
|
||||||
|
config := config.GetConfig()
|
||||||
|
|
||||||
|
iam := new(IndieAuthManager)
|
||||||
|
iam.iac = indieauth.NewClient(config.GetString("indieauth.clientName"), config.GetString("indieauth.redirectURL"), nil)
|
||||||
|
|
||||||
|
|
||||||
|
iam.jwtAuth = jwtauth.New("HS256", []byte(config.GetString("jwt.signKey")), []byte(config.GetString("jwt.signKey")))
|
||||||
|
|
||||||
|
return iam
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iam *IndieAuthManager) GetCurrentUser(c *gin.Context) string {
|
||||||
|
|
||||||
|
jwt, err := c.Cookie("jwt")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}else{
|
||||||
|
tok, err := iam.jwtAuth.Decode(jwt)
|
||||||
|
|
||||||
|
if err != nil{
|
||||||
|
log.Printf("Failed to decode jwt: %v", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
val, present := tok.Get("user")
|
||||||
|
|
||||||
|
if present {
|
||||||
|
return fmt.Sprintf("%v", val)
|
||||||
|
}else{
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iam *IndieAuthManager) getInformation(c *gin.Context) (*indieauth.AuthInfo, string, error) {
|
||||||
|
|
||||||
|
|
||||||
|
config := config.GetConfig()
|
||||||
|
|
||||||
|
cookie, err := c.Request.Cookie(config.GetString("indieauth.oauthCookieName"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := jwtauth.VerifyToken(iam.jwtAuth, cookie.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = jwt.Validate(token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if token.Subject() != config.GetString("indieauth.oauthSubject") {
|
||||||
|
return nil, "", errors.New("invalid subject for oauth token")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, ok := token.Get("data")
|
||||||
|
if !ok || data == nil {
|
||||||
|
return nil, "", errors.New("cannot find 'data' property in token")
|
||||||
|
}
|
||||||
|
|
||||||
|
dataStr, ok := data.(string)
|
||||||
|
if !ok || dataStr == "" {
|
||||||
|
return nil, "", errors.New("cannot find 'data' property in token")
|
||||||
|
}
|
||||||
|
|
||||||
|
var i *indieauth.AuthInfo
|
||||||
|
err = json.Unmarshal([]byte(dataStr), &i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete cookie
|
||||||
|
http.SetCookie(c.Writer, &http.Cookie{
|
||||||
|
Name: config.GetString("indieauth.oauthCookieName"),
|
||||||
|
MaxAge: -1,
|
||||||
|
Secure: c.Request.URL.Scheme == "https",
|
||||||
|
Path: "/",
|
||||||
|
HttpOnly: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
redirect, ok := token.Get("redirect")
|
||||||
|
if !ok {
|
||||||
|
return i, "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
redirectStr, ok := redirect.(string)
|
||||||
|
if !ok || redirectStr == "" {
|
||||||
|
return i, "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return i, redirectStr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iam *IndieAuthManager) saveAuthInfo(w http.ResponseWriter, r *http.Request, i *indieauth.AuthInfo) error {
|
||||||
|
data, err := json.Marshal(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config := config.GetConfig()
|
||||||
|
|
||||||
|
expiration := time.Now().Add(time.Minute * 10)
|
||||||
|
|
||||||
|
_, signed, err := iam.jwtAuth.Encode(map[string]interface{}{
|
||||||
|
jwt.SubjectKey: config.GetString("indieauth.oauthSubject"),
|
||||||
|
jwt.IssuedAtKey: time.Now().Unix(),
|
||||||
|
jwt.ExpirationKey: expiration,
|
||||||
|
"data": string(data),
|
||||||
|
"redirect": r.URL.Query().Get("redirect"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: config.GetString("indieauth.oauthCookieName"),
|
||||||
|
Value: string(signed),
|
||||||
|
Expires: expiration,
|
||||||
|
Secure: r.URL.Scheme == "https",
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
SameSite: http.SameSiteLaxMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
http.SetCookie(w, cookie)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (iam *IndieAuthManager) IndieAuthLoginPost(c *gin.Context) {
|
||||||
|
|
||||||
err := c.Request.ParseForm()
|
err := c.Request.ParseForm()
|
||||||
|
|
||||||
if err != nil{
|
if err != nil{
|
||||||
c.HTML(http.StatusBadRequest, "error.html", gin.H{
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
"message": err,
|
"message": err,
|
||||||
})
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r := c.Request
|
||||||
|
|
||||||
|
profile := r.FormValue("domain")
|
||||||
|
if profile == "" {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": "Empty domain",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = indieauth.CanonicalizeURL(profile)
|
||||||
|
if err := indieauth.IsValidProfileURL(profile); err != nil {
|
||||||
|
err = fmt.Errorf("invalid profile url: %w", err)
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
i, redirect, err := iam.iac.Authenticate(profile, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("profile: %v\n", i)
|
||||||
|
|
||||||
|
|
||||||
|
err = iam.saveAuthInfo(c.Writer, c.Request, i)
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// append me param so the user doesn't have to enter this twice
|
||||||
|
redirect = fmt.Sprintf("%v&me=%v", redirect, url.QueryEscape(i.Me) )
|
||||||
|
|
||||||
|
c.Redirect(http.StatusSeeOther, redirect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (iam *IndieAuthManager) LoginCallbackGet(c *gin.Context) {
|
||||||
|
|
||||||
|
config := config.GetConfig()
|
||||||
|
|
||||||
|
i, redirect, err := iam.getInformation(c)
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
code, err := iam.iac.ValidateCallback(i, c.Request)
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
profile, err := iam.iac.FetchProfile(i, code)
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := indieauth.IsValidProfileURL(profile.Me); err != nil {
|
||||||
|
err = fmt.Errorf("invalid 'me': %w", err)
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
expiration := time.Now().Add(time.Hour * 24 * 7)
|
||||||
|
|
||||||
|
_, signed, err := iam.jwtAuth.Encode(map[string]interface{}{
|
||||||
|
jwt.SubjectKey: config.GetString("indieauth.sessionSubject"),
|
||||||
|
jwt.IssuedAtKey: time.Now().Unix(),
|
||||||
|
jwt.ExpirationKey: expiration,
|
||||||
|
"user": profile.Me,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
|
||||||
|
"message": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: "jwt",
|
||||||
|
Value: string(signed),
|
||||||
|
Expires: expiration,
|
||||||
|
Secure: c.Request.URL.Scheme == "https",
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
SameSite: http.SameSiteLaxMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
http.SetCookie(c.Writer, cookie)
|
||||||
|
|
||||||
|
if redirect == "" {
|
||||||
|
redirect = "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Redirect(http.StatusSeeOther, redirect)
|
||||||
|
}
|
1
go.mod
1
go.mod
|
@ -11,6 +11,7 @@ require (
|
||||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/gin-gonic/gin v1.7.7 // indirect
|
github.com/gin-gonic/gin v1.7.7 // indirect
|
||||||
|
github.com/go-chi/jwtauth/v5 v5.0.2 // indirect
|
||||||
github.com/go-playground/locales v0.14.0 // indirect
|
github.com/go-playground/locales v0.14.0 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.10.0 // indirect
|
github.com/go-playground/validator/v10 v10.10.0 // indirect
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -73,6 +73,9 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
|
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
|
||||||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
|
github.com/go-chi/jwtauth/v5 v5.0.2 h1:CSKtr+b6Jnfy5T27sMaiBPxaVE/bjnjS3ramFQ0526w=
|
||||||
|
github.com/go-chi/jwtauth/v5 v5.0.2/go.mod h1:TeA7vmPe3uYThvHw8O8W13HOOpOd4MTgToxL41gZyjs=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
@ -86,6 +89,7 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
|
||||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||||
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
||||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||||
|
github.com/goccy/go-json v0.7.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/goccy/go-json v0.9.4 h1:L8MLKG2mvVXiQu07qB6hmfqeSYQdOnqPot2GhsIwIaI=
|
github.com/goccy/go-json v0.9.4 h1:L8MLKG2mvVXiQu07qB6hmfqeSYQdOnqPot2GhsIwIaI=
|
||||||
github.com/goccy/go-json v0.9.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.9.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
@ -176,10 +180,12 @@ github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf
|
||||||
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
|
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
|
||||||
github.com/lestrrat-go/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4=
|
github.com/lestrrat-go/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4=
|
||||||
github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
|
github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
|
||||||
|
github.com/lestrrat-go/codegen v1.0.1/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM=
|
||||||
github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc=
|
github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc=
|
||||||
github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE=
|
github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE=
|
||||||
github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A=
|
github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A=
|
||||||
github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
|
github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
|
||||||
|
github.com/lestrrat-go/jwx v1.2.6/go.mod h1:tJuGuAI3LC71IicTx82Mz1n3w9woAs2bYJZpkjJQ5aU=
|
||||||
github.com/lestrrat-go/jwx v1.2.18 h1:RV4hcTRUlPVYUnGqATKXEojoOsLexoU8Na4KheVzxQ8=
|
github.com/lestrrat-go/jwx v1.2.18 h1:RV4hcTRUlPVYUnGqATKXEojoOsLexoU8Na4KheVzxQ8=
|
||||||
github.com/lestrrat-go/jwx v1.2.18/go.mod h1:bWTBO7IHHVMtNunM8so9MT8wD+euEY1PzGEyCnuI2qM=
|
github.com/lestrrat-go/jwx v1.2.18/go.mod h1:bWTBO7IHHVMtNunM8so9MT8wD+euEY1PzGEyCnuI2qM=
|
||||||
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
|
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
|
||||||
|
@ -448,11 +454,13 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||||
|
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
@ -1,30 +1,38 @@
|
||||||
package middlewares
|
package middlewares
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"fmt"
|
||||||
|
|
||||||
"git.jamesravey.me/ravenscroftj/indiescrobble/config"
|
"git.jamesravey.me/ravenscroftj/indiescrobble/controllers"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AuthMiddleware() gin.HandlerFunc {
|
func AuthMiddleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
config := config.GetConfig()
|
// config := config.GetConfig()
|
||||||
reqKey := c.Request.Header.Get("X-Auth-Key")
|
|
||||||
reqSecret := c.Request.Header.Get("X-Auth-Secret")
|
|
||||||
|
|
||||||
var key string
|
iam := controllers.NewIndieAuthManager()
|
||||||
var secret string
|
|
||||||
if key = config.GetString("http.auth.key"); len(strings.TrimSpace(key)) == 0 {
|
|
||||||
c.AbortWithStatus(500)
|
|
||||||
}
|
fmt.Printf("Current user: %v\n", iam.GetCurrentUser(c))
|
||||||
if secret = config.GetString("http.auth.secret"); len(strings.TrimSpace(secret)) == 0 {
|
|
||||||
c.AbortWithStatus(401)
|
// reqKey := c.Request.Header.Get("X-Auth-Key")
|
||||||
}
|
// reqSecret := c.Request.Header.Get("X-Auth-Secret")
|
||||||
if key != reqKey || secret != reqSecret {
|
|
||||||
c.AbortWithStatus(401)
|
// var key string
|
||||||
return
|
// var secret string
|
||||||
}
|
// if key = config.GetString("http.auth.key"); len(strings.TrimSpace(key)) == 0 {
|
||||||
|
// c.AbortWithStatus(500)
|
||||||
|
// }
|
||||||
|
// if secret = config.GetString("http.auth.secret"); len(strings.TrimSpace(secret)) == 0 {
|
||||||
|
// c.AbortWithStatus(401)
|
||||||
|
// }
|
||||||
|
// if key != reqKey || secret != reqSecret {
|
||||||
|
// c.AbortWithStatus(401)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,22 @@ func NewRouter() *gin.Engine {
|
||||||
|
|
||||||
health := new(controllers.HealthController)
|
health := new(controllers.HealthController)
|
||||||
|
|
||||||
|
iam := controllers.NewIndieAuthManager()
|
||||||
|
|
||||||
|
|
||||||
router.GET("/health", health.Status)
|
router.GET("/health", health.Status)
|
||||||
|
|
||||||
|
router.Use(middlewares.AuthMiddleware())
|
||||||
|
|
||||||
router.GET("/", controllers.Index)
|
router.GET("/", controllers.Index)
|
||||||
|
|
||||||
router.Static("/static", config.GetString("server.static_path"))
|
router.Static("/static", config.GetString("server.static_path"))
|
||||||
|
|
||||||
|
router.POST("/indieauth", iam.IndieAuthLoginPost)
|
||||||
|
router.GET("/auth", iam.LoginCallbackGet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
router.Use(middlewares.AuthMiddleware())
|
|
||||||
|
|
||||||
// v1 := router.Group("v1")
|
// v1 := router.Group("v1")
|
||||||
// {
|
// {
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
{{ template "head.tmpl" . }}
|
||||||
<link rel="stylesheet" href="/static/css/simple-v1.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
{{ template "header.tmpl" . }}
|
||||||
<h1>
|
|
||||||
IndieScrobble
|
|
||||||
</h1>
|
|
||||||
</header>
|
|
||||||
<main>
|
<main>
|
||||||
<p>{{ .message }}</p>
|
<h2>Error</h2>
|
||||||
|
{{ .message }}
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,6 @@
|
||||||
|
{{ define "head.tmpl" }}
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="/static/css/simple-v1.css" />
|
||||||
|
<title>IndieScrobble</title>
|
||||||
|
</head>
|
||||||
|
{{end}}
|
|
@ -1,13 +1,22 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
{{ template "head.tmpl" . }}
|
||||||
<link rel="stylesheet" href="/static/css/simple-v1.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
{{ template "header.tmpl" . }}
|
{{ template "header.tmpl" . }}
|
||||||
<main>
|
<main>
|
||||||
<p>Welcome to indiescrobble! IndieScrobble is a <a href="https://micropub.spec.indieweb.org/">MicroPub</a> compliant tool
|
<p>Welcome to indiescrobble! IndieScrobble is a <a href="https://micropub.spec.indieweb.org/">MicroPub</a> compliant tool
|
||||||
for posting about your watches, reads and scrobbles directly back to your site.</p>
|
for posting about your watches, reads and scrobbles directly back to your site.</p>
|
||||||
|
|
||||||
|
{{ if index . "user" }}
|
||||||
|
{{else}}
|
||||||
|
<form action="/indieauth" method="POST">
|
||||||
|
<p>
|
||||||
|
<label>Your domain: </label>
|
||||||
|
<input type="text" name="domain"/>
|
||||||
|
<button type="submit">Log in</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
{{ end }}
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue