diff --git a/backend/internal/agent/agent.go b/backend/internal/agent/agent.go index 9e54bf9..a207c7c 100644 --- a/backend/internal/agent/agent.go +++ b/backend/internal/agent/agent.go @@ -147,7 +147,9 @@ func (a *Agent) RunSimpleComputer(ctx context.Context, exprMsg *messages.Express if err != nil { return fmt.Errorf("can't convert int to str: %v, fn: %s", err, fn) } - + if int(exprMsg.UserID) == 0 { + a.log.Warn("", slog.String("oper", oper), slog.Int("userID", int(exprMsg.UserID))) + } time_for_oper, err := a.dbConfig.Queries.GetOperationTimeByType(ctx, postgres.GetOperationTimeByTypeParams{ OperationType: oper, UserID: exprMsg.UserID, diff --git a/backend/internal/lib/jwt/jwt.go b/backend/internal/lib/jwt/jwt.go index 27f44b1..c45db68 100644 --- a/backend/internal/lib/jwt/jwt.go +++ b/backend/internal/lib/jwt/jwt.go @@ -1,10 +1,13 @@ package jwt import ( + "errors" "fmt" "log" + "net/http" "os" "path/filepath" + "strings" "time" "github.com/Prrromanssss/DAEE-fullstack/internal/storage/postgres" @@ -42,3 +45,55 @@ func NewToken(user postgres.User, duration time.Duration) (string, error) { return tokenString, nil } + +func getTokenFromHeader(r *http.Request) (string, error) { + authHeader := r.Header.Get("Authorization") + if authHeader == "" { + return "", fmt.Errorf("authorization header is missing") + } + + // Checks that header starts with "Bearer". + parts := strings.Split(authHeader, " ") + if len(parts) != 2 || parts[0] != "Bearer" { + return "", fmt.Errorf("invalid Authorization header format") + } + + return parts[1], nil // returns token without "Bearer". +} + +func GetUidFromJWT(r *http.Request, secret string) (int32, error) { + jwtToken, err := getTokenFromHeader(r) + if err != nil { + return 0, err + } + + // Parse JWT Token. + token, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) { + return []byte(secret), nil + }) + if err != nil { + return 0, err + } + + if !token.Valid { + return 0, errors.New("token is invalid") + } + + claims, ok := token.Claims.(jwt.MapClaims) + if !ok { + return 0, errors.New("error in map claims") + } + + userIDFloat, ok := claims["uid"].(float64) + if !ok { + return 0, errors.New("jwt token does not contain uid") + } + + userID := int32(userIDFloat) + + if userID == 0 { + return 0, errors.New("userID == 0") + } + + return userID, nil +} diff --git a/backend/internal/lib/jwt/jwt_from_header.go b/backend/internal/lib/jwt/jwt_from_header.go deleted file mode 100644 index d96b318..0000000 --- a/backend/internal/lib/jwt/jwt_from_header.go +++ /dev/null @@ -1,54 +0,0 @@ -package jwt - -import ( - "fmt" - "net/http" - "strings" - - "github.com/golang-jwt/jwt/v5" -) - -func getTokenFromHeader(r *http.Request) (string, error) { - authHeader := r.Header.Get("Authorization") - if authHeader == "" { - return "", fmt.Errorf("authorization header is missing") - } - - // Checks that header starts with "Bearer". - parts := strings.Split(authHeader, " ") - if len(parts) != 2 || parts[0] != "Bearer" { - return "", fmt.Errorf("invalid Authorization header format") - } - - return parts[1], nil // returns token without "Bearer". -} - -func GetUidFromJWT(r *http.Request, secret string) (int32, error) { - jwtToken, err := getTokenFromHeader(r) - if err != nil { - return 0, err - } - - // Parse JWT Token. - token, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) { - return []byte(secret), nil - }) - if err != nil { - return 0, err - } - - if !token.Valid { - return 0, err - } - - claims, ok := token.Claims.(jwt.MapClaims) - if !ok { - return 0, err - } - userID, ok := claims["uid"].(int32) - if !ok { - return 0, err - } - - return userID, nil -} diff --git a/backend/internal/orchestrator/orchestrator.go b/backend/internal/orchestrator/orchestrator.go index 2381b4a..5eec072 100644 --- a/backend/internal/orchestrator/orchestrator.go +++ b/backend/internal/orchestrator/orchestrator.go @@ -60,6 +60,7 @@ func (o *Orchestrator) AddTask( ExpressionID: expressionMessage.ExpressionID, Token: token, Expression: expressionMessage.Expression, + UserID: expressionMessage.UserID, }) if err != nil { o.log.Error("can't publish token to queue", sl.Err(err), slog.String("fn", fn)) @@ -226,6 +227,7 @@ func (o *Orchestrator) HandleExpression( ExpressionID: exprMsg.ExpressionID, Token: newResultAndToken.Token, Expression: newResultAndToken.Result, + UserID: exprMsg.UserID, }) if err != nil { return fmt.Errorf("orchestrator error: %v, fn: %s", err, fn) diff --git a/backend/sql/schema/0005_operations.sql b/backend/sql/schema/0005_operations.sql index 6592476..57a7983 100644 --- a/backend/sql/schema/0005_operations.sql +++ b/backend/sql/schema/0005_operations.sql @@ -1,11 +1,12 @@ -- +goose Up CREATE TABLE IF NOT EXISTS operations ( operation_id int GENERATED ALWAYS AS IDENTITY, - operation_type varchar(1) UNIQUE NOT NULL, + operation_type varchar(1) NOT NULL, execution_time int NOT NULL DEFAULT 100, user_id int NOT NULL, PRIMARY KEY(operation_id), + CONSTRAINT operation_type_user_id UNIQUE(operation_type, user_id), FOREIGN KEY(user_id) REFERENCES users(user_id) ON DELETE CASCADE