diff --git a/ui/controllers/auth.go b/ui/controllers/auth.go index 0051d58..a56f7d8 100644 --- a/ui/controllers/auth.go +++ b/ui/controllers/auth.go @@ -70,11 +70,17 @@ func SignUpHandler (c *gin.Context) { return } + now := time.Now().Unix() + exp := time.Now().Add(12 * time.Hour).Unix() //build jwt token := jwt.NewWithClaims(jwt.SigningMethodHS256, - jwt.MapClaims{ - "sub": user.UserId, - "exp": time.Now().Add(12 * time.Hour).Unix(), + AuthClaims{ + Subject: user.UserId, + Expires: exp, + IssuedAt: now, + NotBefore: now, + Issuer: "capstone.preston-baxter.com", + Audience: "capstone.preston-baxter.com", }, ) @@ -132,11 +138,17 @@ func LoginHandler(c *gin.Context) { return } + now := time.Now().Unix() + exp := time.Now().Add(12 * time.Hour).Unix() //build jwt token := jwt.NewWithClaims(jwt.SigningMethodHS256, - jwt.MapClaims{ - "sub": user.UserId, - "exp": time.Now().Add(12 * time.Hour).Unix(), + AuthClaims{ + Subject: user.UserId, + Expires: exp, + IssuedAt: now, + NotBefore: now, + Issuer: "capstone.preston-baxter.com", + Audience: "capstone.preston-baxter.com", }, ) diff --git a/ui/controllers/auth_middleware.go b/ui/controllers/auth_middleware.go new file mode 100644 index 0000000..1595007 --- /dev/null +++ b/ui/controllers/auth_middleware.go @@ -0,0 +1,107 @@ +package controllers + +import ( + "net/http" + "time" + + "git.preston-baxter.com/Preston_PLB/capstone/frontend-service/config" + "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" +) + +type AuthClaims struct { + Subject string `json:"sub"` + Expires int64 `json:"exp"` + IssuedAt int64 `json:"iat"` + NotBefore int64 `json:"nbf"` + Issuer string `json:"iss"` + Audience string `json:"aud"` +} + +func (claims AuthClaims) GetExpirationTime() (*jwt.NumericDate, error) { + time := time.Unix(claims.Expires, 0) + return jwt.NewNumericDate(time), nil +} + +func (claims AuthClaims) GetIssuedAt() (*jwt.NumericDate, error) { + time := time.Unix(claims.IssuedAt, 0) + return jwt.NewNumericDate(time), nil +} + +func (claims AuthClaims) GetNotBefore() (*jwt.NumericDate, error) { + time := time.Unix(claims.NotBefore, 0) + return jwt.NewNumericDate(time), nil +} + +func (claims AuthClaims) GetIssuer() (string, error) { + return claims.Issuer, nil +} + +func (claims AuthClaims) GetSubject() (string, error) { + return claims.Subject, nil +} + +func (claims AuthClaims) GetAudience() (jwt.ClaimStrings, error) { + return []string{claims.Subject}, nil +} + +func AuthMiddleware(strict bool) gin.HandlerFunc { + conf := config.Config() + return func(c *gin.Context) { + //check for cookie + token, err := c.Cookie("authorization") + if err != nil { + if err == http.ErrNoCookie { + if strict { + c.Redirect(301, "/login") + return + } else { + return + } + } else { + log.WithError(err).Error("Unable to get cookie from browser") + c.AbortWithError(504, err) + return + } + } + + claims := &AuthClaims{} + + parsedToken, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (any, error) { + return []byte(conf.JwtSecret), nil + }) + if err != nil { + if err == jwt.ErrSignatureInvalid { + log.Warn("Redirecting, jwt invalid") + c.Redirect(301, "/login") + return + } + log.WithError(err).Error("Unable to get cookie from browser") + c.AbortWithError(504, err) + return + } + if !parsedToken.Valid { + if strict { + log.Warn("Redirecting, jwt invalid") + c.Redirect(301, "/login") + return + } else { + log.Warn("Jwt is invalid, but auth is not strict") + return + } + } + + user, err := mongo.FindUserById(claims.Subject) + if err != nil { + log.WithError(err).Errorf("Unable to get user: %s from DB", claims.Subject) + c.AbortWithError(504, err) + } + + if user == nil { + log.Errorf("Unable to find user: %s in DB", claims.Subject) + c.AbortWithError(504, nil) + } + + c.Set("UserObj", user) + } +} diff --git a/ui/controllers/controllers.go b/ui/controllers/controllers.go index 010c9c1..429886d 100644 --- a/ui/controllers/controllers.go +++ b/ui/controllers/controllers.go @@ -3,7 +3,6 @@ package controllers import ( "git.preston-baxter.com/Preston_PLB/capstone/frontend-service/config" "git.preston-baxter.com/Preston_PLB/capstone/frontend-service/db" - "git.preston-baxter.com/Preston_PLB/capstone/frontend-service/middleware" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) @@ -25,16 +24,16 @@ func BuildRouter(r *gin.Engine) { ForceColors: true, }) - r.GET("/", middleware.AuthMiddleware(false) ,LandingPage) - r.GET("/login", middleware.AuthMiddleware(false), LoginPage) - r.GET("/signup", middleware.AuthMiddleware(false), SignUpPage) + r.GET("/", LandingPage) + r.GET("/login", AuthMiddleware(false), LoginPage) + r.GET("/signup",AuthMiddleware(false), SignUpPage) r.POST("/login", LoginHandler) r.POST("/signup", SignUpHandler) r.POST("/logout", LogoutHandler) dashboard := r.Group("/dashboard") - dashboard.Use(middleware.AuthMiddleware(true)) + dashboard.Use(AuthMiddleware(true)) dashboard.GET("/", DashboardPage) } diff --git a/ui/middleware/auth.go b/ui/middleware/auth.go deleted file mode 100644 index b1642a7..0000000 --- a/ui/middleware/auth.go +++ /dev/null @@ -1,34 +0,0 @@ -package middleware - -import ( - //"git.preston-baxter.com/Preston_PLB/capstone/frontend-service/config" - "github.com/gin-gonic/gin" -) - -func AuthMiddleware(strict bool) gin.HandlerFunc { - //conf := config.Config(); - return func(c *gin.Context) { - //check for cookie - - /* - no cookie: - if strict - route login - else: - continue with nil auth_user - */ - - /* - cookie: - validate jwt: - if valid: - set context with auth_user - else: - if strict - route login - else: - continue with nil auth_user - - */ - } -}