-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package api |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package config | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
"crypto/x509" | ||
"encoding/pem" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
var ( | ||
jwtPublicKey *ecdsa.PublicKey | ||
jwtPrivateKey *ecdsa.PrivateKey | ||
) | ||
|
||
func GetJwtPrivateKey() *ecdsa.PrivateKey { | ||
return jwtPrivateKey | ||
} | ||
|
||
func GetJwtPublicKey() *ecdsa.PublicKey { | ||
return jwtPublicKey | ||
} | ||
|
||
func LoadPrivateKey(path string) error { | ||
content, err := os.ReadFile(path) | ||
if err != nil { | ||
return fmt.Errorf("failed to read private key file: %w", err) | ||
} | ||
|
||
block, _ := pem.Decode(content) | ||
if block == nil { | ||
return fmt.Errorf("failed to decode private key") | ||
} | ||
|
||
key, err := x509.ParseECPrivateKey(block.Bytes) | ||
if err != nil { | ||
return fmt.Errorf("failed to parse private key: %w", err) | ||
} | ||
|
||
jwtPrivateKey = key | ||
return nil | ||
} | ||
|
||
func LoadPublicKey(path string) error { | ||
content, err := os.ReadFile(path) | ||
if err != nil { | ||
return fmt.Errorf("failed to read public key file: %w", err) | ||
} | ||
|
||
block, _ := pem.Decode(content) | ||
if block == nil { | ||
return fmt.Errorf("failed to decode public key") | ||
} | ||
|
||
key, err := x509.ParsePKIXPublicKey(block.Bytes) | ||
if err != nil { | ||
return fmt.Errorf("failed to parse public key: %w", err) | ||
} | ||
|
||
jwtPublicKey = key.(*ecdsa.PublicKey) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package auth | ||
|
||
import ( | ||
"errors" | ||
"time" | ||
|
||
"server/config" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/golang-jwt/jwt/v5" | ||
) | ||
|
||
const JWT_ISSUER = "ctec-api-server" | ||
|
||
var ErrTokenValidation = errors.New("token validation failed") | ||
|
||
type JwtCustomClaims struct { | ||
jwt.RegisteredClaims | ||
ID uint `json:"id"` | ||
} | ||
|
||
type JwtToken struct { | ||
Token string `json:"token"` | ||
Claims JwtCustomClaims `json:"claims"` | ||
} | ||
|
||
func New() *JwtToken { | ||
return &JwtToken{} | ||
} | ||
|
||
// CreateUserToken creates a token for the user | ||
func CreateUserToken(ID uint) (*JwtToken, error) { | ||
expiresAt := time.Now().Add(time.Hour * 24 * time.Duration(config.Get().API.JwtExpireDay)) | ||
claims := JwtCustomClaims{ | ||
RegisteredClaims: jwt.RegisteredClaims{ | ||
Issuer: JWT_ISSUER, | ||
ExpiresAt: jwt.NewNumericDate(expiresAt), | ||
}, | ||
ID: ID, | ||
} | ||
|
||
t := jwt.New(jwt.SigningMethodES256) | ||
t.Claims = &claims | ||
tokenString, err := t.SignedString(config.GetJwtPrivateKey()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &JwtToken{Token: tokenString, Claims: claims}, nil | ||
} | ||
|
||
// ParseToken parses the token and returns the claims | ||
func (j *JwtToken) ParseToken(token string) (*JwtCustomClaims, error) { | ||
t, err := jwt.ParseWithClaims(token, &JwtCustomClaims{}, func(t *jwt.Token) (any, error) { | ||
return config.GetJwtPublicKey(), nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
claims, ok := t.Claims.(*JwtCustomClaims) | ||
if !ok || !t.Valid { | ||
return nil, ErrTokenValidation | ||
} | ||
|
||
return claims, nil | ||
} | ||
|
||
// JwtClaims returns the claims from the token | ||
func (j *JwtToken) JwtClaims(c *gin.Context) (*JwtCustomClaims, error) { | ||
token := c.GetHeader("Authorization") | ||
claims, err := j.ParseToken(token) | ||
return claims, err | ||
} | ||
|
||
// JwtUserId returns the user ID from the token | ||
func (j *JwtToken) JwtUserId(c *gin.Context) uint { | ||
claims, _ := j.JwtClaims(c) | ||
return claims.ID | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package database | ||
|
||
import ( | ||
"strconv" | ||
"time" | ||
) | ||
|
||
type Model struct { | ||
ID uint `gorm:"primarykey" json:"id,omitempty"` | ||
CreatedAt time.Time `json:"created_at,omitempty"` | ||
UpdatedAt time.Time `json:"updated_at,omitempty"` | ||
} | ||
|
||
func (m *Model) IDtoString() string { | ||
return strconv.Itoa(int(m.ID)) | ||
} |