chores: refactor struct and structure project
This commit is contained in:
@@ -14,8 +14,10 @@ func (e ErrorCode) Error() string {
|
||||
|
||||
var (
|
||||
// 4xx
|
||||
ErrBadRequest = &ErrorCode{Code: "BAD_REQUEST", Message: "BAD_REQUEST", HttpCode: http.StatusBadRequest}
|
||||
ErrDBRequest = &ErrorCode{Code: "BAD_DB_REQUEST", Message: "DB_ERROR", HttpCode: http.StatusBadRequest}
|
||||
ErrBadRequest = &ErrorCode{Code: "BAD_REQUEST", Message: "BAD_REQUEST", HttpCode: http.StatusBadRequest}
|
||||
ErrUnauthorized = &ErrorCode{Code: "UNAUTHORIZED", Message: "UNAUTHORIZED", HttpCode: http.StatusUnauthorized}
|
||||
ErrDBRequest = &ErrorCode{Code: "BAD_DB_REQUEST", Message: "DB_ERROR", HttpCode: http.StatusBadRequest}
|
||||
ErrExpiryToken = &ErrorCode{Code: "EXPIRED_TOKEN", Message: "EXPIRED_TOKEN", HttpCode: http.StatusUnauthorized}
|
||||
|
||||
// 5xx
|
||||
ErrMarshal = &ErrorCode{Code: "FAILED_MARSHAL", Message: "FAILED_MARSHAL_BODY", HttpCode: http.StatusInternalServerError}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func RespondJsonErrorWithCode(ctx context.Context, w http.ResponseWriter,
|
||||
err error, code string, statusCode int, message string) {
|
||||
setDefaultHeaders(ctx, w.Header())
|
||||
|
||||
w.WriteHeader(statusCode)
|
||||
|
||||
b, _ := json.Marshal(ErrorResponse{
|
||||
Error: ErrorResponseData{
|
||||
Code: code,
|
||||
Message: message,
|
||||
},
|
||||
})
|
||||
|
||||
w.Write(b)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func RespondWithError(w http.ResponseWriter, r *http.Request, err error, msg string) {
|
||||
if err != nil {
|
||||
code := ErrUnauthorized.Code
|
||||
status := http.StatusUnauthorized
|
||||
|
||||
if errors.Is(err, ErrExpiryToken) {
|
||||
code = ErrExpiryToken.Code
|
||||
status = ErrExpiryToken.HttpCode
|
||||
}
|
||||
|
||||
RespondJsonErrorWithCode(r.Context(), w, err, code, status, msg)
|
||||
} else {
|
||||
RespondJsonErrorWithCode(r.Context(), w, nil,
|
||||
ErrUnauthorized.Code, http.StatusUnauthorized, msg)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const SessionHeader = "Authorization"
|
||||
|
||||
func GetToken(r *http.Request) (string, error) {
|
||||
token := getTokenFromHeader(r)
|
||||
|
||||
if token == "" {
|
||||
return "", fmt.Errorf("token not found")
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func getTokenFromHeader(r *http.Request) string {
|
||||
session := r.Header.Get(SessionHeader)
|
||||
arr := strings.Split(session, " ")
|
||||
|
||||
if len(arr) != 2 || strings.ToUpper(arr[0]) != "BEARER" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return arr[1]
|
||||
}
|
||||
@@ -24,8 +24,8 @@ func GetTokenDetail(r *http.Request) (authdomain.AuthToken, error) {
|
||||
if len(token) < 2 {
|
||||
return data, errors.New("invalid token")
|
||||
}
|
||||
|
||||
data, err := DestructToken(token[1])
|
||||
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@ type ClaimOption func(options jwt.MapClaims)
|
||||
|
||||
func GenerateToken(data authdomain.AuthToken) (string, error) {
|
||||
now := timeutils.Now()
|
||||
|
||||
claims := jwt.MapClaims{
|
||||
"email": data.Email,
|
||||
"role": data.Role,
|
||||
"session_id": data.SessionID,
|
||||
"exp": now.Add(1 * time.Hour).Unix(),
|
||||
"exp": now.Add(time.Minute * time.Duration(config.REDIS_TIMEOUT)).Unix(),
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
@@ -45,11 +45,10 @@ func GenerateToken(data authdomain.AuthToken) (string, error) {
|
||||
return token.SignedString([]byte(config.SALT_SECURITY))
|
||||
}
|
||||
|
||||
func parseToken(s string) (*jwt.Token, error) {
|
||||
func ParseToken(s string) (*jwt.Token, error) {
|
||||
return jwt.Parse(s, func(t *jwt.Token) (any, error) {
|
||||
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
errMsg := fmt.Sprintf("unexpected signing method: %v", t.Header["alg"])
|
||||
return nil, errors.New(errMsg)
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
|
||||
}
|
||||
|
||||
return []byte(config.SALT_SECURITY), nil
|
||||
@@ -59,7 +58,7 @@ func parseToken(s string) (*jwt.Token, error) {
|
||||
func DestructToken(s string) (authdomain.AuthToken, error) {
|
||||
var data authdomain.AuthToken
|
||||
|
||||
token, err := parseToken(s)
|
||||
token, err := ParseToken(s)
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
|
||||
@@ -2,12 +2,36 @@ package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"legalgo-BE-go/config"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
func StoreToken(ctx context.Context, rdb *redis.Client, token, username string) error {
|
||||
func GetTokenRedis(ctx context.Context, rdb *redis.Client, id string) (string, error) {
|
||||
val, err := rdb.Get(ctx, "token-"+id).Result()
|
||||
|
||||
switch {
|
||||
case err == redis.Nil:
|
||||
return "", fmt.Errorf("token does not exist")
|
||||
case err != nil:
|
||||
return "", err
|
||||
case val == "":
|
||||
return "", fmt.Errorf("token does not exist")
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func StoreTokenRedis(ctx context.Context, rdb *redis.Client, token, id string) error {
|
||||
_, err := rdb.Get(ctx, "token-"+id).Result()
|
||||
if err != redis.Nil {
|
||||
// If there's an existing token, delete it (expire the previous session)
|
||||
if err := rdb.Del(ctx, "token-"+id).Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// return rdb.Set(ctx context.Context, key string, value interface{}, expiration time.Duration)
|
||||
return rdb.Set(ctx, "token"+username, token, time.Hour).Err()
|
||||
return rdb.Set(ctx, "token-"+id, token, time.Minute*time.Duration(config.REDIS_TIMEOUT)).Err()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user