feat: allow access token expiration to be set in the config
This commit is contained in:
parent
f16cceb0e1
commit
a8b3809515
@ -52,12 +52,12 @@ func (r *ErrMalformedToken) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewAccessToken generates a new JWT access token with the correct claims
|
// NewAccessToken generates a new JWT access token with the correct claims
|
||||||
func NewAccessToken(userID string, restrictedMode RestrictedMode, orgRole string, jwtKey []byte) (string, error) {
|
func NewAccessToken(userID string, restrictedMode RestrictedMode, orgRole string, jwtKey []byte, expirationTime time.Duration) (string, error) {
|
||||||
role := RoleMember
|
role := RoleMember
|
||||||
if orgRole == "admin" {
|
if orgRole == "admin" {
|
||||||
role = RoleAdmin
|
role = RoleAdmin
|
||||||
}
|
}
|
||||||
accessExpirationTime := time.Now().Add(5 * time.Second)
|
accessExpirationTime := time.Now().Add(expirationTime)
|
||||||
accessClaims := &AccessTokenClaims{
|
accessClaims := &AccessTokenClaims{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
Restricted: restrictedMode,
|
Restricted: restrictedMode,
|
||||||
|
@ -80,6 +80,7 @@ func Execute() {
|
|||||||
viper.SetDefault("database.user", "taskcafe")
|
viper.SetDefault("database.user", "taskcafe")
|
||||||
viper.SetDefault("database.password", "taskcafe_test")
|
viper.SetDefault("database.password", "taskcafe_test")
|
||||||
viper.SetDefault("database.port", "5432")
|
viper.SetDefault("database.port", "5432")
|
||||||
|
viper.SetDefault("security.token_expiration", "15m")
|
||||||
|
|
||||||
viper.SetDefault("queue.broker", "amqp://guest:guest@localhost:5672/")
|
viper.SetDefault("queue.broker", "amqp://guest:guest@localhost:5672/")
|
||||||
viper.SetDefault("queue.store", "memcache://localhost:11211")
|
viper.SetDefault("queue.store", "memcache://localhost:11211")
|
||||||
|
@ -76,6 +76,7 @@ func newWebCmd() *cobra.Command {
|
|||||||
log.Warn("server.secret is not set, generating a random secret")
|
log.Warn("server.secret is not set, generating a random secret")
|
||||||
secret = uuid.New().String()
|
secret = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
security, err := utils.GetSecurityConfig(viper.GetString("security.token_expiration"), []byte(secret))
|
||||||
r, _ := route.NewRouter(db, utils.EmailConfig{
|
r, _ := route.NewRouter(db, utils.EmailConfig{
|
||||||
From: viper.GetString("smtp.from"),
|
From: viper.GetString("smtp.from"),
|
||||||
Host: viper.GetString("smtp.host"),
|
Host: viper.GetString("smtp.host"),
|
||||||
@ -83,7 +84,7 @@ func newWebCmd() *cobra.Command {
|
|||||||
Username: viper.GetString("smtp.username"),
|
Username: viper.GetString("smtp.username"),
|
||||||
Password: viper.GetString("smtp.password"),
|
Password: viper.GetString("smtp.password"),
|
||||||
InsecureSkipVerify: viper.GetBool("smtp.skip_verify"),
|
InsecureSkipVerify: viper.GetBool("smtp.skip_verify"),
|
||||||
}, []byte(secret))
|
}, security)
|
||||||
return http.ListenAndServe(viper.GetString("server.hostname"), r)
|
return http.ListenAndServe(viper.GetString("server.hostname"), r)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ func (h *TaskcafeHandler) RefreshTokenHandler(w http.ResponseWriter, r *http.Req
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Info("here 1")
|
log.Info("here 1")
|
||||||
accessTokenString, err := auth.NewAccessToken(token.UserID.String(), auth.Unrestricted, user.RoleCode, h.jwtKey)
|
accessTokenString, err := auth.NewAccessToken(token.UserID.String(), auth.Unrestricted, user.RoleCode, h.SecurityConfig.Secret, h.SecurityConfig.AccessTokenExpiration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -220,7 +220,7 @@ func (h *TaskcafeHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
refreshExpiresAt := refreshCreatedAt.AddDate(0, 0, 1)
|
refreshExpiresAt := refreshCreatedAt.AddDate(0, 0, 1)
|
||||||
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
||||||
|
|
||||||
accessTokenString, err := auth.NewAccessToken(user.UserID.String(), auth.Unrestricted, user.RoleCode, h.jwtKey)
|
accessTokenString, err := auth.NewAccessToken(user.UserID.String(), auth.Unrestricted, user.RoleCode, h.SecurityConfig.Secret, h.SecurityConfig.AccessTokenExpiration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ func (h *TaskcafeHandler) InstallHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
||||||
|
|
||||||
log.WithField("userID", user.UserID.String()).Info("creating install access token")
|
log.WithField("userID", user.UserID.String()).Info("creating install access token")
|
||||||
accessTokenString, err := auth.NewAccessToken(user.UserID.String(), auth.Unrestricted, user.RoleCode, h.jwtKey)
|
accessTokenString, err := auth.NewAccessToken(user.UserID.String(), auth.Unrestricted, user.RoleCode, h.SecurityConfig.Secret, h.SecurityConfig.AccessTokenExpiration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@ -386,7 +386,7 @@ func (h *TaskcafeHandler) ConfirmUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
refreshExpiresAt := refreshCreatedAt.AddDate(0, 0, 1)
|
refreshExpiresAt := refreshCreatedAt.AddDate(0, 0, 1)
|
||||||
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
||||||
|
|
||||||
accessTokenString, err := auth.NewAccessToken(user.UserID.String(), auth.Unrestricted, user.RoleCode, h.jwtKey)
|
accessTokenString, err := auth.NewAccessToken(user.UserID.String(), auth.Unrestricted, user.RoleCode, h.SecurityConfig.Secret, h.SecurityConfig.AccessTokenExpiration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
@ -60,12 +60,12 @@ func (h FrontendHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// TaskcafeHandler contains all the route handlers
|
// TaskcafeHandler contains all the route handlers
|
||||||
type TaskcafeHandler struct {
|
type TaskcafeHandler struct {
|
||||||
repo db.Repository
|
repo db.Repository
|
||||||
jwtKey []byte
|
SecurityConfig utils.SecurityConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter creates a new router for chi
|
// NewRouter creates a new router for chi
|
||||||
func NewRouter(dbConnection *sqlx.DB, emailConfig utils.EmailConfig, jwtKey []byte) (chi.Router, error) {
|
func NewRouter(dbConnection *sqlx.DB, emailConfig utils.EmailConfig, securityConfig utils.SecurityConfig) (chi.Router, error) {
|
||||||
formatter := new(log.TextFormatter)
|
formatter := new(log.TextFormatter)
|
||||||
formatter.TimestampFormat = "02-01-2006 15:04:05"
|
formatter.TimestampFormat = "02-01-2006 15:04:05"
|
||||||
formatter.FullTimestamp = true
|
formatter.FullTimestamp = true
|
||||||
@ -81,7 +81,7 @@ func NewRouter(dbConnection *sqlx.DB, emailConfig utils.EmailConfig, jwtKey []by
|
|||||||
r.Use(middleware.Timeout(60 * time.Second))
|
r.Use(middleware.Timeout(60 * time.Second))
|
||||||
|
|
||||||
repository := db.NewRepository(dbConnection)
|
repository := db.NewRepository(dbConnection)
|
||||||
taskcafeHandler := TaskcafeHandler{*repository, jwtKey}
|
taskcafeHandler := TaskcafeHandler{*repository, securityConfig}
|
||||||
|
|
||||||
var imgServer = http.FileServer(http.Dir("./uploads/"))
|
var imgServer = http.FileServer(http.Dir("./uploads/"))
|
||||||
r.Group(func(mux chi.Router) {
|
r.Group(func(mux chi.Router) {
|
||||||
@ -91,7 +91,7 @@ func NewRouter(dbConnection *sqlx.DB, emailConfig utils.EmailConfig, jwtKey []by
|
|||||||
mux.Post("/auth/confirm", taskcafeHandler.ConfirmUser)
|
mux.Post("/auth/confirm", taskcafeHandler.ConfirmUser)
|
||||||
mux.Post("/auth/register", taskcafeHandler.RegisterUser)
|
mux.Post("/auth/register", taskcafeHandler.RegisterUser)
|
||||||
})
|
})
|
||||||
auth := AuthenticationMiddleware{jwtKey}
|
auth := AuthenticationMiddleware{securityConfig.Secret}
|
||||||
r.Group(func(mux chi.Router) {
|
r.Group(func(mux chi.Router) {
|
||||||
mux.Use(auth.Middleware)
|
mux.Use(auth.Middleware)
|
||||||
mux.Post("/users/me/avatar", taskcafeHandler.ProfileImageUpload)
|
mux.Post("/users/me/avatar", taskcafeHandler.ProfileImageUpload)
|
||||||
|
21
internal/utils/security.go
Normal file
21
internal/utils/security.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SecurityConfig struct {
|
||||||
|
AccessTokenExpiration time.Duration
|
||||||
|
Secret []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSecurityConfig(accessTokenExp string, secret []byte) (SecurityConfig, error) {
|
||||||
|
exp, err := time.ParseDuration(accessTokenExp)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("issue parsing duration")
|
||||||
|
return SecurityConfig{}, err
|
||||||
|
}
|
||||||
|
return SecurityConfig{AccessTokenExpiration: exp, Secret: secret}, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user