package main import ( "context" "encoding/json" "io" "libshared" "log" "net/http" "strings" "time" "github.com/golang-jwt/jwt/v5" ) type getRoleTokenRequest struct { RoleName string `json:"rolename"` } func getRoleToken(w http.ResponseWriter, r *http.Request) { log.Println("getRoleToken called") // Only allow POST if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } // Get JWT from Authorization header authHeader := r.Header.Get("Authorization") if authHeader == "" { http.Error(w, "Missing Authorization header", http.StatusUnauthorized) return } parts := strings.SplitN(authHeader, " ", 2) if len(parts) != 2 || parts[0] != "Bearer" { http.Error(w, "Invalid Authorization format", http.StatusUnauthorized) return } tokenString := parts[1] // Replace with your actual secret or keyfunc secret := []byte("super-secret-key") claims := &MyClaims{} token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { // Validate signing method if needed return secret, nil }) if err != nil || !token.Valid { http.Error(w, "Invalid token", http.StatusUnauthorized) return } // Access parsed values log.Println("sub:", claims.Sub) log.Println("purpose:", claims.Purpose) log.Println("account:", claims.Account) // exp and iat come from RegisteredClaims log.Println("exp:", claims.ExpiresAt) log.Println("iat:", claims.IssuedAt) if claims.ExpiresAt == nil || time.Now().After(claims.ExpiresAt.Time) { http.Error(w, "Token expired", http.StatusUnauthorized) return } log.Println("Add in validation that the user is allowed to get this token") // Read the raw request body body, err := io.ReadAll(r.Body) if err != nil { http.Error(w, "Failed to read body", http.StatusBadRequest) return } defer r.Body.Close() // Parse JSON into Role struct var role getRoleTokenRequest if err := json.Unmarshal(body, &role); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } log.Println("Received request for role:", role.RoleName) log.Println("Authentication would taken place here") // Check if policy with the same name already exists for the account checkExisting := libshared.Pool.QueryRow(context.Background(), "SELECT FROM roles WHERE accountid = $1 AND rolename = $2", claims.Account, role.RoleName) log.Println("checkExisting:", role.RoleName) err = checkExisting.Scan() if err != nil { w.WriteHeader(http.StatusConflict) return } usertoken, err := libshared.CreateJWT(privateKey, claims.Account, role.RoleName, "role") if err != nil { w.WriteHeader(http.StatusInternalServerError) return } log.Println(usertoken) }