Skip to content

Commit

Permalink
auth
Browse files Browse the repository at this point in the history
  • Loading branch information
Prrromanssss committed Apr 20, 2024
1 parent 17c59f4 commit 6ca41ad
Show file tree
Hide file tree
Showing 17 changed files with 174 additions and 87 deletions.
7 changes: 4 additions & 3 deletions backend/cmd/orchestrator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,15 @@ func main() {
v1Router.Post("/expressions", handlers.HandlerCreateExpression(
log,
dbCfg,
cfg.JWTSecret,
application.OrchestratorApp,
application.Producer,
))
v1Router.Get("/expressions", handlers.HandlerGetExpressions(log, dbCfg))
v1Router.Get("/expressions", handlers.HandlerGetExpressions(log, dbCfg, cfg.JWTSecret))

// Operation endpoints
v1Router.Get("/operations", handlers.HandlerGetOperations(log, dbCfg))
v1Router.Patch("/operations", handlers.HandlerUpdateOperation(log, dbCfg))
v1Router.Get("/operations", handlers.HandlerGetOperations(log, dbCfg, cfg.JWTSecret))
v1Router.Patch("/operations", handlers.HandlerUpdateOperation(log, dbCfg, cfg.JWTSecret))

// Agent endpoints
v1Router.Get("/agents", handlers.HandlerGetAgents(log, dbCfg))
Expand Down
7 changes: 4 additions & 3 deletions backend/internal/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ func (a *Agent) RunSimpleComputer(ctx context.Context, exprMsg *messages.Express
return fmt.Errorf("can't convert int to str: %v, fn: %s", err, fn)
}

time_for_oper, err := a.dbConfig.Queries.GetOperationTimeByType(ctx, oper)
time_for_oper, err := a.dbConfig.Queries.GetOperationTimeByType(ctx, postgres.GetOperationTimeByTypeParams{
OperationType: oper,
UserID: exprMsg.UserID,
})
if err != nil {
return fmt.Errorf("can't get execution time by operation type: %v, fn: %s", err, fn)
}
Expand All @@ -162,8 +165,6 @@ func (a *Agent) RunSimpleComputer(ctx context.Context, exprMsg *messages.Express
return fmt.Errorf("can't increment number of active calculations: %v, fn: %s", err, fn)
}

// atomic.AddInt32(&a.NumberOfActiveCalculations, 1)

return nil
}

Expand Down
1 change: 1 addition & 0 deletions backend/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
InactiveTimeForAgent int32 `yaml:"inactive_time_for_agent" env-default:"200"`
TimeForPing int32 `yaml:"time_for_ping" end-default:"100"`
TokenTTL time.Duration `yaml:"tokenTTL" env-default:"1h"`
JWTSecret string `env:"JWT_SECRET" env-required:"true"`
GRPCServer `yaml:"grpc_server" env-required:"true"`
DatabaseInstance `yaml:"database_instance" env-required:"true"`
RabbitQueue `yaml:"rabbit_queue" env-required:"true"`
Expand Down
1 change: 1 addition & 0 deletions backend/internal/domain/messages/expression_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type ExpressionMessage struct {
Result int `json:"result"`
IsPing bool `json:"is_ping"`
AgentID int32 `json:"agent_id"`
UserID int32 `json:"user_id"`
}

