github.com/timoth-y/kicksware-api/order-service@v0.0.0-20201002192818-87b546a7ae5a/api/rest/auth.go (about) 1 package rest 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "net/http" 8 "net/url" 9 10 "github.com/dgrijalva/jwt-go" 11 "github.com/dgrijalva/jwt-go/request" 12 ) 13 14 var ( 15 errInvalidTokenClaims = errors.New("invalid token claims") 16 guestRole = "gst" 17 ) 18 19 type authClaims struct { 20 UniqueID string `json:"nameid,omitempty"` 21 Username string `json:"unique_name,omitempty"` 22 Email string `json:"sub,omitempty"` 23 Role string `json:"role,omitempty"` 24 } 25 26 func (h *Handler) Authenticator(next http.Handler) http.Handler { 27 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 28 token, err := h.getRequestToken(r); if err != nil { 29 http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) 30 fmt.Println() 31 return 32 } 33 34 if token == nil || !token.Valid { 35 http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) 36 return 37 } 38 39 // Token is authenticated, pass it through 40 next.ServeHTTP(w, r) 41 }) 42 } 43 44 func (h *Handler) Authorizer(next http.Handler) http.Handler { 45 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 46 token, err := h.getRequestToken(r); if err != nil { 47 http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) 48 fmt.Println() 49 return 50 } 51 52 claims, err := getClaims(token); if err != nil { 53 http.Error(w, errInvalidTokenClaims.Error(), http.StatusInternalServerError) 54 fmt.Println() 55 return 56 } 57 if claims != nil && claims.Role != guestRole { 58 r.URL.User = url.User(claims.UniqueID) 59 } else { 60 http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) 61 fmt.Println() 62 return 63 } 64 65 next.ServeHTTP(w, r) 66 }) 67 } 68 69 func (h *Handler) UserSetter(next http.Handler) http.Handler { 70 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 71 token, err := h.getRequestToken(r); if err != nil { 72 http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) 73 fmt.Println() 74 return 75 } 76 77 if claims, err := getClaims(token); err == nil && claims != nil && claims.Role != guestRole { 78 r.URL.User = url.User(claims.UniqueID) 79 } else { 80 r.URL.User = nil 81 } 82 83 next.ServeHTTP(w, r) 84 }) 85 } 86 87 func (h *Handler) getRequestToken(r *http.Request) (token *jwt.Token, err error) { 88 token, err = request.ParseFromRequest(r, request.OAuth2Extractor, func(token *jwt.Token) (interface{}, error) { 89 if _, ok := token.Method.(*jwt.SigningMethodRSA); ok { 90 return h.auth.PublicKey(), nil 91 } 92 return nil, fmt.Errorf("authenticator: unexpected signing method: %q", token.Header["alg"]) 93 }) 94 return 95 } 96 97 func getClaims(token *jwt.Token) (*authClaims, error) { 98 payload, err := json.Marshal(token.Claims); if err != nil { 99 return nil, err 100 } 101 claims := &authClaims{} 102 103 if err = json.Unmarshal(payload, claims); err != nil { 104 return nil, err 105 } 106 return claims, nil 107 }