diff --git a/controllers/index.go b/controllers/index.go index fc9205f..cdf701f 100644 --- a/controllers/index.go +++ b/controllers/index.go @@ -3,14 +3,27 @@ package controllers import ( "net/http" + "git.jamesravey.me/ravenscroftj/indiescrobble/models" "git.jamesravey.me/ravenscroftj/indiescrobble/scrobble" "github.com/gin-gonic/gin" ) func Index(c *gin.Context) { + + // this is an authed endpoint so 'user' must be set and if not panicking is fair + currentUser, exists := c.Get("user") + + var user *models.BaseUser + + if exists { + user = currentUser.(*models.BaseUser) + }else{ + user = nil + } + c.HTML(http.StatusOK, "index.tmpl", gin.H{ - "title": "test", - "user": c.GetString("user"), + "title": "test", + "user": user, "scrobbleTypes": scrobble.ScrobbleTypeNames, }) } diff --git a/controllers/indieauth.go b/controllers/indieauth.go index 92e2878..e7922ca 100644 --- a/controllers/indieauth.go +++ b/controllers/indieauth.go @@ -15,21 +15,22 @@ import ( "github.com/go-chi/jwtauth/v5" "github.com/hacdias/indieauth" "github.com/lestrrat-go/jwx/jwt" + "gorm.io/gorm" ) type IndieAuthManager struct { - iac *indieauth.Client + iac *indieauth.Client jwtAuth *jwtauth.JWTAuth + db *gorm.DB } -func NewIndieAuthManager() *IndieAuthManager{ - +func NewIndieAuthManager(db *gorm.DB) *IndieAuthManager { + config := config.GetConfig() iam := new(IndieAuthManager) iam.iac = indieauth.NewClient(config.GetString("indieauth.clientName"), config.GetString("indieauth.redirectURL"), nil) - - + iam.db = db iam.jwtAuth = jwtauth.New("HS256", []byte(config.GetString("jwt.signKey")), []byte(config.GetString("jwt.signKey"))) return iam @@ -41,27 +42,52 @@ func (iam *IndieAuthManager) GetCurrentUser(c *gin.Context) *models.BaseUser { if err != nil { return nil - }else{ + } else { tok, err := iam.jwtAuth.Decode(jwt) - if err != nil{ + if err != nil { log.Printf("Failed to decode jwt: %v", err) return nil } me, present := tok.Get("user") - if !present{ + if !present { return nil } indietok, present := tok.Get("token") - if !present{ + if !present { return nil } - user := models.BaseUser{Me: me.(string), Token: indietok.(string)} + // see if the user exists in the database or set up their profile + userRecord := models.User{} + result := iam.db.First(&userRecord, models.User{Me: me.(string)}) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + log.Printf("Create new user profile for user %v\n", me) + + // create user record for current user + userRecord = models.User{Me: me.(string)} + userRecord.GenerateRandomKey() + result := iam.db.Create(&userRecord) + + if result.Error != nil { + log.Printf("Failed to create user record in db: %v", result.Error) + return nil + } + + } else { + log.Printf("Failed to get user from db: %v\n", result.Error) + return nil + } + + } + + user := models.BaseUser{Me: me.(string), Token: indietok.(string), UserRecord: &userRecord} return &user @@ -71,7 +97,6 @@ func (iam *IndieAuthManager) GetCurrentUser(c *gin.Context) *models.BaseUser { func (iam *IndieAuthManager) getInformation(c *gin.Context) (*indieauth.AuthInfo, string, error) { - config := config.GetConfig() cookie, err := c.Request.Cookie(config.GetString("indieauth.oauthCookieName")) @@ -166,7 +191,6 @@ func (iam *IndieAuthManager) saveAuthInfo(w http.ResponseWriter, r *http.Request return nil } - func (iam *IndieAuthManager) Logout(c *gin.Context) { // delete the cookie @@ -180,7 +204,7 @@ func (iam *IndieAuthManager) Logout(c *gin.Context) { } http.SetCookie(c.Writer, cookie) - + // redirect back to index c.Redirect(http.StatusSeeOther, "/") @@ -190,7 +214,7 @@ func (iam *IndieAuthManager) IndieAuthLoginPost(c *gin.Context) { err := c.Request.ParseForm() - if err != nil{ + if err != nil { c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ "message": err, }) @@ -227,7 +251,6 @@ func (iam *IndieAuthManager) IndieAuthLoginPost(c *gin.Context) { 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{ @@ -237,12 +260,11 @@ func (iam *IndieAuthManager) IndieAuthLoginPost(c *gin.Context) { } // append me param so the user doesn't have to enter this twice - redirect = fmt.Sprintf("%v&me=%v", redirect, url.QueryEscape(i.Me) ) + 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() @@ -263,7 +285,6 @@ func (iam *IndieAuthManager) LoginCallbackGet(c *gin.Context) { return } - // profile, err := iam.iac.FetchProfile(i, code) // if err != nil { // c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ @@ -272,7 +293,6 @@ func (iam *IndieAuthManager) LoginCallbackGet(c *gin.Context) { // return // } - token, _, err := iam.iac.GetToken(i, code) if err != nil { c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ @@ -283,7 +303,6 @@ func (iam *IndieAuthManager) LoginCallbackGet(c *gin.Context) { me := token.Extra("me").(string) - if err := indieauth.IsValidProfileURL(me); err != nil { err = fmt.Errorf("invalid 'me': %w", err) c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ @@ -299,7 +318,7 @@ func (iam *IndieAuthManager) LoginCallbackGet(c *gin.Context) { jwt.IssuedAtKey: time.Now().Unix(), jwt.ExpirationKey: expiration, "user": me, - "token": token.AccessToken, + "token": token.AccessToken, }) if err != nil { c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ @@ -325,4 +344,4 @@ func (iam *IndieAuthManager) LoginCallbackGet(c *gin.Context) { } c.Redirect(http.StatusSeeOther, redirect) -} \ No newline at end of file +} diff --git a/controllers/scrobble.go b/controllers/scrobble.go index 8d9bf61..7aa08ce 100644 --- a/controllers/scrobble.go +++ b/controllers/scrobble.go @@ -99,7 +99,14 @@ func PreviewScrobble(c *gin.Context){ discovery := micropub.MicropubDiscoveryService{} - discovery.Discover(currentUser.Me, currentUser.Token ) + config, err := discovery.Discover(currentUser.Me, currentUser.Token ) + + if err != nil{ + c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ + "message": err, + }) + return + } c.HTML(http.StatusOK, "preview.tmpl", gin.H{ "user": currentUser, @@ -109,6 +116,7 @@ func PreviewScrobble(c *gin.Context){ "when": c.Request.Form.Get("when"), "rating": c.Request.Form.Get("rating"), "content": c.Request.Form.Get("content"), + "config": config, }) } \ No newline at end of file diff --git a/middlewares/auth.go b/middlewares/auth.go index 986b7db..5df2476 100644 --- a/middlewares/auth.go +++ b/middlewares/auth.go @@ -7,12 +7,10 @@ import ( "github.com/gin-gonic/gin" ) -func AuthMiddleware(requireValidUser bool) gin.HandlerFunc { +func AuthMiddleware(requireValidUser bool, iam *controllers.IndieAuthManager) gin.HandlerFunc { return func(c *gin.Context) { // config := config.GetConfig() - iam := controllers.NewIndieAuthManager() - currentUser := iam.GetCurrentUser(c) if requireValidUser && (currentUser == nil) { @@ -40,4 +38,3 @@ func AuthMiddleware(requireValidUser bool) gin.HandlerFunc { c.Next() } } - diff --git a/server/router.go b/server/router.go index 0a7e778..3e1aeb2 100644 --- a/server/router.go +++ b/server/router.go @@ -5,9 +5,10 @@ import ( "git.jamesravey.me/ravenscroftj/indiescrobble/controllers" "git.jamesravey.me/ravenscroftj/indiescrobble/middlewares" "github.com/gin-gonic/gin" + "gorm.io/gorm" ) -func NewRouter() *gin.Engine { +func NewRouter(db *gorm.DB) *gin.Engine { router := gin.New() router.Use(gin.Logger()) router.Use(gin.Recovery()) @@ -16,12 +17,11 @@ func NewRouter() *gin.Engine { health := new(controllers.HealthController) - iam := controllers.NewIndieAuthManager() - + iam := controllers.NewIndieAuthManager(db) router.GET("/health", health.Status) - router.Use(middlewares.AuthMiddleware(false)) + router.Use(middlewares.AuthMiddleware(false, iam)) router.GET("/", controllers.Index) @@ -33,14 +33,12 @@ func NewRouter() *gin.Engine { router.GET("/auth", iam.LoginCallbackGet) router.GET("/logout", iam.Logout) - authed := router.Use(middlewares.AuthMiddleware(true)) + authed := router.Use(middlewares.AuthMiddleware(true, iam)) // add scrobble endpoints authed.GET("/scrobble", controllers.Scrobble) authed.POST("/scrobble/preview", controllers.PreviewScrobble) - - // v1 := router.Group("v1") // { // userGroup := v1.Group("user") diff --git a/server/server.go b/server/server.go index 10c1846..93e935c 100644 --- a/server/server.go +++ b/server/server.go @@ -15,25 +15,23 @@ import ( func Init() { config := config.GetConfig() - var dialect gorm.Dialector if config.GetString("server.database.driver") == "sqlite" { dialect = sqlite.Open(config.GetString("server.database.dsn")) - }else{ + } else { dialect = mysql.Open(config.GetString("server.database.dsn")) } db, err := gorm.Open(dialect, &gorm.Config{}) - if err != nil{ + if err != nil { log.Fatalf("%v\n", err) } db.AutoMigrate(&models.User{}) - - r := NewRouter() + r := NewRouter(db) r.LoadHTMLGlob("templates/*.tmpl") - r.Run( fmt.Sprintf("%v:%v", config.GetString("server.host"), config.GetString("server.port"))) + r.Run(fmt.Sprintf("%v:%v", config.GetString("server.host"), config.GetString("server.port"))) } diff --git a/templates/footer.tmpl b/templates/footer.tmpl index e69de29..5164d3a 100644 --- a/templates/footer.tmpl +++ b/templates/footer.tmpl @@ -0,0 +1,5 @@ +{{ define "footer.tmpl" }} + +{{end}} \ No newline at end of file diff --git a/templates/index.tmpl b/templates/index.tmpl index 3464ea0..6b3f65a 100644 --- a/templates/index.tmpl +++ b/templates/index.tmpl @@ -6,7 +6,7 @@
{{ if .user }} - Logged in as {{.user}} + Logged in as {{.user.Me}}

Add A Scrobble

@@ -32,5 +32,6 @@ {{ end }}
+ {{ template "footer.tmpl" . }} \ No newline at end of file diff --git a/templates/preview.tmpl b/templates/preview.tmpl index c07df6a..8baa4d0 100644 --- a/templates/preview.tmpl +++ b/templates/preview.tmpl @@ -9,7 +9,7 @@ {{ $scrobbleType := .scrobbleType }} {{ if .user }} - Logged in as {{.user}} + Logged in as {{.user.Me}} {{end}} @@ -38,6 +38,13 @@
{{.content}}
+ {{if .config.SyndicateTargets}} +

Syndication Options

+ {{ range $target := .config.SyndicateTargets}} +
+ {{end}} + {{end}} +
@@ -49,6 +56,7 @@ + {{ template "footer.tmpl" . }} {{end}} \ No newline at end of file diff --git a/templates/scrobble.tmpl b/templates/scrobble.tmpl index 84b423f..a992df1 100644 --- a/templates/scrobble.tmpl +++ b/templates/scrobble.tmpl @@ -80,10 +80,8 @@ {{end}} - - - + {{ template "footer.tmpl" . }} {{end}} \ No newline at end of file