mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 21:00:06 +01:00
initial rebuild
This commit is contained in:
85
internal/middleware/auth.go
Normal file
85
internal/middleware/auth.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/glueops/autoglue/internal/db"
|
||||
"github.com/glueops/autoglue/internal/db/models"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type AuthClaims struct {
|
||||
Orgs []string `json:"orgs"`
|
||||
Roles []string `json:"roles"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
type AuthContext struct {
|
||||
UserID uuid.UUID
|
||||
OrganizationID uuid.UUID
|
||||
OrgRole string // Role in the org
|
||||
Claims *AuthClaims `json:"claims,omitempty" swaggerignore:"true"`
|
||||
}
|
||||
|
||||
type contextKey struct{}
|
||||
|
||||
var authContextKey = contextKey{}
|
||||
|
||||
func AuthMiddleware(secret string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader == "" || !strings.HasPrefix(strings.ToLower(authHeader), "bearer ") {
|
||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
tokenStr := strings.TrimPrefix(authHeader, "Bearer ")
|
||||
claims := &AuthClaims{}
|
||||
|
||||
token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(secret), nil
|
||||
})
|
||||
if err != nil || !token.Valid {
|
||||
http.Error(w, "Invalid token", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
userUUID, err := uuid.Parse(claims.Subject)
|
||||
if err != nil {
|
||||
http.Error(w, "invalid user id", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
authCtx := &AuthContext{
|
||||
UserID: userUUID,
|
||||
Claims: claims,
|
||||
}
|
||||
|
||||
if orgID := r.Header.Get("X-Org-ID"); orgID != "" {
|
||||
orgUUID, _ := uuid.Parse(orgID)
|
||||
|
||||
var member models.Member
|
||||
if err := db.DB.Where("user_id = ? AND organization_id = ?", claims.Subject, orgID).First(&member).Error; err != nil {
|
||||
http.Error(w, "User not a member of the organization", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
authCtx.OrganizationID = orgUUID
|
||||
authCtx.OrgRole = string(member.Role)
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), authContextKey, authCtx)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func GetAuthContext(r *http.Request) *AuthContext {
|
||||
if ac, ok := r.Context().Value(authContextKey).(*AuthContext); ok {
|
||||
return ac
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user