t2/services/authorization.go

91 lines
1.7 KiB
Go

package services
import (
"errors"
"time"
"github.com/golang-jwt/jwt"
)
var (
users = map[string]string{
"henri": "henri123",
}
secret = []byte("mein-secret")
)
type Session struct {
Username string
Expiry time.Time
}
type Credentials struct {
Password string
Username string
}
func (s Session) IsExpired() bool {
return s.Expiry.Before(time.Now())
}
func Signin(cred Credentials) (string, time.Time, error) {
expectedPassword, ok := users[cred.Username]
if !ok || expectedPassword != cred.Password {
return "", time.Time{}, errors.New("wrong password")
}
expiresAt := time.Now().Add(2 * time.Hour)
sessionToken, err := tokenFromSession(Session{
Username: cred.Username,
Expiry: expiresAt,
})
if err != nil {
return "", time.Time{}, err
}
return sessionToken, expiresAt, nil
}
func GetSession(sessionToken string) (*Session, error) {
return sessionFromToken(sessionToken)
}
func RemoveSession(sessionID string) {
}
func tokenFromSession(session Session) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256,
jwt.MapClaims{
"username": session.Username,
"exp": session.Expiry.Unix(),
})
return token.SignedString(secret)
}
func sessionFromToken(tokenString string) (*Session, error) {
sessionToken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return secret, nil
})
if err != nil {
return nil, err
}
if !sessionToken.Valid {
return nil, errors.New("invalid token")
}
if claims, ok := sessionToken.Claims.(jwt.MapClaims); ok {
expiresAt := time.Unix(int64(claims["exp"].(float64)), 0)
return &Session{
Username: claims["username"].(string),
Expiry: expiresAt,
}, nil
} else {
return nil, errors.New("cannot read claims")
}
}