type ResultAndTokenMessage struct {
Expand Down
24 changes: 19 additions & 5 deletions backend/internal/http-server/handlers/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import (

"github.com/Prrromanssss/DAEE-fullstack/internal/domain/brokers"
"github.com/Prrromanssss/DAEE-fullstack/internal/domain/messages"
"github.com/Prrromanssss/DAEE-fullstack/internal/lib/jwt"
"github.com/Prrromanssss/DAEE-fullstack/internal/orchestrator"

"github.com/Prrromanssss/DAEE-fullstack/internal/orchestrator/parser"
"github.com/Prrromanssss/DAEE-fullstack/internal/storage"
"github.com/Prrromanssss/DAEE-fullstack/internal/storage/postgres"
)

// TODO: user
// HandlerCreateExpression is a http.Handler to create new expression.
func HandlerCreateExpression(
log *slog.Logger,
dbCfg *storage.Storage,
secret string,
orc *orchestrator.Orchestrator,
producer brokers.Producer,
) http.HandlerFunc {
Expand All @@ -31,13 +32,19 @@ func HandlerCreateExpression(
slog.String("fn", fn),
)

userID, err := jwt.GetUidFromJWT(r, secret)
if err != nil {
respondWithError(log, w, 403, "Status Forbidden")
return
}

type parametrs struct {
Data string `json:"data"`
}

decoder := json.NewDecoder(r.Body)
params := parametrs{}
err := decoder.Decode(&params)
err = decoder.Decode(&params)
if err != nil {
respondWithError(log, w, 400, fmt.Sprintf("error parsing JSON: %v", err))
return
Expand All @@ -56,7 +63,7 @@ func HandlerCreateExpression(
Data: params.Data,
ParseData: parseData,
Status: "ready_for_computation",
UserID: 1, // TODO: UserID !!!
UserID: userID,
})
if err != nil {
respondWithError(log, w, 400, fmt.Sprintf("can't create expression: %v", err))
Expand All @@ -66,6 +73,7 @@ func HandlerCreateExpression(
msgToQueue := messages.ExpressionMessage{
ExpressionID: expression.ExpressionID,
Expression: parseData,
UserID: userID,
}

orc.AddTask(msgToQueue, producer)
Expand All @@ -77,15 +85,21 @@ func HandlerCreateExpression(
}

// HandlerGetExpressions is a http.Handler to get all expressions from storage.
func HandlerGetExpressions(log *slog.Logger, dbCfg *storage.Storage) http.HandlerFunc {
func HandlerGetExpressions(log *slog.Logger, dbCfg *storage.Storage, secret string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
const fn = "handlers.HandlerCreateExpression"

log := log.With(
slog.String("fn", fn),
)

expressions, err := dbCfg.Queries.GetExpressions(r.Context())
userID, err := jwt.GetUidFromJWT(r, secret)
if err != nil {
respondWithError(log, w, 403, "Status Forbidden")
return
}

expressions, err := dbCfg.Queries.GetExpressions(r.Context(), userID)
if err != nil {
respondWithError(log, w, 400, fmt.Sprintf("Couldn't get expressions: %v", err))
return
Expand Down
22 changes: 18 additions & 4 deletions backend/internal/http-server/handlers/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,27 @@ import (
"log/slog"
"net/http"

"github.com/Prrromanssss/DAEE-fullstack/internal/lib/jwt"
"github.com/Prrromanssss/DAEE-fullstack/internal/storage"
"github.com/Prrromanssss/DAEE-fullstack/internal/storage/postgres"
)

// HandlerGetOperations is a http.Handler to get all operations from storage.
func HandlerGetOperations(log *slog.Logger, dbCfg *storage.Storage) http.HandlerFunc {
func HandlerGetOperations(log *slog.Logger, dbCfg *storage.Storage, secret string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
const fn = "hadlers.HandlerGetOperations"

log := log.With(
slog.String("fn", fn),
)

operations, err := dbCfg.Queries.GetOperations(r.Context())
userID, err := jwt.GetUidFromJWT(r, secret)
if err != nil {
respondWithError(log, w, 403, "Status Forbidden")
return
}

operations, err := dbCfg.Queries.GetOperations(r.Context(), userID)
if err != nil {
respondWithError(log, w, 400, fmt.Sprintf("can't get operations: %v", err))
return
Expand All @@ -30,29 +37,36 @@ func HandlerGetOperations(log *slog.Logger, dbCfg *storage.Storage) http.Handler
}

// HandlerUpdateOperation is a http.Handler to update execution time of the certain operation type.
func HandlerUpdateOperation(log *slog.Logger, dbCfg *storage.Storage) http.HandlerFunc {
func HandlerUpdateOperation(log *slog.Logger, dbCfg *storage.Storage, secret string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
const fn = "handlers.HandlerUpdateOperation"

log := log.With(
slog.String("fn", fn),
)

userID, err := jwt.GetUidFromJWT(r, secret)
if err != nil {
respondWithError(log, w, 403, "Status Forbidden")
return
}

type parametrs struct {
OperationType string `json:"operation_type"`
ExecutionTime int32 `json:"execution_time"`
}

decoder := json.NewDecoder(r.Body)
params := parametrs{}
err := decoder.Decode(&params)
err = decoder.Decode(&params)
if err != nil {
respondWithError(log, w, 400, fmt.Sprintf("error parsing JSON: %v", err))
}

operation, err := dbCfg.Queries.UpdateOperationTime(r.Context(), postgres.UpdateOperationTimeParams{
OperationType: params.OperationType,
ExecutionTime: params.ExecutionTime,
UserID: userID,
})

if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions backend/internal/http-server/handlers/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ func HandlerRegisterNewUser(
return
}

err = dbCfg.Queries.NewOperationsForUser(r.Context(), int32(registerResponse.UserId))
if err != nil {
respondWithError(log, w, 400, fmt.Sprintf("can't create new operations for user: %v", err))
return
}

respondWithJson(log, w, 200, registerResponse)
}
}
54 changes: 54 additions & 0 deletions backend/internal/lib/jwt/jwt_from_header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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
}
2 changes: 2 additions & 0 deletions backend/internal/orchestrator/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func (o *Orchestrator) ReloadComputingExpressions(
msgToQueue := messages.ExpressionMessage{
ExpressionID: expr.ExpressionID,
Expression: expr.ParseData,
UserID: expr.UserID,
}
o.AddTask(msgToQueue, producer)
}
Expand Down Expand Up @@ -170,6 +171,7 @@ func (o *Orchestrator) CheckPing(ctx context.Context, producer brokers.Producer)
msgToQueue := messages.ExpressionMessage{
ExpressionID: expr.ExpressionID,
Expression: expr.ParseData,
UserID: expr.UserID,
}
o.AddTask(msgToQueue, producer)
}
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/storage/postgres/expressions.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/internal/storage/postgres/model_transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type OperationTransformed struct {
OperationID int32 `json:"operation_id"`
OperationType string `json:"operation_type"`
ExecutionTime int32 `json:"execution_time"`
UserID int32 `json:"user_id"`
}

func DatabaseOperationToOperation(dbOper Operation) OperationTransformed {
Expand Down
1 change: 1 addition & 0 deletions backend/internal/storage/postgres/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6ca41ad

Please sign in to comment.