package auth import ( "errors" "net/http" "time" "github.com/golang-jwt/jwt/v5" ) type EasyAuth struct { client Auth jwtSecret []byte } type UserClaims struct { jwt.RegisteredClaims User AuthentikUser } func NewEasyAuth(client Auth) (EasyAuth, error) { e := EasyAuth{} e.client = client e.jwtSecret = []byte("hsajedogö") return e, nil } func (e EasyAuth) GetUser(w http.ResponseWriter, r *http.Request) (AuthentikUser, bool, error) { if r.Method == http.MethodGet { setCookie(w, "url", r.URL.String(), time.Now().Add(1*time.Minute)) } cookieValue, err := getCookie(w, r, "jwt") if err != nil { return AuthentikUser{}, false, err } if cookieValue == "" { e.redirectAuth(w, r) return AuthentikUser{}, false, nil } parsedAccessToken, _ := jwt.ParseWithClaims(cookieValue, &UserClaims{}, func(token *jwt.Token) (interface{}, error) { return e.jwtSecret, nil }) claims := parsedAccessToken.Claims.(*UserClaims) return claims.User, true, nil } func (e EasyAuth) redirectAuth(w http.ResponseWriter, r *http.Request) error { redirectURL, err := e.client.GetAuthorizationURL("") if err != nil { return err } http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect) return nil } func (e EasyAuth) AuthHTTPHandler(w http.ResponseWriter, r *http.Request) { token, err := e.client.GetTokenFromCode(r.URL.Query().Get("code")) if err != nil { panic(err) // TODO: Deal with error } user := AuthentikUser{} err = e.client.GetUserInfo(token.AccessToken, &user) if err != nil { panic(err) // TODO: Deal with error } expired := time.Now().Add(5 * time.Minute) claims := UserClaims{} claims.Issuer = "EasyAuth" claims.Subject = user.Nickname claims.IssuedAt = jwt.NewNumericDate(time.Now()) claims.ExpiresAt = jwt.NewNumericDate(expired) claims.NotBefore = jwt.NewNumericDate(time.Now()) claims.User = user jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) jwtString, err := jwtToken.SignedString(e.jwtSecret) if err != nil { panic(err) // TODO: Deal with error } setCookie(w, "jwt", jwtString, expired) redirectURL, err := getCookie(w, r, "url") if err != nil { panic(err) // TODO: Deal with error } if redirectURL == "" { redirectURL = "/" } http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect) } func getCookie(w http.ResponseWriter, r *http.Request, name string) (string, error) { cookie, err := r.Cookie(name) if err != nil { if errors.Is(err, http.ErrNoCookie) { return "", nil } return "", err } return cookie.Value, nil } func setCookie(w http.ResponseWriter, name, value string, expired time.Time) { cookie := http.Cookie{} cookie.Name = name cookie.Value = value cookie.Expires = expired cookie.Path = "/" cookie.MaxAge = int(time.Until(expired).Seconds()) cookie.Secure = true cookie.HttpOnly = true cookie.SameSite = http.SameSiteStrictMode http.SetCookie(w, &cookie) }