Compare commits
No commits in common. "2e0596c924abd850fa65cc96e8b63fb9cf36cb9d" and "615f1184ab8c4ca4fe57ad10c3e66f662c09e59a" have entirely different histories.
2e0596c924
...
615f1184ab
@ -1,7 +1,4 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
type UserDto struct {
|
type UserDto struct {
|
||||||
Id int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Scopes string `json:"scopes"`
|
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,3 @@ package domain
|
|||||||
type HelloBodyRequest struct {
|
type HelloBodyRequest struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddScopeRequest struct {
|
|
||||||
Username string `json:"name"`
|
|
||||||
Scopes []string `json:"scopes" validate:"required"`
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
type ErrorResponse struct {
|
type ErrorResponse struct {
|
||||||
Success bool `json:"success"`
|
HttpCode int `json:"code"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"go-cook/api/domain"
|
"go-cook/api/domain"
|
||||||
"go-cook/api/repositories"
|
"go-cook/api/repositories"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@ -16,43 +18,120 @@ const (
|
|||||||
ErrJwtExpired = "auth token has expired"
|
ErrJwtExpired = "auth token has expired"
|
||||||
ErrJwtScopeMissing = "required scope is missing"
|
ErrJwtScopeMissing = "required scope is missing"
|
||||||
ErrUserNotFound = "requested user does not exist"
|
ErrUserNotFound = "requested user does not exist"
|
||||||
ErrUsernameAlreadyExists = "the requested username already exists"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handler) AuthRegister(c echo.Context) error {
|
type JwtToken struct {
|
||||||
username := c.FormValue("username")
|
Exp time.Time `json:"exp"`
|
||||||
password := c.FormValue("password")
|
Iss string `json:"iss"`
|
||||||
|
Authorized bool `json:"authorized"`
|
||||||
|
UserName string `json:"username"`
|
||||||
|
Scopes []string `json:"scopes"`
|
||||||
|
jwt.RegisteredClaims
|
||||||
|
}
|
||||||
|
|
||||||
//username := c.QueryParam("username")
|
func (j JwtToken) IsValid(scope string) error {
|
||||||
exists, err := h.userRepo.GetByName(username)
|
err := j.hasExpired()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = j.hasScope(scope)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j JwtToken) hasExpired() error {
|
||||||
|
// Check to see if the token has expired
|
||||||
|
hasExpired := j.Exp.Compare(time.Now())
|
||||||
|
if hasExpired == -1 {
|
||||||
|
return errors.New(ErrJwtExpired)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j JwtToken) hasScope(scope string) error {
|
||||||
|
// they have the scope to access everything, so let them pass.
|
||||||
|
if strings.Contains(domain.ScopeAll, scope) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range j.Scopes {
|
||||||
|
if strings.Contains(s, scope) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.New(ErrJwtScopeMissing)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) generateJwt(username string) (string, error) {
|
||||||
|
secret := []byte(h.Config.JwtSecret)
|
||||||
|
|
||||||
|
token := jwt.New(jwt.SigningMethodHS256)
|
||||||
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
|
claims["exp"] = time.Now().Add(10 * time.Minute)
|
||||||
|
claims["authorized"] = true
|
||||||
|
claims["username"] = username
|
||||||
|
|
||||||
|
var scopes []string
|
||||||
|
scopes = append(scopes, domain.ScopeRecipeRead)
|
||||||
|
claims["scopes"] = scopes
|
||||||
|
|
||||||
|
tokenString, err := token.SignedString(secret)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenString, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) generateAdminJwt(username string) (string, error) {
|
||||||
|
secret := []byte(h.Config.JwtSecret)
|
||||||
|
|
||||||
|
token := jwt.New(jwt.SigningMethodHS256)
|
||||||
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
|
claims["exp"] = time.Now().Add(10 * time.Minute)
|
||||||
|
claims["authorized"] = true
|
||||||
|
claims["username"] = username
|
||||||
|
claims["scopes"] = domain.ScopeAll
|
||||||
|
|
||||||
|
tokenString, err := token.SignedString(secret)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenString, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) AuthRegister(c echo.Context) error {
|
||||||
|
username := c.QueryParam("username")
|
||||||
|
_, err := h.userRepo.GetByName(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// if we have an err, validate that if its not user not found.
|
// if we have an err, validate that if its not user not found.
|
||||||
// if the user is not found, we can use that name
|
// if the user is not found, we can use that name
|
||||||
if err.Error() != repositories.ErrUserNotFound {
|
if err.Error() != repositories.ErrUserNotFound {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
|
HttpCode: http.StatusInternalServerError,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
Success: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if exists.Name == username {
|
|
||||||
return h.InternalServerErrorResponse(c, ErrUsernameAlreadyExists)
|
|
||||||
}
|
|
||||||
|
|
||||||
//password := c.QueryParam("password")
|
password := c.QueryParam("password")
|
||||||
err = h.UserService.CheckPasswordForRequirements(password)
|
err = h.UserService.CheckPasswordForRequirements(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Success: false,
|
HttpCode: http.StatusInternalServerError,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = h.userRepo.Create(username, password, domain.ScopeRecipeRead)
|
_, err = h.userRepo.Create(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Success: false,
|
HttpCode: http.StatusInternalServerError,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -61,12 +140,21 @@ func (h *Handler) AuthRegister(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) AuthLogin(c echo.Context) error {
|
func (h *Handler) AuthLogin(c echo.Context) error {
|
||||||
username := c.FormValue("name")
|
username := c.QueryParam("username")
|
||||||
password := c.FormValue("password")
|
password := c.QueryParam("password")
|
||||||
|
|
||||||
// Check to see if they are trying to login with the admin token
|
// Check to see if they are trying to login with the admin token
|
||||||
if username == "" {
|
if username == "" {
|
||||||
return h.validateAdminToken(c, password)
|
if h.Config.AdminToken != password {
|
||||||
|
return h.ReturnUnauthorizedResponse(c, ErrUserNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := h.generateAdminJwt("admin")
|
||||||
|
if err != nil {
|
||||||
|
return h.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the user exists
|
// check if the user exists
|
||||||
@ -89,55 +177,9 @@ func (h *Handler) AuthLogin(c echo.Context) error {
|
|||||||
return c.JSON(http.StatusOK, token)
|
return c.JSON(http.StatusOK, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) validateAdminToken(c echo.Context, password string) error {
|
//func (h *Handler) AddScope(c echo.Context) error {
|
||||||
if h.Config.AdminToken != password {
|
//
|
||||||
return h.ReturnUnauthorizedResponse(c, ErrUserNotFound)
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
token, err := h.generateAdminJwt("admin")
|
|
||||||
if err != nil {
|
|
||||||
return h.InternalServerErrorResponse(c, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) AddScope(c echo.Context) error {
|
|
||||||
token, err := h.getJwtToken(c)
|
|
||||||
if err != nil {
|
|
||||||
return h.ReturnUnauthorizedResponse(c, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = token.IsValid(domain.ScopeAll)
|
|
||||||
if err != nil {
|
|
||||||
return h.ReturnUnauthorizedResponse(c, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
request := domain.AddScopeRequest{}
|
|
||||||
err = (&echo.DefaultBinder{}).BindBody(c, &request)
|
|
||||||
if err != nil {
|
|
||||||
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
|
||||||
Success: false,
|
|
||||||
Message: err.Error(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.UserService.AddScopes(request.Username, request.Scopes)
|
|
||||||
if err != nil {
|
|
||||||
return h.InternalServerErrorResponse(c, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, domain.ErrorResponse{
|
|
||||||
Success: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) RemoveScope(c echo.Context) error {
|
|
||||||
return c.JSON(http.StatusOK, domain.ErrorResponse{
|
|
||||||
Success: false,
|
|
||||||
Message: "Not Implemented",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) RefreshJwtToken(c echo.Context) error {
|
func (h *Handler) RefreshJwtToken(c echo.Context) error {
|
||||||
return nil
|
return nil
|
||||||
|
@ -37,14 +37,10 @@ func (h *Handler) Register(v1 *echo.Group) {
|
|||||||
SigningKey: []byte(h.Config.JwtSecret),
|
SigningKey: []byte(h.Config.JwtSecret),
|
||||||
}
|
}
|
||||||
|
|
||||||
auth := v1.Group("/auth")
|
v1.POST("/login", h.AuthLogin)
|
||||||
auth.POST("/login", h.AuthLogin)
|
v1.POST("/register", h.AuthRegister)
|
||||||
auth.POST("/register", h.AuthRegister)
|
|
||||||
auth.Use(echojwt.WithConfig(jwtConfig))
|
|
||||||
auth.POST("/scopes/add", h.AddScope)
|
|
||||||
//auth.POST("/refresh", h.RefreshJwtToken)
|
|
||||||
|
|
||||||
demo := v1.Group("/demo")
|
demo := v1.Group("/demo")
|
||||||
|
|
||||||
demo.GET("/hello", h.DemoHello)
|
demo.GET("/hello", h.DemoHello)
|
||||||
demo.GET("/hello/:who", h.HelloWho)
|
demo.GET("/hello/:who", h.HelloWho)
|
||||||
|
|
||||||
@ -65,14 +61,14 @@ func (h *Handler) Register(v1 *echo.Group) {
|
|||||||
|
|
||||||
func (h *Handler) ReturnUnauthorizedResponse(c echo.Context, message string) error {
|
func (h *Handler) ReturnUnauthorizedResponse(c echo.Context, message string) error {
|
||||||
return c.JSON(http.StatusUnauthorized, domain.ErrorResponse{
|
return c.JSON(http.StatusUnauthorized, domain.ErrorResponse{
|
||||||
Success: false,
|
HttpCode: http.StatusUnauthorized,
|
||||||
Message: message,
|
Message: message,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) InternalServerErrorResponse(c echo.Context, message string) error {
|
func (h *Handler) InternalServerErrorResponse(c echo.Context, message string) error {
|
||||||
return c.JSON(http.StatusServiceUnavailable, domain.ErrorResponse{
|
return c.JSON(http.StatusServiceUnavailable, domain.ErrorResponse{
|
||||||
Success: false,
|
HttpCode: http.StatusInternalServerError,
|
||||||
Message: message,
|
Message: message,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"go-cook/api/domain"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
|
||||||
)
|
|
||||||
|
|
||||||
type JwtToken struct {
|
|
||||||
Exp time.Time `json:"exp"`
|
|
||||||
Iss string `json:"iss"`
|
|
||||||
Authorized bool `json:"authorized"`
|
|
||||||
UserName string `json:"username"`
|
|
||||||
Scopes []string `json:"scopes"`
|
|
||||||
jwt.RegisteredClaims
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j JwtToken) IsValid(scope string) error {
|
|
||||||
err := j.hasExpired()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = j.hasScope(scope)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j JwtToken) hasExpired() error {
|
|
||||||
// Check to see if the token has expired
|
|
||||||
hasExpired := j.Exp.Compare(time.Now())
|
|
||||||
if hasExpired == -1 {
|
|
||||||
return errors.New(ErrJwtExpired)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j JwtToken) hasScope(scope string) error {
|
|
||||||
// they have the scope to access everything, so let them pass.
|
|
||||||
if strings.Contains(domain.ScopeAll, scope) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range j.Scopes {
|
|
||||||
if strings.Contains(s, scope) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors.New(ErrJwtScopeMissing)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) generateJwt(username string) (string, error) {
|
|
||||||
secret := []byte(h.Config.JwtSecret)
|
|
||||||
|
|
||||||
token := jwt.New(jwt.SigningMethodHS256)
|
|
||||||
claims := token.Claims.(jwt.MapClaims)
|
|
||||||
claims["exp"] = time.Now().Add(10 * time.Minute)
|
|
||||||
claims["authorized"] = true
|
|
||||||
claims["username"] = username
|
|
||||||
|
|
||||||
var scopes []string
|
|
||||||
scopes = append(scopes, domain.ScopeRecipeRead)
|
|
||||||
claims["scopes"] = scopes
|
|
||||||
|
|
||||||
tokenString, err := token.SignedString(secret)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokenString, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) generateAdminJwt(username string) (string, error) {
|
|
||||||
secret := []byte(h.Config.JwtSecret)
|
|
||||||
|
|
||||||
token := jwt.New(jwt.SigningMethodHS256)
|
|
||||||
claims := token.Claims.(jwt.MapClaims)
|
|
||||||
claims["exp"] = time.Now().Add(10 * time.Minute)
|
|
||||||
claims["authorized"] = true
|
|
||||||
claims["username"] = username
|
|
||||||
|
|
||||||
var scopes []string
|
|
||||||
scopes = append(scopes, domain.ScopeAll)
|
|
||||||
claims["scopes"] = scopes
|
|
||||||
|
|
||||||
tokenString, err := token.SignedString(secret)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokenString, nil
|
|
||||||
}
|
|
@ -18,11 +18,11 @@ const (
|
|||||||
|
|
||||||
type IUserTable interface {
|
type IUserTable interface {
|
||||||
GetByName(name string) (domain.UserEntity, error)
|
GetByName(name string) (domain.UserEntity, error)
|
||||||
Create(name, password, scope string) (int64, error)
|
Create(name, password string) (int64, error)
|
||||||
Update(id int, entity domain.UserEntity) error
|
Update(id int, entity domain.UserEntity) error
|
||||||
UpdatePassword(name, password string) error
|
UpdatePassword(name, password string) error
|
||||||
CheckUserHash(name, password string) error
|
CheckUserHash(name, password string) error
|
||||||
UpdateScopes(name, scope string) error
|
AddScope(name, scope string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new instance of UserRepository with the bound sql
|
// Creates a new instance of UserRepository with the bound sql
|
||||||
@ -56,7 +56,7 @@ func (ur UserRepository) GetByName(name string) (domain.UserEntity, error) {
|
|||||||
return data[0], nil
|
return data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur UserRepository) Create(name, password, scope string) (int64, error) {
|
func (ur UserRepository) Create(name, password string) (int64, error) {
|
||||||
passwordBytes := []byte(password)
|
passwordBytes := []byte(password)
|
||||||
hash, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
|
hash, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -66,8 +66,8 @@ func (ur UserRepository) Create(name, password, scope string) (int64, error) {
|
|||||||
dt := time.Now()
|
dt := time.Now()
|
||||||
queryBuilder := sqlbuilder.NewInsertBuilder()
|
queryBuilder := sqlbuilder.NewInsertBuilder()
|
||||||
queryBuilder.InsertInto("users")
|
queryBuilder.InsertInto("users")
|
||||||
queryBuilder.Cols("Name", "Hash", "LastUpdated", "CreatedAt", "Scopes")
|
queryBuilder.Cols("Name", "Hash", "LastUpdated", "CreatedAt")
|
||||||
queryBuilder.Values(name, string(hash), dt, dt, scope)
|
queryBuilder.Values(name, string(hash), dt, dt)
|
||||||
query, args := queryBuilder.Build()
|
query, args := queryBuilder.Build()
|
||||||
|
|
||||||
_, err = ur.connection.Exec(query, args...)
|
_, err = ur.connection.Exec(query, args...)
|
||||||
@ -110,7 +110,7 @@ func (ur UserRepository) CheckUserHash(name, password string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur UserRepository) UpdateScopes(name, scope string) error {
|
func (ur UserRepository) AddScope(name, scope string) error {
|
||||||
builder := sqlbuilder.NewUpdateBuilder()
|
builder := sqlbuilder.NewUpdateBuilder()
|
||||||
builder.Update("users")
|
builder.Update("users")
|
||||||
builder.Set (
|
builder.Set (
|
||||||
|
@ -2,7 +2,6 @@ package repositories_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"go-cook/api/domain"
|
|
||||||
"go-cook/api/repositories"
|
"go-cook/api/repositories"
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
@ -21,7 +20,7 @@ func TestCanCreateNewUser(t *testing.T) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
repo := repositories.NewUserRepository(db)
|
repo := repositories.NewUserRepository(db)
|
||||||
updated, err := repo.Create("testing", "NotSecure", domain.ScopeRecipeRead)
|
updated, err := repo.Create("testing", "NotSecure")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
@ -53,70 +53,13 @@ func (us UserService) GetUser(username string) (domain.UserEntity, error) {
|
|||||||
return us.repo.GetByName(username)
|
return us.repo.GetByName(username)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us UserService) AddScopes(username string, scopes []string) error {
|
func (us UserService) CreateNewUser(name, password string) (domain.UserEntity, error) {
|
||||||
usr, err := us.repo.GetByName(username)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if usr.Name != username {
|
|
||||||
return errors.New(repositories.ErrUserNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
newScopes := strings.Split(usr.Scopes, ",")
|
|
||||||
|
|
||||||
// check the current scopes
|
|
||||||
for _, item := range strings.Split(usr.Scopes, ",") {
|
|
||||||
if !us.doesScopeExist(scopes, item) {
|
|
||||||
newScopes = append(newScopes, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return us.repo.UpdateScopes(username, strings.Join(newScopes, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (us UserService) RemoveScopes(username string, scopes []string) error {
|
|
||||||
usr, err := us.repo.GetByName(username)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if usr.Name != username {
|
|
||||||
return errors.New(repositories.ErrUserNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
var newScopes []string
|
|
||||||
|
|
||||||
// check all the scopes that are currently assigned
|
|
||||||
for _, item := range strings.Split(usr.Scopes, ",") {
|
|
||||||
|
|
||||||
// check the scopes given, if one matches skip it
|
|
||||||
if us.doesScopeExist(scopes, item) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// did not match, add it
|
|
||||||
newScopes = append(newScopes, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
return us.repo.UpdateScopes(username, strings.Join(newScopes, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (us UserService) doesScopeExist(scopes []string, target string) bool {
|
|
||||||
for _, item := range scopes {
|
|
||||||
if item == target {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (us UserService) CreateNewUser(name, password, scope string) (domain.UserEntity, error) {
|
|
||||||
err := us.CheckPasswordForRequirements(password)
|
err := us.CheckPasswordForRequirements(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.UserEntity{}, err
|
return domain.UserEntity{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
us.repo.Create(name, password, domain.ScopeRecipeRead)
|
us.repo.Create(name, password)
|
||||||
return domain.UserEntity{}, nil
|
return domain.UserEntity{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
rest.http
40
rest.http
@ -1,41 +1,7 @@
|
|||||||
### Create a standard User
|
|
||||||
POST http://localhost:1323/api/v1/auth/register?username=test&password=test1234!
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
|
|
||||||
name=test&password=test1234!
|
|
||||||
### Login with user
|
|
||||||
POST http://localhost:1323/api/v1/auth/login
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
|
|
||||||
name=test&password=test1234!
|
|
||||||
|
|
||||||
### Login with the admin token
|
|
||||||
POST http://localhost:1323/api/v1/auth/login
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
|
|
||||||
password=lol
|
|
||||||
|
|
||||||
|
|
||||||
### Add Scope to test user
|
|
||||||
POST http://localhost:1323/api/v1/auth/scopes/add
|
|
||||||
Content-Type: application/json
|
|
||||||
Authorization: Bearer
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "test",
|
|
||||||
"scopes": [
|
|
||||||
"recipe:create"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
### Remove scope from test user
|
|
||||||
POST http://localhost:1323/api/v1/auth/scopes/remove
|
|
||||||
Content-Type: application/json
|
|
||||||
Authorization: Bearer
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
POST http://localhost:1323/api/v1/
|
POST http://localhost:1323/api/v1/register?username=test&password=test1234!
|
||||||
|
###
|
||||||
|
POST http://localhost:1323/api/v1/login?username=test&password=test1234!
|
||||||
###
|
###
|
||||||
GET http://localhost:1323/api/v1/demo/hello
|
GET http://localhost:1323/api/v1/demo/hello
|
||||||
###
|
###
|
||||||
|
Loading…
Reference in New Issue
Block a user