Skip to content

Commit

Permalink
Leverage Mattress | Refactor Config (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettladley authored Feb 6, 2024
1 parent ddb0145 commit 1405dc1
Show file tree
Hide file tree
Showing 22 changed files with 420 additions and 196 deletions.
8 changes: 7 additions & 1 deletion backend/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/GenerateNU/sac/backend

go 1.21.1
go 1.21.6

require (
github.com/go-playground/validator/v10 v10.17.0
Expand All @@ -13,6 +13,11 @@ require (
gorm.io/gorm v1.25.6
)

require (
github.com/awnumar/memcall v0.2.0 // indirect
github.com/awnumar/memguard v0.22.4 // indirect
)

require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
Expand All @@ -21,6 +26,7 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/garrettladley/mattress v0.2.0
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/spec v0.20.4 // indirect
Expand Down
7 changes: 7 additions & 0 deletions backend/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/awnumar/memcall v0.2.0 h1:sRaogqExTOOkkNwO9pzJsL8jrOV29UuUW7teRMfbqtI=
github.com/awnumar/memcall v0.2.0/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo=
github.com/awnumar/memguard v0.22.4 h1:1PLgKcgGPeExPHL8dCOWGVjIbQUBgJv9OL0F/yE1PqQ=
github.com/awnumar/memguard v0.22.4/go.mod h1:+APmZGThMBWjnMlKiSM1X7MVpbIVewen2MTkqWkA/zE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -17,6 +21,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/garrettladley/mattress v0.2.0 h1:+XUdsv9NO2s4JL+8exvAFziw0b1kv/0WlQo2Dlxat+w=
github.com/garrettladley/mattress v0.2.0/go.mod h1:OWKIRc9wC3gtD3Ng/nUuNEiR1TJvRYLmn/KZYw9nl5Q=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
Expand Down Expand Up @@ -153,6 +159,7 @@ golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
49 changes: 25 additions & 24 deletions backend/src/auth/tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ import (
"github.com/GenerateNU/sac/backend/src/errors"
"github.com/GenerateNU/sac/backend/src/types"

m "github.com/garrettladley/mattress"
"github.com/gofiber/fiber/v2"
"github.com/golang-jwt/jwt"
)

func CreateTokenPair(id string, role string, authSettings config.AuthSettings) (*string, *string, *errors.Error) {
accessToken, catErr := CreateAccessToken(id, role, authSettings.AccessTokenExpiry, authSettings.AccessToken)
accessToken, catErr := CreateAccessToken(id, role, authSettings.AccessTokenExpiry, authSettings.AccessKey)
if catErr != nil {
return nil, nil, catErr
}

refreshToken, crtErr := CreateRefreshToken(id, authSettings.RefreshTokenExpiry, authSettings.RefreshToken)
refreshToken, crtErr := CreateRefreshToken(id, authSettings.RefreshTokenExpiry, authSettings.RefreshKey)
if crtErr != nil {
return nil, nil, crtErr
}
Expand All @@ -26,7 +27,7 @@ func CreateTokenPair(id string, role string, authSettings config.AuthSettings) (
}

// CreateAccessToken creates a new access token for the user
func CreateAccessToken(id string, role string, accessExpiresAfter uint, accessTokenSecret string) (*string, *errors.Error) {
func CreateAccessToken(id string, role string, accessExpiresAfter uint, accessToken *m.Secret[string]) (*string, *errors.Error) {
if id == "" || role == "" {
return nil, &errors.FailedToCreateAccessToken
}
Expand All @@ -40,16 +41,16 @@ func CreateAccessToken(id string, role string, accessExpiresAfter uint, accessTo
Role: role,
})

accessToken, err := SignToken(accessTokenClaims, accessTokenSecret)
returnedAccessToken, err := SignToken(accessTokenClaims, accessToken)
if err != nil {
return nil, err
}

return accessToken, nil
return returnedAccessToken, nil
}

// CreateRefreshToken creates a new refresh token for the user
func CreateRefreshToken(id string, refreshExpiresAfter uint, refreshTokenSecret string) (*string, *errors.Error) {
func CreateRefreshToken(id string, refreshExpiresAfter uint, refreshKey *m.Secret[string]) (*string, *errors.Error) {
if id == "" {
return nil, &errors.FailedToCreateRefreshToken
}
Expand All @@ -60,20 +61,20 @@ func CreateRefreshToken(id string, refreshExpiresAfter uint, refreshTokenSecret
ExpiresAt: time.Now().Add(time.Hour * 24 * time.Duration(refreshExpiresAfter)).Unix(),
})

refreshToken, err := SignToken(refreshTokenClaims, refreshTokenSecret)
returnedRefreshToken, err := SignToken(refreshTokenClaims, refreshKey)
if err != nil {
return nil, err
}

return refreshToken, nil
return returnedRefreshToken, nil
}

func SignToken(token *jwt.Token, secret string) (*string, *errors.Error) {
if token == nil || secret == "" {
func SignToken(token *jwt.Token, key *m.Secret[string]) (*string, *errors.Error) {
if token == nil || key.Expose() == "" {
return nil, &errors.FailedToSignToken
}

tokenString, err := token.SignedString([]byte(secret))
tokenString, err := token.SignedString([]byte(key.Expose()))
if err != nil {
return nil, &errors.FailedToSignToken
}
Expand Down Expand Up @@ -101,9 +102,9 @@ func ExpireCookie(name string) *fiber.Cookie {
}

// RefreshAccessToken refreshes the access token
func RefreshAccessToken(refreshCookie string, role string, refreshTokenSecret string, accessExpiresAfter uint, accessTokenSecret string) (*string, *errors.Error) {
func RefreshAccessToken(refreshCookie string, role string, refreshKey *m.Secret[string], accessExpiresAfter uint, accessKey *m.Secret[string]) (*string, *errors.Error) {
// Parse the refresh token
refreshToken, err := ParseRefreshToken(refreshCookie, refreshTokenSecret)
refreshToken, err := ParseRefreshToken(refreshCookie, refreshKey)
if err != nil {
return nil, &errors.FailedToParseRefreshToken
}
Expand All @@ -115,7 +116,7 @@ func RefreshAccessToken(refreshCookie string, role string, refreshTokenSecret st
}

// Create a new access token
accessToken, catErr := CreateAccessToken(claims.Issuer, role, accessExpiresAfter, accessTokenSecret)
accessToken, catErr := CreateAccessToken(claims.Issuer, role, accessExpiresAfter, accessKey)
if catErr != nil {
return nil, &errors.FailedToCreateAccessToken
}
Expand All @@ -124,22 +125,22 @@ func RefreshAccessToken(refreshCookie string, role string, refreshTokenSecret st
}

// ParseAccessToken parses the access token
func ParseAccessToken(cookie string, accessTokenSecret string) (*jwt.Token, error) {
func ParseAccessToken(cookie string, accessKey *m.Secret[string]) (*jwt.Token, error) {
return jwt.ParseWithClaims(cookie, &types.CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(accessTokenSecret), nil
return []byte(accessKey.Expose()), nil
})
}

// ParseRefreshToken parses the refresh token
func ParseRefreshToken(cookie string, refreshTokenSecret string) (*jwt.Token, error) {
func ParseRefreshToken(cookie string, refreshKey *m.Secret[string]) (*jwt.Token, error) {
return jwt.ParseWithClaims(cookie, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(refreshTokenSecret), nil
return []byte(refreshKey.Expose()), nil
})
}

// GetRoleFromToken gets the role from the custom claims
func GetRoleFromToken(tokenString string, accessTokenSecret string) (*string, error) {
token, err := ParseAccessToken(tokenString, accessTokenSecret)
func GetRoleFromToken(tokenString string, accessKey *m.Secret[string]) (*string, error) {
token, err := ParseAccessToken(tokenString, accessKey)
if err != nil {
return nil, err
}
Expand All @@ -153,8 +154,8 @@ func GetRoleFromToken(tokenString string, accessTokenSecret string) (*string, er
}

// ExtractClaims extracts the claims from the token
func ExtractAccessClaims(tokenString string, accessTokenSecret string) (*types.CustomClaims, *errors.Error) {
token, err := ParseAccessToken(tokenString, accessTokenSecret)
func ExtractAccessClaims(tokenString string, accessKey *m.Secret[string]) (*types.CustomClaims, *errors.Error) {
token, err := ParseAccessToken(tokenString, accessKey)
if err != nil {
return nil, &errors.FailedToParseAccessToken
}
Expand All @@ -168,8 +169,8 @@ func ExtractAccessClaims(tokenString string, accessTokenSecret string) (*types.C
}

// ExtractClaims extracts the claims from the token
func ExtractRefreshClaims(tokenString string, refreshTokenSecret string) (*jwt.StandardClaims, *errors.Error) {
token, err := ParseRefreshToken(tokenString, refreshTokenSecret)
func ExtractRefreshClaims(tokenString string, refreshKey *m.Secret[string]) (*jwt.StandardClaims, *errors.Error) {
token, err := ParseRefreshToken(tokenString, refreshKey)
if err != nil {
return nil, &errors.FailedToParseRefreshToken
}
Expand Down
7 changes: 7 additions & 0 deletions backend/src/config/application.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package config

type ApplicationSettings struct {
Port uint16 `yaml:"port"`
Host string `yaml:"host"`
BaseUrl string `yaml:"baseurl"`
}
40 changes: 40 additions & 0 deletions backend/src/config/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package config

import (
"errors"

m "github.com/garrettladley/mattress"
)

type AuthSettings struct {
AccessKey *m.Secret[string]
RefreshKey *m.Secret[string]
AccessTokenExpiry uint
RefreshTokenExpiry uint
}

type intermediateAuthSettings struct {
AccessKey string `yaml:"accesskey"`
RefreshKey string `yaml:"refreshkey"`
AccessTokenExpiry uint `yaml:"accesstokenexpiry"`
RefreshTokenExpiry uint `yaml:"refreshtokenexpiry"`
}

func (int *intermediateAuthSettings) into() (*AuthSettings, error) {
accessToken, err := m.NewSecret(int.AccessKey)
if err != nil {
return nil, errors.New("failed to create secret from access key")
}

refreshToken, err := m.NewSecret(int.RefreshKey)
if err != nil {
return nil, errors.New("failed to create secret from refresh key")
}

return &AuthSettings{
AccessKey: accessToken,
RefreshKey: refreshToken,
AccessTokenExpiry: int.AccessTokenExpiry,
RefreshTokenExpiry: int.RefreshTokenExpiry,
}, nil
}
Loading

0 comments on commit 1405dc1

Please sign in to comment.