-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth.go
130 lines (105 loc) · 3.42 KB
/
auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
)
var mySigningKey []byte
func init() {
if err := godotenv.Load(); err != nil {
log.Fatal("Error loading .env file")
}
mySigningKey = []byte(os.Getenv("SECRET_KEY"))
}
type Claims struct {
Username string `json:"username"`
Role string `json:"role"`
jwt.StandardClaims
}
type ErrorResponse struct {
ErrorCode int `json:"error_code"`
ErrorMessage string `json:"error_message"`
}
func GenerateJWT(username, role string) (string, error) {
expirationTime := time.Now().Add(5 * time.Minute)
claims := &Claims{
Username: username,
Role: role,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(mySigningKey)
if err != nil {
return "", fmt.Errorf("error signing token: %w", err)
}
return tokenString, nil
}
func HomeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome! Please login or register.")
}
func LoginHandler(w http.ResponseWriter, r *http.Request) {
username := "testuser"
role := "organizer"
token, err := GenerateJWT(username, role)
if err != nil {
respondWithError(w, http.StatusInternalServerError, fmt.Sprintf("Error generating token: %v", err))
return
}
fmt.Fprintf(w, "Token: %s", token)
}
func ValidateMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tokenString := r.Header.Get("Authorization")
if tokenString == "" {
respondWithError(w, http.StatusUnauthorized, "No Authorization token provided")
return
}
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
return mySigningKey, nil
})
if err != nil || !token.Valid {
respondWithError(w, http.StatusUnauthorized, "Invalid token")
return
}
next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "props", claims)))
})
}
func EventInfoHandler(w http.ResponseWriter, r *http.Request) {
claims, ok := r.Context().Value("props").(*Claims)
if !ok {
respondWithError(w, http.StatusInternalServerError, "Could not extract claims from request context")
return
}
info := fmt.Sprintf("%s-level event details", claims.Role)
fmt.Fprintf(w, info)
}
func respondWithError(w http.ResponseWriter, code int, message string) {
response := ErrorResponse{ErrorCode: code, ErrorMessage: message}
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Printf("Error marshalling error response: %s", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
w.Write(jsonResponse)
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
r.HandleFunc("/login", LoginHandler)
r.Handle("/eventinfo", ValidateMiddleware(http.HandlerFunc(EventInfoHandler)))
http.Handle("/", r)
log.Fatal(http.ListenAndServe(":8080", nil))
}