package gpaste import ( "fmt" "time" "git.t-juice.club/torjus/gpaste/users" "github.com/golang-jwt/jwt" "github.com/google/uuid" ) type AuthLevel int const ( AuthLevelUnset AuthLevel = iota AuthLevelUser AuthLevelAdmin ) type AuthService struct { users users.UserStore hmacSecret []byte } type Claims struct { Role users.Role `json:"role,omitempty"` jwt.StandardClaims } func NewAuthService(store users.UserStore, signingSecret []byte) *AuthService { return &AuthService{users: store, hmacSecret: signingSecret} } func (as *AuthService) Login(username, password string) (string, error) { user, err := as.users.Get(username) if err != nil { return "", err } if err := user.ValidatePassword(password); err != nil { return "", err } // TODO: Set iss and aud claims := new(Claims) claims.Subject = user.Username claims.ExpiresAt = time.Now().Add(7 * 24 * time.Hour).Unix() claims.NotBefore = time.Now().Unix() claims.IssuedAt = time.Now().Unix() claims.Id = uuid.NewString() claims.Role = user.Role token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), claims) signed, err := token.SignedString(as.hmacSecret) if err != nil { return "", err } return signed, nil } func (as *AuthService) ValidateToken(rawToken string) (*Claims, error) { claims := &Claims{} token, err := jwt.ParseWithClaims(rawToken, claims, func(t *jwt.Token) (interface{}, error) { return as.hmacSecret, nil }) if err != nil { return nil, err } if !token.Valid { return nil, fmt.Errorf("invalid token") } return claims, nil }