You've already forked golang-saas-starter-kit
mirror of
https://github.com/raseels-repos/golang-saas-starter-kit.git
synced 2025-07-17 01:42:36 +02:00
fixed user oauth token to support form post
This commit is contained in:
@ -41,7 +41,7 @@ func (c *Signup) Signup(ctx context.Context, w http.ResponseWriter, r *http.Requ
|
||||
|
||||
// Claims are optional as authentication is not required ATM for this method.
|
||||
claims, _ := auth.ClaimsFromContext(ctx)
|
||||
|
||||
|
||||
var req signup.SignupRequest
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user_auth"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
@ -467,10 +468,15 @@ func (u *User) SwitchAccount(ctx context.Context, w http.ResponseWriter, r *http
|
||||
// @Summary Token handles a request to authenticate a user.
|
||||
// @Description Token generates an oauth2 accessToken using Basic Auth with a user's email and password.
|
||||
// @Tags user
|
||||
// @Accept json
|
||||
// @Accept x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Security BasicAuth
|
||||
// @Param scope query string false "Scope" Enums(user, admin)
|
||||
// @Param username formData string true "Email"
|
||||
// @Param password formData string true "Password"
|
||||
// @Param account_id formData string false "Account ID"
|
||||
// @Param scope formData {array} string true "Scope" Enums(user, admin)
|
||||
// @Param scope query {array} string false "Scope" Enums(user, admin)
|
||||
// @Param account_id query string false "Account ID"
|
||||
// @Success 200
|
||||
// @Failure 400 {object} weberror.ErrorResponse
|
||||
// @Failure 401 {object} weberror.ErrorResponse
|
||||
@ -482,22 +488,56 @@ func (u *User) Token(ctx context.Context, w http.ResponseWriter, r *http.Request
|
||||
return err
|
||||
}
|
||||
|
||||
var authReq user_auth.AuthenticateRequest
|
||||
var scopes []string
|
||||
|
||||
email, pass, ok := r.BasicAuth()
|
||||
if !ok {
|
||||
err := errors.New("must provide email and password in Basic auth")
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusUnauthorized))
|
||||
if !ok || email == "" {
|
||||
if r.Method == http.MethodPost {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
decoder := schema.NewDecoder()
|
||||
decoder.IgnoreUnknownKeys(true)
|
||||
|
||||
var req user_auth.OAuth2PasswordRequest
|
||||
if err := decoder.Decode(&req, r.PostForm); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
// Validate the request.
|
||||
err = webcontext.Validator().StructCtx(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authReq.Email = req.Username
|
||||
authReq.Password = req.Password
|
||||
scopes = req.Scope
|
||||
} else {
|
||||
err := errors.New("must provide email and password in Basic auth")
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusUnauthorized))
|
||||
}
|
||||
} else {
|
||||
authReq.Email = email
|
||||
authReq.Password = pass
|
||||
}
|
||||
|
||||
accountID := r.URL.Query().Get("account_id")
|
||||
if qv := r.URL.Query().Get("account_id"); qv != "" {
|
||||
authReq.AccountID = qv
|
||||
}
|
||||
|
||||
// Optional to include scope.
|
||||
scope := r.URL.Query().Get("scope")
|
||||
if qv := r.URL.Query().Get("scope"); qv != "" {
|
||||
scopes = strings.Split(qv, ",")
|
||||
}
|
||||
|
||||
tkn, err := user_auth.Authenticate(ctx, u.MasterDB, u.TokenGenerator, user_auth.AuthenticateRequest{
|
||||
Email: email,
|
||||
Password: pass,
|
||||
AccountID: accountID,
|
||||
}, sessionTtl, v.Now, scope)
|
||||
tkn, err := user_auth.Authenticate(ctx, u.MasterDB, u.TokenGenerator, authReq, sessionTtl, v.Now, scopes...)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
|
@ -148,7 +148,7 @@ func newValidator() *validator.Validate {
|
||||
|
||||
// Second check if the default unique key is set in context.
|
||||
if cv == nil {
|
||||
cv := ctx.Value(KeyTagUnique)
|
||||
cv = ctx.Value(KeyTagUnique)
|
||||
if cv == nil {
|
||||
return false
|
||||
}
|
||||
|
@ -13,6 +13,15 @@ type AuthenticateRequest struct {
|
||||
AccountID string `json:"account_id" validate:"omitempty,uuid" example:"c4653bf9-5978-48b7-89c5-95704aebb7e2"`
|
||||
}
|
||||
|
||||
// OAuth2PasswordRequest defines what information is required to authenticate a user.
|
||||
type OAuth2PasswordRequest struct {
|
||||
Username string `json:"username" schema:"username" validate:"required,email" example:"gabi.may@geeksinthewoods.com"`
|
||||
Password string `json:"password" schema:"password" validate:"required" example:"NeverTellSecret"`
|
||||
AccountID string `json:"account_id" schema:"account_id" validate:"omitempty,uuid" example:"c4653bf9-5978-48b7-89c5-95704aebb7e2"`
|
||||
Scope []string `json:"scope" schema:"scope" validate:"omitempty,dive,oneof=admin user" enums:"admin,user" swaggertype:"array,string" example:"admin"`
|
||||
// GrantType string `json:"grant_type" validate:"omitempty" example:"password"`
|
||||
}
|
||||
|
||||
// Token is the payload we deliver to users when they authenticate.
|
||||
type Token struct {
|
||||
// AccessToken is the token that authorizes and authenticates
|
||||
|
Reference in New Issue
Block a user