Skip to content
Snippets Groups Projects
Commit 0b9d4fb5 authored by Emanuel Petrinovic's avatar Emanuel Petrinovic
Browse files

JWT Implementation

parent 1918b1fd
No related branches found
No related tags found
No related merge requests found
go 1.24.2
use ./src/myaktion
use ./src/genjwt
module gitlab.reutlingen-university.de/petrinov/myaktion-go/src/genjwt
go 1.24.2
require github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
package main
import (
"fmt"
"os"
"time"
"github.com/golang-jwt/jwt"
)
var secretKey = []byte("myaktion-go-secret-key")
func createToken(username string) (string, error) {
claims := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": username,
"iss": "myaktion-go",
"aud": "organizer",
"exp": time.Now().Add(time.Hour).Unix(),
"iat": time.Now().Unix(),
})
fmt.Printf("Token claims added: %+v\n", claims)
tokenString, err := claims.SignedString(secretKey)
if err != nil {
return "", err
}
return tokenString, nil
}
func main() {
if len(os.Args) >= 2 {
organizerName := os.Args[1]
tokenString, err := createToken(organizerName)
if err != nil {
fmt.Printf("Unable to create token: %+v\n", err)
} else {
fmt.Printf("%+v\n", tokenString)
}
} else {
fmt.Println("Please pass a username as command-line argument")
}
}
......@@ -12,6 +12,7 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/go-sql-driver/mysql v1.9.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
golang.org/x/sys v0.5.0 // indirect
......
......@@ -6,6 +6,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
......
......@@ -64,8 +64,8 @@ func GetCampaign(w http.ResponseWriter, r *http.Request) {
sendJson(w, campaign)
}
func GetCampaigns(w http.ResponseWriter, _ *http.Request) {
campaigns, err := service.GetCampaigns()
func GetCampaigns(w http.ResponseWriter, r *http.Request) {
campaigns, err := service.GetCampaigns(getOrganizerName(r))
if err != nil {
log.Printf("Error calling service GetCampaigns: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
......@@ -118,6 +118,7 @@ func getCampaign(r *http.Request) (*model.Campaign, error) {
log.Errorf("Can't serialize request body to campaign struct: %v", err)
return nil, err
}
campaign.OrganizerName = getOrganizerName(r)
return &campaign, nil
}
......@@ -159,3 +160,7 @@ func PatchCampaign(w http.ResponseWriter, r *http.Request) {
}*/
}
func getOrganizerName(r *http.Request) string {
return r.Context().Value("organizerName").(string)
}
package main
import (
"context"
"fmt"
"net/http"
"os"
"strings"
"github.com/golang-jwt/jwt"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
"gitlab.reutlingen-university.de/petrinov/myaktion-go/handler"
)
var secretKey = []byte("myaktion-go-secret-key")
func authMW(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tokenString := r.Header.Get("Authorization")
if tokenString == "" {
w.WriteHeader(http.StatusUnauthorized)
return
}
log.Info(tokenString)
tokenString = strings.Replace(tokenString, "Bearer ", "", 1)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method")
}
return []byte(secretKey), nil
})
if err != nil {
log.Errorf("Can' parse token string: %+v\n", err)
w.WriteHeader(http.StatusUnauthorized)
return
}
if !token.Valid {
log.Errorf("Token is not valid: %+v\n", err)
w.WriteHeader(http.StatusUnauthorized)
return
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
log.Errorf("Can' extract claims from token: %+v\n", err)
w.WriteHeader(http.StatusUnauthorized)
return
}
organizerName, ok := claims["sub"].(string)
if !ok {
log.Errorf("Can' read organizerName from token: %+v\n", err)
w.WriteHeader(http.StatusUnauthorized)
return
}
if organizerName == "" {
log.Errorf("OrganizerName is an empty string: %+v\n", err)
w.WriteHeader(http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), "organizerName", organizerName)
next(w, r.WithContext(ctx))
}
}
func init() {
log.SetFormatter(&log.TextFormatter{})
log.SetReportCaller(true)
......@@ -25,9 +79,9 @@ func main() {
router := mux.NewRouter()
router.HandleFunc("/health", handler.Health).Methods("GET")
router.HandleFunc("/campaigns", handler.CreateCampaign).Methods("POST")
router.HandleFunc("/campaigns", authMW(handler.CreateCampaign)).Methods("POST")
router.HandleFunc("/campaigns/{id}", handler.UpdateCampaign).Methods("PUT")
router.HandleFunc("/campaigns/{id}", handler.GetCampaign).Methods("GET")
router.HandleFunc("/campaigns/{id}", authMW(handler.GetCampaign)).Methods("GET")
router.HandleFunc("/campaigns", handler.GetCampaigns).Methods("GET")
router.HandleFunc("/campaigns/{id}", handler.DeleteCampaign).Methods("DELETE")
router.HandleFunc("/campaigns/{id}", handler.PatchCampaign).Methods("PATCH")
......
......@@ -19,9 +19,9 @@ func CreateCampaign(campaign *model.Campaign) error {
}
func GetCampaigns() ([]model.Campaign, error) {
func GetCampaigns(organizerName string) ([]model.Campaign, error) {
var campaigns []model.Campaign
result := db.DB.Preload("Donations").Find(&campaigns)
result := db.DB.Preload("Donations").Where("organizer_name = ?", organizerName).Find(&campaigns)
if result.Error != nil {
return nil, result.Error
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment