step 3 : login absensi fix, return graphql staff
This commit is contained in:
70
backend/pkg/auth/middleware.go
Normal file
70
backend/pkg/auth/middleware.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"com.sismedika.com.absensi/graph/model"
|
||||
"com.sismedika.com.absensi/pkg/jwt"
|
||||
)
|
||||
|
||||
var userCtxKey = &contextKey{"user"}
|
||||
|
||||
type contextKey struct {
|
||||
name string
|
||||
}
|
||||
|
||||
type AuthRequest struct {
|
||||
isAuthenticated bool
|
||||
staff model.Staff
|
||||
}
|
||||
|
||||
func Middleware() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
header := r.Header.Get("Authorization")
|
||||
AuthStatus := AuthRequest{isAuthenticated: false}
|
||||
// Allow unauthenticated users in
|
||||
if header == "" {
|
||||
ctx := context.WithValue(r.Context(), userCtxKey, &AuthStatus)
|
||||
r = r.WithContext(ctx)
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// validate jwt token
|
||||
tokenParts := strings.Split(header, " ")
|
||||
var tokenStr string
|
||||
if len(tokenParts) == 2 && tokenParts[0] == "Bearer" {
|
||||
tokenStr = tokenParts[1]
|
||||
}
|
||||
email, idGoogleSignIn, err := jwt.ParseToken(tokenStr)
|
||||
if err != nil {
|
||||
log.Printf("ParseToken: %v\n", err)
|
||||
ctx := context.WithValue(r.Context(), userCtxKey, &AuthStatus)
|
||||
r = r.WithContext(ctx)
|
||||
next.ServeHTTP(w, r)
|
||||
// boom.Unathorized(w, fmt.Errorf("AUTHORIZATION_HEADER_INVALID"))
|
||||
return
|
||||
}
|
||||
AuthStatus.staff = model.Staff{
|
||||
Email: email,
|
||||
IDGoogleSignIn: idGoogleSignIn,
|
||||
}
|
||||
// put it in context
|
||||
ctx := context.WithValue(r.Context(), userCtxKey, &AuthStatus)
|
||||
|
||||
// and call the next with our new context
|
||||
r = r.WithContext(ctx)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ForContext finds the user from the context. REQUIRES Middleware to have run.
|
||||
func ForContext(ctx context.Context) *model.User {
|
||||
raw, _ := ctx.Value(userCtxKey).(*model.User)
|
||||
return raw
|
||||
}
|
||||
@@ -12,15 +12,14 @@ import (
|
||||
// var conf = config.Data
|
||||
|
||||
// GenerateToken generates a jwt token and assign a username to it's claims and return it
|
||||
func GenerateToken(user_id int, username string, staff_id int) (string, int64, error) {
|
||||
func GenerateToken(M_StaffEmail string, M_StaffIDGoogleSignIn string) (string, int64, error) {
|
||||
token := jwt.New(jwt.SigningMethodHS256)
|
||||
/* Create a map to store our claims */
|
||||
claims := token.Claims.(jwt.MapClaims)
|
||||
/* Set token claims */
|
||||
expired := time.Now().Add(time.Minute * time.Duration(config.Data.GetInt("tokenExpiration"))).Unix()
|
||||
claims["user_id"] = user_id
|
||||
claims["user_name"] = username
|
||||
claims["staff_id"] = staff_id
|
||||
claims["M_StaffIDGoogleSignIn"] = M_StaffIDGoogleSignIn
|
||||
claims["M_StaffEmail"] = M_StaffEmail
|
||||
claims["exp"] = expired
|
||||
tokenString, err := token.SignedString([]byte(config.Data.Get("secretkey")))
|
||||
if err != nil {
|
||||
@@ -30,7 +29,7 @@ func GenerateToken(user_id int, username string, staff_id int) (string, int64, e
|
||||
}
|
||||
|
||||
// ParseToken parses a jwt token and returns the username in it's claims
|
||||
func ParseToken(tokenStr string) (int, string, int, error) {
|
||||
func ParseToken(tokenStr string) (string, string, error) {
|
||||
claims := jwt.MapClaims{}
|
||||
|
||||
token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
|
||||
@@ -41,38 +40,34 @@ func ParseToken(tokenStr string) (int, string, int, error) {
|
||||
|
||||
if v.Errors == jwt.ValidationErrorExpired {
|
||||
log.Printf("parse token 1: %v\n", err)
|
||||
return 0, "", 0, fmt.Errorf("TOKEN_EXPIRED")
|
||||
return "", "", fmt.Errorf("TOKEN_EXPIRED")
|
||||
}
|
||||
|
||||
log.Printf("parse token 2: %v\n", err)
|
||||
return 0, "", 0, fmt.Errorf("TOKEN_INVALID")
|
||||
return "", "", fmt.Errorf("TOKEN_INVALID")
|
||||
}
|
||||
|
||||
if !token.Valid {
|
||||
log.Printf("token invalid: %v\n", err)
|
||||
return 0, "", 0, fmt.Errorf(("TOKEN_INVALID"))
|
||||
return "", "", fmt.Errorf(("TOKEN_INVALID"))
|
||||
}
|
||||
|
||||
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
if !ok {
|
||||
return 0, "", 0, fmt.Errorf(("TOKEN_INVALID"))
|
||||
return "", "", fmt.Errorf(("TOKEN_INVALID"))
|
||||
}
|
||||
// type of user_id is float64: https://stackoverflow.com/questions/70705673/panic-interface-conversion-interface-is-float64-not-int64
|
||||
if claims["user_id"] == nil {
|
||||
return 0, "", 0, fmt.Errorf(("TOKEN_INVALID"))
|
||||
if claims["M_StaffIDGoogleSignIn"] == nil {
|
||||
return "", "", fmt.Errorf(("TOKEN_INVALID"))
|
||||
}
|
||||
if claims["user_name"] == nil {
|
||||
return 0, "", 0, fmt.Errorf(("TOKEN_INVALID"))
|
||||
if claims["M_StaffEmail"] == nil {
|
||||
return "", "", fmt.Errorf(("TOKEN_INVALID"))
|
||||
}
|
||||
if claims["staff_id"] == nil {
|
||||
return 0, "", 0, fmt.Errorf(("TOKEN_INVALID"))
|
||||
}
|
||||
user_id := int(claims["user_id"].(float64))
|
||||
user_name := claims["user_name"].(string)
|
||||
staff_id := int(claims["practitioner_id"].(float64))
|
||||
return user_id, user_name, staff_id, nil
|
||||
M_StaffIDGoogleSignIn := claims["M_StaffIDGoogleSignIn"].(string)
|
||||
M_StaffEmail := claims["M_StaffEmail"].(string)
|
||||
return M_StaffIDGoogleSignIn, M_StaffEmail, nil
|
||||
} else {
|
||||
log.Printf("token claims: %v\n", err)
|
||||
return 0, "", 0, fmt.Errorf(("TOKEN_INVALID"))
|
||||
return "", "", fmt.Errorf(("TOKEN_INVALID"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user