mirror of
https://github.com/hay-kot/homebox.git
synced 2025-01-17 19:20:11 +00:00
feat: auth-roles, image-gallery, click-to-open (#166)
* schema changes * db generate * db migration * add role based middleware * implement attachment token access * generate docs * implement role based auth * replace attachment specific tokens with gen token * run linter * cleanup temporary token implementation
This commit is contained in:
parent
974d6914a2
commit
de419dc37d
48 changed files with 3127 additions and 244 deletions
|
@ -15,6 +15,7 @@ type (
|
|||
TokenResponse struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
AttachmentToken string `json:"attachmentToken"`
|
||||
}
|
||||
|
||||
LoginForm struct {
|
||||
|
@ -78,6 +79,7 @@ func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
|||
return server.Respond(w, http.StatusOK, TokenResponse{
|
||||
Token: "Bearer " + newToken.Raw,
|
||||
ExpiresAt: newToken.ExpiresAt,
|
||||
AttachmentToken: newToken.AttachmentToken,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,7 @@ package v1
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
|
@ -100,46 +97,11 @@ func (ctrl *V1Controller) HandleItemAttachmentCreate() server.HandlerFunc {
|
|||
// @Tags Items Attachments
|
||||
// @Produce application/octet-stream
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param token query string true "Attachment token"
|
||||
// @Success 200
|
||||
// @Router /v1/items/{id}/attachments/download [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentDownload() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
token := server.GetParam(r, "token", "")
|
||||
|
||||
doc, err := ctrl.svc.Items.AttachmentPath(r.Context(), token)
|
||||
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to get attachment")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
ext := filepath.Ext(doc.Path)
|
||||
|
||||
title := doc.Title
|
||||
|
||||
if !strings.HasSuffix(doc.Title, ext) {
|
||||
title = doc.Title + ext
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", title))
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
http.ServeFile(w, r, doc.Path)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// HandleItemAttachmentToken godocs
|
||||
// @Summary retrieves an attachment for an item
|
||||
// @Tags Items Attachments
|
||||
// @Produce application/octet-stream
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param attachment_id path string true "Attachment ID"
|
||||
// @Success 200 {object} ItemAttachmentToken
|
||||
// @Router /v1/items/{id}/attachments/{attachment_id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentToken() server.HandlerFunc {
|
||||
func (ctrl *V1Controller) HandleItemAttachmentGet() server.HandlerFunc {
|
||||
return ctrl.handleItemAttachmentsHandler
|
||||
}
|
||||
|
||||
|
@ -181,33 +143,15 @@ func (ctrl *V1Controller) handleItemAttachmentsHandler(w http.ResponseWriter, r
|
|||
|
||||
ctx := services.NewContext(r.Context())
|
||||
switch r.Method {
|
||||
// Token Handler
|
||||
case http.MethodGet:
|
||||
token, err := ctrl.svc.Items.AttachmentToken(ctx, ID, attachmentID)
|
||||
doc, err := ctrl.svc.Items.AttachmentPath(r.Context(), attachmentID)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case services.ErrNotFound:
|
||||
log.Err(err).
|
||||
Str("id", attachmentID.String()).
|
||||
Msg("failed to find attachment with id")
|
||||
|
||||
return validate.NewRequestError(err, http.StatusNotFound)
|
||||
|
||||
case services.ErrFileNotFound:
|
||||
log.Err(err).
|
||||
Str("id", attachmentID.String()).
|
||||
Msg("failed to find file path for attachment with id")
|
||||
log.Warn().Msg("attachment with no file path removed from database")
|
||||
|
||||
return validate.NewRequestError(err, http.StatusNotFound)
|
||||
|
||||
default:
|
||||
log.Err(err).Msg("failed to get attachment")
|
||||
log.Err(err).Msg("failed to get attachment path")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, ItemAttachmentToken{Token: token})
|
||||
http.ServeFile(w, r, doc.Path)
|
||||
return nil
|
||||
|
||||
// Delete Attachment Handler
|
||||
case http.MethodDelete:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
@ -10,17 +11,87 @@ import (
|
|||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
)
|
||||
|
||||
type tokenHasKey struct {
|
||||
key string
|
||||
}
|
||||
|
||||
var (
|
||||
hashedToken = tokenHasKey{key: "hashedToken"}
|
||||
)
|
||||
|
||||
type RoleMode int
|
||||
|
||||
const (
|
||||
RoleModeOr RoleMode = 0
|
||||
RoleModeAnd RoleMode = 1
|
||||
)
|
||||
|
||||
// mwRoles is a middleware that will validate the required roles are met. All roles
|
||||
// are required to be met for the request to be allowed. If the user does not have
|
||||
// the required roles, a 403 Forbidden will be returned.
|
||||
//
|
||||
// WARNING: This middleware _MUST_ be called after mwAuthToken or else it will panic
|
||||
func (a *app) mwRoles(rm RoleMode, required ...string) server.Middleware {
|
||||
return func(next server.Handler) server.Handler {
|
||||
return server.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := r.Context()
|
||||
|
||||
maybeToken := ctx.Value(hashedToken)
|
||||
if maybeToken == nil {
|
||||
panic("mwRoles: token not found in context, you must call mwAuthToken before mwRoles")
|
||||
}
|
||||
|
||||
token := maybeToken.(string)
|
||||
|
||||
roles, err := a.repos.AuthTokens.GetRoles(r.Context(), token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
outer:
|
||||
switch rm {
|
||||
case RoleModeOr:
|
||||
for _, role := range required {
|
||||
if roles.Contains(role) {
|
||||
break outer
|
||||
}
|
||||
}
|
||||
return validate.NewRequestError(errors.New("Forbidden"), http.StatusForbidden)
|
||||
case RoleModeAnd:
|
||||
for _, req := range required {
|
||||
if !roles.Contains(req) {
|
||||
return validate.NewRequestError(errors.New("Unauthorized"), http.StatusForbidden)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// mwAuthToken is a middleware that will check the database for a stateful token
|
||||
// and attach it to the request context with the user, or return a 401 if it doesn't exist.
|
||||
// and attach it's user to the request context, or return an appropriate error.
|
||||
// Authorization support is by token via Headers or Query Parameter
|
||||
//
|
||||
// Example:
|
||||
// - header = "Bearer 1234567890"
|
||||
// - query = "?access_token=1234567890"
|
||||
func (a *app) mwAuthToken(next server.Handler) server.Handler {
|
||||
return server.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||
requestToken := r.Header.Get("Authorization")
|
||||
|
||||
if requestToken == "" {
|
||||
return validate.NewRequestError(errors.New("Authorization header is required"), http.StatusUnauthorized)
|
||||
// check for query param
|
||||
requestToken = r.URL.Query().Get("access_token")
|
||||
if requestToken == "" {
|
||||
return validate.NewRequestError(errors.New("Authorization header or query is required"), http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
|
||||
requestToken = strings.TrimPrefix(requestToken, "Bearer ")
|
||||
|
||||
r = r.WithContext(context.WithValue(r.Context(), hashedToken, requestToken))
|
||||
|
||||
usr, err := a.services.User.GetSelf(r.Context(), requestToken)
|
||||
|
||||
// Check the database for the token
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/hay-kot/homebox/backend/app/api/handlers/debughandlers"
|
||||
v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1"
|
||||
_ "github.com/hay-kot/homebox/backend/app/api/static/docs"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
httpSwagger "github.com/swaggo/http-swagger" // http-swagger middleware
|
||||
|
@ -64,49 +65,55 @@ func (a *app) mountRoutes(repos *repo.AllRepos) {
|
|||
a.server.Post(v1Base("/users/register"), v1Ctrl.HandleUserRegistration())
|
||||
a.server.Post(v1Base("/users/login"), v1Ctrl.HandleAuthLogin())
|
||||
|
||||
// Attachment download URl needs a `token` query param to be passed in the request.
|
||||
// and also needs to be outside of the `auth` middleware.
|
||||
a.server.Get(v1Base("/items/{id}/attachments/download"), v1Ctrl.HandleItemAttachmentDownload())
|
||||
userMW := []server.Middleware{
|
||||
a.mwAuthToken,
|
||||
a.mwRoles(RoleModeOr, authroles.RoleUser.String()),
|
||||
}
|
||||
|
||||
a.server.Get(v1Base("/users/self"), v1Ctrl.HandleUserSelf(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/users/self"), v1Ctrl.HandleUserSelfUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/users/self"), v1Ctrl.HandleUserSelfDelete(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/users/logout"), v1Ctrl.HandleAuthLogout(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/users/refresh"), v1Ctrl.HandleAuthRefresh(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/users/self/change-password"), v1Ctrl.HandleUserSelfChangePassword(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/users/self"), v1Ctrl.HandleUserSelf(), userMW...)
|
||||
a.server.Put(v1Base("/users/self"), v1Ctrl.HandleUserSelfUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/users/self"), v1Ctrl.HandleUserSelfDelete(), userMW...)
|
||||
a.server.Post(v1Base("/users/logout"), v1Ctrl.HandleAuthLogout(), userMW...)
|
||||
a.server.Get(v1Base("/users/refresh"), v1Ctrl.HandleAuthRefresh(), userMW...)
|
||||
a.server.Put(v1Base("/users/self/change-password"), v1Ctrl.HandleUserSelfChangePassword(), userMW...)
|
||||
|
||||
a.server.Post(v1Base("/groups/invitations"), v1Ctrl.HandleGroupInvitationsCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/groups/statistics"), v1Ctrl.HandleGroupStatistics(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/groups/invitations"), v1Ctrl.HandleGroupInvitationsCreate(), userMW...)
|
||||
a.server.Get(v1Base("/groups/statistics"), v1Ctrl.HandleGroupStatistics(), userMW...)
|
||||
|
||||
// TODO: I don't like /groups being the URL for users
|
||||
a.server.Get(v1Base("/groups"), v1Ctrl.HandleGroupGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/groups"), v1Ctrl.HandleGroupUpdate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/groups"), v1Ctrl.HandleGroupGet(), userMW...)
|
||||
a.server.Put(v1Base("/groups"), v1Ctrl.HandleGroupUpdate(), userMW...)
|
||||
|
||||
a.server.Post(v1Base("/actions/ensure-asset-ids"), v1Ctrl.HandleEnsureAssetID(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/actions/ensure-asset-ids"), v1Ctrl.HandleEnsureAssetID(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/locations"), v1Ctrl.HandleLocationGetAll(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/locations"), v1Ctrl.HandleLocationCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/locations/{id}"), v1Ctrl.HandleLocationGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/locations/{id}"), v1Ctrl.HandleLocationUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/locations/{id}"), v1Ctrl.HandleLocationDelete(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/locations"), v1Ctrl.HandleLocationGetAll(), userMW...)
|
||||
a.server.Post(v1Base("/locations"), v1Ctrl.HandleLocationCreate(), userMW...)
|
||||
a.server.Get(v1Base("/locations/{id}"), v1Ctrl.HandleLocationGet(), userMW...)
|
||||
a.server.Put(v1Base("/locations/{id}"), v1Ctrl.HandleLocationUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/locations/{id}"), v1Ctrl.HandleLocationDelete(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/labels"), v1Ctrl.HandleLabelsGetAll(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/labels"), v1Ctrl.HandleLabelsCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/labels/{id}"), v1Ctrl.HandleLabelGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/labels/{id}"), v1Ctrl.HandleLabelUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/labels/{id}"), v1Ctrl.HandleLabelDelete(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/labels"), v1Ctrl.HandleLabelsGetAll(), userMW...)
|
||||
a.server.Post(v1Base("/labels"), v1Ctrl.HandleLabelsCreate(), userMW...)
|
||||
a.server.Get(v1Base("/labels/{id}"), v1Ctrl.HandleLabelGet(), userMW...)
|
||||
a.server.Put(v1Base("/labels/{id}"), v1Ctrl.HandleLabelUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/labels/{id}"), v1Ctrl.HandleLabelDelete(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/items"), v1Ctrl.HandleItemsGetAll(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/items/import"), v1Ctrl.HandleItemsImport(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/items"), v1Ctrl.HandleItemsCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/items/{id}"), v1Ctrl.HandleItemGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/items/{id}"), v1Ctrl.HandleItemUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/items/{id}"), v1Ctrl.HandleItemDelete(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/items"), v1Ctrl.HandleItemsGetAll(), userMW...)
|
||||
a.server.Post(v1Base("/items/import"), v1Ctrl.HandleItemsImport(), userMW...)
|
||||
a.server.Post(v1Base("/items"), v1Ctrl.HandleItemsCreate(), userMW...)
|
||||
a.server.Get(v1Base("/items/{id}"), v1Ctrl.HandleItemGet(), userMW...)
|
||||
a.server.Put(v1Base("/items/{id}"), v1Ctrl.HandleItemUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/items/{id}"), v1Ctrl.HandleItemDelete(), userMW...)
|
||||
|
||||
a.server.Post(v1Base("/items/{id}/attachments"), v1Ctrl.HandleItemAttachmentCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentToken(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentDelete(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/items/{id}/attachments"), v1Ctrl.HandleItemAttachmentCreate(), userMW...)
|
||||
a.server.Put(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentDelete(), userMW...)
|
||||
|
||||
a.server.Get(
|
||||
v1Base("/items/{id}/attachments/{attachment_id}"),
|
||||
v1Ctrl.HandleItemAttachmentGet(),
|
||||
a.mwAuthToken, a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()),
|
||||
)
|
||||
|
||||
a.server.NotFound(notFoundHandler())
|
||||
}
|
||||
|
|
|
@ -1966,6 +1966,9 @@ const docTemplate = `{
|
|||
"v1.TokenResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"attachmentToken": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiresAt": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
@ -1958,6 +1958,9 @@
|
|||
"v1.TokenResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"attachmentToken": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiresAt": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
@ -510,6 +510,8 @@ definitions:
|
|||
type: object
|
||||
v1.TokenResponse:
|
||||
properties:
|
||||
attachmentToken:
|
||||
type: string
|
||||
expiresAt:
|
||||
type: string
|
||||
token:
|
||||
|
|
|
@ -38,7 +38,6 @@ func New(repos *repo.AllRepos, opts ...OptionsFunc) *AllServices {
|
|||
Group: &GroupService{repos},
|
||||
Items: &ItemService{
|
||||
repo: repos,
|
||||
at: attachmentTokens{},
|
||||
autoIncrementAssetID: options.autoIncrementAssetID,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@ type ItemService struct {
|
|||
repo *repo.AllRepos
|
||||
|
||||
filepath string
|
||||
// at is a map of tokens to attachment IDs. This is used to store the attachment ID
|
||||
// for issued URLs
|
||||
at attachmentTokens
|
||||
|
||||
autoIncrementAssetID bool
|
||||
}
|
||||
|
|
|
@ -4,71 +4,15 @@ import (
|
|||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// TODO: this isn't a scalable solution, tokens should be stored in the database
|
||||
type attachmentTokens map[string]uuid.UUID
|
||||
|
||||
func (at attachmentTokens) Add(token string, id uuid.UUID) {
|
||||
at[token] = id
|
||||
|
||||
log.Debug().Str("token", token).Str("uuid", id.String()).Msg("added token")
|
||||
|
||||
go func() {
|
||||
ch := time.After(1 * time.Minute)
|
||||
<-ch
|
||||
at.Delete(token)
|
||||
log.Debug().Str("token", token).Msg("deleted token")
|
||||
}()
|
||||
}
|
||||
|
||||
func (at attachmentTokens) Get(token string) (uuid.UUID, bool) {
|
||||
id, ok := at[token]
|
||||
return id, ok
|
||||
}
|
||||
|
||||
func (at attachmentTokens) Delete(token string) {
|
||||
delete(at, token)
|
||||
}
|
||||
|
||||
func (svc *ItemService) AttachmentToken(ctx Context, itemId, attachmentId uuid.UUID) (string, error) {
|
||||
_, err := svc.repo.Items.GetOneByGroup(ctx, ctx.GID, itemId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
token := hasher.GenerateToken()
|
||||
|
||||
// Ensure that the file exists
|
||||
attachment, err := svc.repo.Attachments.Get(ctx, attachmentId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(attachment.Edges.Document.Path); os.IsNotExist(err) {
|
||||
_ = svc.AttachmentDelete(ctx, ctx.GID, itemId, attachmentId)
|
||||
return "", ErrNotFound
|
||||
}
|
||||
|
||||
svc.at.Add(token.Raw, attachmentId)
|
||||
|
||||
return token.Raw, nil
|
||||
}
|
||||
|
||||
func (svc *ItemService) AttachmentPath(ctx context.Context, token string) (*ent.Document, error) {
|
||||
attachmentId, ok := svc.at.Get(token)
|
||||
if !ok {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
|
||||
func (svc *ItemService) AttachmentPath(ctx context.Context, attachmentId uuid.UUID) (*ent.Document, error) {
|
||||
attachment, err := svc.repo.Attachments.Get(ctx, attachmentId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
@ -31,6 +32,7 @@ type (
|
|||
}
|
||||
UserAuthTokenDetail struct {
|
||||
Raw string `json:"raw"`
|
||||
AttachmentToken string `json:"attachmentToken"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
}
|
||||
LoginForm struct {
|
||||
|
@ -131,16 +133,37 @@ func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data repo.
|
|||
// ============================================================================
|
||||
// User Authentication
|
||||
|
||||
func (svc *UserService) createToken(ctx context.Context, userId uuid.UUID) (UserAuthTokenDetail, error) {
|
||||
newToken := hasher.GenerateToken()
|
||||
func (svc *UserService) createSessionToken(ctx context.Context, userId uuid.UUID) (UserAuthTokenDetail, error) {
|
||||
|
||||
created, err := svc.repos.AuthTokens.CreateToken(ctx, repo.UserAuthTokenCreate{
|
||||
attachmentToken := hasher.GenerateToken()
|
||||
attachmentData := repo.UserAuthTokenCreate{
|
||||
UserID: userId,
|
||||
TokenHash: newToken.Hash,
|
||||
TokenHash: attachmentToken.Hash,
|
||||
ExpiresAt: time.Now().Add(oneWeek),
|
||||
})
|
||||
}
|
||||
|
||||
return UserAuthTokenDetail{Raw: newToken.Raw, ExpiresAt: created.ExpiresAt}, err
|
||||
_, err := svc.repos.AuthTokens.CreateToken(ctx, attachmentData, authroles.RoleAttachments)
|
||||
if err != nil {
|
||||
return UserAuthTokenDetail{}, err
|
||||
}
|
||||
|
||||
userToken := hasher.GenerateToken()
|
||||
data := repo.UserAuthTokenCreate{
|
||||
UserID: userId,
|
||||
TokenHash: userToken.Hash,
|
||||
ExpiresAt: time.Now().Add(oneWeek),
|
||||
}
|
||||
|
||||
created, err := svc.repos.AuthTokens.CreateToken(ctx, data, authroles.RoleUser)
|
||||
if err != nil {
|
||||
return UserAuthTokenDetail{}, err
|
||||
}
|
||||
|
||||
return UserAuthTokenDetail{
|
||||
Raw: userToken.Raw,
|
||||
ExpiresAt: created.ExpiresAt,
|
||||
AttachmentToken: attachmentToken.Raw,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (svc *UserService) Login(ctx context.Context, username, password string) (UserAuthTokenDetail, error) {
|
||||
|
@ -156,7 +179,7 @@ func (svc *UserService) Login(ctx context.Context, username, password string) (U
|
|||
return UserAuthTokenDetail{}, ErrorInvalidLogin
|
||||
}
|
||||
|
||||
return svc.createToken(ctx, usr.ID)
|
||||
return svc.createSessionToken(ctx, usr.ID)
|
||||
}
|
||||
|
||||
func (svc *UserService) Logout(ctx context.Context, token string) error {
|
||||
|
@ -174,9 +197,7 @@ func (svc *UserService) RenewToken(ctx context.Context, token string) (UserAuthT
|
|||
return UserAuthTokenDetail{}, ErrorInvalidToken
|
||||
}
|
||||
|
||||
newToken, _ := svc.createToken(ctx, dbToken.ID)
|
||||
|
||||
return newToken, nil
|
||||
return svc.createSessionToken(ctx, dbToken.ID)
|
||||
}
|
||||
|
||||
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
||||
|
|
141
backend/internal/data/ent/authroles.go
Normal file
141
backend/internal/data/ent/authroles.go
Normal file
|
@ -0,0 +1,141 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
)
|
||||
|
||||
// AuthRoles is the model entity for the AuthRoles schema.
|
||||
type AuthRoles struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int `json:"id,omitempty"`
|
||||
// Role holds the value of the "role" field.
|
||||
Role authroles.Role `json:"role,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the AuthRolesQuery when eager-loading is set.
|
||||
Edges AuthRolesEdges `json:"edges"`
|
||||
auth_tokens_roles *uuid.UUID
|
||||
}
|
||||
|
||||
// AuthRolesEdges holds the relations/edges for other nodes in the graph.
|
||||
type AuthRolesEdges struct {
|
||||
// Token holds the value of the token edge.
|
||||
Token *AuthTokens `json:"token,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
}
|
||||
|
||||
// TokenOrErr returns the Token value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AuthRolesEdges) TokenOrErr() (*AuthTokens, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Token == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: authtokens.Label}
|
||||
}
|
||||
return e.Token, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "token"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*AuthRoles) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case authroles.FieldID:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case authroles.FieldRole:
|
||||
values[i] = new(sql.NullString)
|
||||
case authroles.ForeignKeys[0]: // auth_tokens_roles
|
||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected column %q for type AuthRoles", columns[i])
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the AuthRoles fields.
|
||||
func (ar *AuthRoles) assignValues(columns []string, values []any) error {
|
||||
if m, n := len(values), len(columns); m < n {
|
||||
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
|
||||
}
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case authroles.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
ar.ID = int(value.Int64)
|
||||
case authroles.FieldRole:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field role", values[i])
|
||||
} else if value.Valid {
|
||||
ar.Role = authroles.Role(value.String)
|
||||
}
|
||||
case authroles.ForeignKeys[0]:
|
||||
if value, ok := values[i].(*sql.NullScanner); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field auth_tokens_roles", values[i])
|
||||
} else if value.Valid {
|
||||
ar.auth_tokens_roles = new(uuid.UUID)
|
||||
*ar.auth_tokens_roles = *value.S.(*uuid.UUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryToken queries the "token" edge of the AuthRoles entity.
|
||||
func (ar *AuthRoles) QueryToken() *AuthTokensQuery {
|
||||
return (&AuthRolesClient{config: ar.config}).QueryToken(ar)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this AuthRoles.
|
||||
// Note that you need to call AuthRoles.Unwrap() before calling this method if this AuthRoles
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (ar *AuthRoles) Update() *AuthRolesUpdateOne {
|
||||
return (&AuthRolesClient{config: ar.config}).UpdateOne(ar)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the AuthRoles entity that was returned from a transaction after it was closed,
|
||||
// so that all future queries will be executed through the driver which created the transaction.
|
||||
func (ar *AuthRoles) Unwrap() *AuthRoles {
|
||||
_tx, ok := ar.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: AuthRoles is not a transactional entity")
|
||||
}
|
||||
ar.config.driver = _tx.drv
|
||||
return ar
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (ar *AuthRoles) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("AuthRoles(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", ar.ID))
|
||||
builder.WriteString("role=")
|
||||
builder.WriteString(fmt.Sprintf("%v", ar.Role))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// AuthRolesSlice is a parsable slice of AuthRoles.
|
||||
type AuthRolesSlice []*AuthRoles
|
||||
|
||||
func (ar AuthRolesSlice) config(cfg config) {
|
||||
for _i := range ar {
|
||||
ar[_i].config = cfg
|
||||
}
|
||||
}
|
81
backend/internal/data/ent/authroles/authroles.go
Normal file
81
backend/internal/data/ent/authroles/authroles.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package authroles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the authroles type in the database.
|
||||
Label = "auth_roles"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldRole holds the string denoting the role field in the database.
|
||||
FieldRole = "role"
|
||||
// EdgeToken holds the string denoting the token edge name in mutations.
|
||||
EdgeToken = "token"
|
||||
// Table holds the table name of the authroles in the database.
|
||||
Table = "auth_roles"
|
||||
// TokenTable is the table that holds the token relation/edge.
|
||||
TokenTable = "auth_roles"
|
||||
// TokenInverseTable is the table name for the AuthTokens entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "authtokens" package.
|
||||
TokenInverseTable = "auth_tokens"
|
||||
// TokenColumn is the table column denoting the token relation/edge.
|
||||
TokenColumn = "auth_tokens_roles"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for authroles fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldRole,
|
||||
}
|
||||
|
||||
// ForeignKeys holds the SQL foreign-keys that are owned by the "auth_roles"
|
||||
// table and are not defined as standalone fields in the schema.
|
||||
var ForeignKeys = []string{
|
||||
"auth_tokens_roles",
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for i := range ForeignKeys {
|
||||
if column == ForeignKeys[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Role defines the type for the "role" enum field.
|
||||
type Role string
|
||||
|
||||
// RoleUser is the default value of the Role enum.
|
||||
const DefaultRole = RoleUser
|
||||
|
||||
// Role values.
|
||||
const (
|
||||
RoleAdmin Role = "admin"
|
||||
RoleUser Role = "user"
|
||||
RoleAttachments Role = "attachments"
|
||||
)
|
||||
|
||||
func (r Role) String() string {
|
||||
return string(r)
|
||||
}
|
||||
|
||||
// RoleValidator is a validator for the "role" field enum values. It is called by the builders before save.
|
||||
func RoleValidator(r Role) error {
|
||||
switch r {
|
||||
case RoleAdmin, RoleUser, RoleAttachments:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("authroles: invalid enum value for role field: %q", r)
|
||||
}
|
||||
}
|
176
backend/internal/data/ent/authroles/where.go
Normal file
176
backend/internal/data/ent/authroles/where.go
Normal file
|
@ -0,0 +1,176 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package authroles
|
||||
|
||||
import (
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// RoleEQ applies the EQ predicate on the "role" field.
|
||||
func RoleEQ(v Role) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldRole), v))
|
||||
})
|
||||
}
|
||||
|
||||
// RoleNEQ applies the NEQ predicate on the "role" field.
|
||||
func RoleNEQ(v Role) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldRole), v))
|
||||
})
|
||||
}
|
||||
|
||||
// RoleIn applies the In predicate on the "role" field.
|
||||
func RoleIn(vs ...Role) predicate.AuthRoles {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldRole), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// RoleNotIn applies the NotIn predicate on the "role" field.
|
||||
func RoleNotIn(vs ...Role) predicate.AuthRoles {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldRole), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// HasToken applies the HasEdge predicate on the "token" edge.
|
||||
func HasToken() predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(TokenTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, true, TokenTable, TokenColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasTokenWith applies the HasEdge predicate on the "token" edge with a given conditions (other predicates).
|
||||
func HasTokenWith(preds ...predicate.AuthTokens) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(TokenInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, true, TokenTable, TokenColumn),
|
||||
)
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.AuthRoles) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s1 := s.Clone().SetP(nil)
|
||||
for _, p := range predicates {
|
||||
p(s1)
|
||||
}
|
||||
s.Where(s1.P())
|
||||
})
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.AuthRoles) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s1 := s.Clone().SetP(nil)
|
||||
for i, p := range predicates {
|
||||
if i > 0 {
|
||||
s1.Or()
|
||||
}
|
||||
p(s1)
|
||||
}
|
||||
s.Where(s1.P())
|
||||
})
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.AuthRoles) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
p(s.Not())
|
||||
})
|
||||
}
|
286
backend/internal/data/ent/authroles_create.go
Normal file
286
backend/internal/data/ent/authroles_create.go
Normal file
|
@ -0,0 +1,286 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
)
|
||||
|
||||
// AuthRolesCreate is the builder for creating a AuthRoles entity.
|
||||
type AuthRolesCreate struct {
|
||||
config
|
||||
mutation *AuthRolesMutation
|
||||
hooks []Hook
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (arc *AuthRolesCreate) SetRole(a authroles.Role) *AuthRolesCreate {
|
||||
arc.mutation.SetRole(a)
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetNillableRole sets the "role" field if the given value is not nil.
|
||||
func (arc *AuthRolesCreate) SetNillableRole(a *authroles.Role) *AuthRolesCreate {
|
||||
if a != nil {
|
||||
arc.SetRole(*a)
|
||||
}
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetTokenID sets the "token" edge to the AuthTokens entity by ID.
|
||||
func (arc *AuthRolesCreate) SetTokenID(id uuid.UUID) *AuthRolesCreate {
|
||||
arc.mutation.SetTokenID(id)
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetNillableTokenID sets the "token" edge to the AuthTokens entity by ID if the given value is not nil.
|
||||
func (arc *AuthRolesCreate) SetNillableTokenID(id *uuid.UUID) *AuthRolesCreate {
|
||||
if id != nil {
|
||||
arc = arc.SetTokenID(*id)
|
||||
}
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetToken sets the "token" edge to the AuthTokens entity.
|
||||
func (arc *AuthRolesCreate) SetToken(a *AuthTokens) *AuthRolesCreate {
|
||||
return arc.SetTokenID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthRolesMutation object of the builder.
|
||||
func (arc *AuthRolesCreate) Mutation() *AuthRolesMutation {
|
||||
return arc.mutation
|
||||
}
|
||||
|
||||
// Save creates the AuthRoles in the database.
|
||||
func (arc *AuthRolesCreate) Save(ctx context.Context) (*AuthRoles, error) {
|
||||
var (
|
||||
err error
|
||||
node *AuthRoles
|
||||
)
|
||||
arc.defaults()
|
||||
if len(arc.hooks) == 0 {
|
||||
if err = arc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = arc.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthRolesMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = arc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arc.mutation = mutation
|
||||
if node, err = arc.sqlSave(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &node.ID
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(arc.hooks) - 1; i >= 0; i-- {
|
||||
if arc.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = arc.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, arc.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*AuthRoles)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from AuthRolesMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (arc *AuthRolesCreate) SaveX(ctx context.Context) *AuthRoles {
|
||||
v, err := arc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (arc *AuthRolesCreate) Exec(ctx context.Context) error {
|
||||
_, err := arc.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (arc *AuthRolesCreate) ExecX(ctx context.Context) {
|
||||
if err := arc.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (arc *AuthRolesCreate) defaults() {
|
||||
if _, ok := arc.mutation.Role(); !ok {
|
||||
v := authroles.DefaultRole
|
||||
arc.mutation.SetRole(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (arc *AuthRolesCreate) check() error {
|
||||
if _, ok := arc.mutation.Role(); !ok {
|
||||
return &ValidationError{Name: "role", err: errors.New(`ent: missing required field "AuthRoles.role"`)}
|
||||
}
|
||||
if v, ok := arc.mutation.Role(); ok {
|
||||
if err := authroles.RoleValidator(v); err != nil {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "AuthRoles.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (arc *AuthRolesCreate) sqlSave(ctx context.Context) (*AuthRoles, error) {
|
||||
_node, _spec := arc.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, arc.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
id := _spec.ID.Value.(int64)
|
||||
_node.ID = int(id)
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (arc *AuthRolesCreate) createSpec() (*AuthRoles, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &AuthRoles{config: arc.config}
|
||||
_spec = &sqlgraph.CreateSpec{
|
||||
Table: authroles.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
}
|
||||
)
|
||||
if value, ok := arc.mutation.Role(); ok {
|
||||
_spec.SetField(authroles.FieldRole, field.TypeEnum, value)
|
||||
_node.Role = value
|
||||
}
|
||||
if nodes := arc.mutation.TokenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_node.auth_tokens_roles = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
// AuthRolesCreateBulk is the builder for creating many AuthRoles entities in bulk.
|
||||
type AuthRolesCreateBulk struct {
|
||||
config
|
||||
builders []*AuthRolesCreate
|
||||
}
|
||||
|
||||
// Save creates the AuthRoles entities in the database.
|
||||
func (arcb *AuthRolesCreateBulk) Save(ctx context.Context) ([]*AuthRoles, error) {
|
||||
specs := make([]*sqlgraph.CreateSpec, len(arcb.builders))
|
||||
nodes := make([]*AuthRoles, len(arcb.builders))
|
||||
mutators := make([]Mutator, len(arcb.builders))
|
||||
for i := range arcb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := arcb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthRolesMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err := builder.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.mutation = mutation
|
||||
nodes[i], specs[i] = builder.createSpec()
|
||||
var err error
|
||||
if i < len(mutators)-1 {
|
||||
_, err = mutators[i+1].Mutate(root, arcb.builders[i+1].mutation)
|
||||
} else {
|
||||
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||
// Invoke the actual operation on the latest mutation in the chain.
|
||||
if err = sqlgraph.BatchCreate(ctx, arcb.driver, spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &nodes[i].ID
|
||||
if specs[i].ID.Value != nil {
|
||||
id := specs[i].ID.Value.(int64)
|
||||
nodes[i].ID = int(id)
|
||||
}
|
||||
mutation.done = true
|
||||
return nodes[i], nil
|
||||
})
|
||||
for i := len(builder.hooks) - 1; i >= 0; i-- {
|
||||
mut = builder.hooks[i](mut)
|
||||
}
|
||||
mutators[i] = mut
|
||||
}(i, ctx)
|
||||
}
|
||||
if len(mutators) > 0 {
|
||||
if _, err := mutators[0].Mutate(ctx, arcb.builders[0].mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (arcb *AuthRolesCreateBulk) SaveX(ctx context.Context) []*AuthRoles {
|
||||
v, err := arcb.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (arcb *AuthRolesCreateBulk) Exec(ctx context.Context) error {
|
||||
_, err := arcb.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (arcb *AuthRolesCreateBulk) ExecX(ctx context.Context) {
|
||||
if err := arcb.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
115
backend/internal/data/ent/authroles_delete.go
Normal file
115
backend/internal/data/ent/authroles_delete.go
Normal file
|
@ -0,0 +1,115 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// AuthRolesDelete is the builder for deleting a AuthRoles entity.
|
||||
type AuthRolesDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *AuthRolesMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthRolesDelete builder.
|
||||
func (ard *AuthRolesDelete) Where(ps ...predicate.AuthRoles) *AuthRolesDelete {
|
||||
ard.mutation.Where(ps...)
|
||||
return ard
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (ard *AuthRolesDelete) Exec(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
if len(ard.hooks) == 0 {
|
||||
affected, err = ard.sqlExec(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthRolesMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
ard.mutation = mutation
|
||||
affected, err = ard.sqlExec(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(ard.hooks) - 1; i >= 0; i-- {
|
||||
if ard.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = ard.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, ard.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ard *AuthRolesDelete) ExecX(ctx context.Context) int {
|
||||
n, err := ard.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (ard *AuthRolesDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := &sqlgraph.DeleteSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authroles.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
if ps := ard.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, ard.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// AuthRolesDeleteOne is the builder for deleting a single AuthRoles entity.
|
||||
type AuthRolesDeleteOne struct {
|
||||
ard *AuthRolesDelete
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ardo *AuthRolesDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ardo.ard.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{authroles.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ardo *AuthRolesDeleteOne) ExecX(ctx context.Context) {
|
||||
ardo.ard.ExecX(ctx)
|
||||
}
|
633
backend/internal/data/ent/authroles_query.go
Normal file
633
backend/internal/data/ent/authroles_query.go
Normal file
|
@ -0,0 +1,633 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// AuthRolesQuery is the builder for querying AuthRoles entities.
|
||||
type AuthRolesQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
predicates []predicate.AuthRoles
|
||||
withToken *AuthTokensQuery
|
||||
withFKs bool
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the AuthRolesQuery builder.
|
||||
func (arq *AuthRolesQuery) Where(ps ...predicate.AuthRoles) *AuthRolesQuery {
|
||||
arq.predicates = append(arq.predicates, ps...)
|
||||
return arq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
func (arq *AuthRolesQuery) Limit(limit int) *AuthRolesQuery {
|
||||
arq.limit = &limit
|
||||
return arq
|
||||
}
|
||||
|
||||
// Offset adds an offset step to the query.
|
||||
func (arq *AuthRolesQuery) Offset(offset int) *AuthRolesQuery {
|
||||
arq.offset = &offset
|
||||
return arq
|
||||
}
|
||||
|
||||
// Unique configures the query builder to filter duplicate records on query.
|
||||
// By default, unique is set to true, and can be disabled using this method.
|
||||
func (arq *AuthRolesQuery) Unique(unique bool) *AuthRolesQuery {
|
||||
arq.unique = &unique
|
||||
return arq
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
func (arq *AuthRolesQuery) Order(o ...OrderFunc) *AuthRolesQuery {
|
||||
arq.order = append(arq.order, o...)
|
||||
return arq
|
||||
}
|
||||
|
||||
// QueryToken chains the current query on the "token" edge.
|
||||
func (arq *AuthRolesQuery) QueryToken() *AuthTokensQuery {
|
||||
query := &AuthTokensQuery{config: arq.config}
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := arq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(authroles.Table, authroles.FieldID, selector),
|
||||
sqlgraph.To(authtokens.Table, authtokens.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, true, authroles.TokenTable, authroles.TokenColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(arq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first AuthRoles entity from the query.
|
||||
// Returns a *NotFoundError when no AuthRoles was found.
|
||||
func (arq *AuthRolesQuery) First(ctx context.Context) (*AuthRoles, error) {
|
||||
nodes, err := arq.Limit(1).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{authroles.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) FirstX(ctx context.Context) *AuthRoles {
|
||||
node, err := arq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first AuthRoles ID from the query.
|
||||
// Returns a *NotFoundError when no AuthRoles ID was found.
|
||||
func (arq *AuthRolesQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = arq.Limit(1).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{authroles.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) FirstIDX(ctx context.Context) int {
|
||||
id, err := arq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single AuthRoles entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one AuthRoles entity is found.
|
||||
// Returns a *NotFoundError when no AuthRoles entities are found.
|
||||
func (arq *AuthRolesQuery) Only(ctx context.Context) (*AuthRoles, error) {
|
||||
nodes, err := arq.Limit(2).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{authroles.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{authroles.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) OnlyX(ctx context.Context) *AuthRoles {
|
||||
node, err := arq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only AuthRoles ID in the query.
|
||||
// Returns a *NotSingularError when more than one AuthRoles ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (arq *AuthRolesQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = arq.Limit(2).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{authroles.Label}
|
||||
default:
|
||||
err = &NotSingularError{authroles.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) OnlyIDX(ctx context.Context) int {
|
||||
id, err := arq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of AuthRolesSlice.
|
||||
func (arq *AuthRolesQuery) All(ctx context.Context) ([]*AuthRoles, error) {
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return arq.sqlAll(ctx)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) AllX(ctx context.Context) []*AuthRoles {
|
||||
nodes, err := arq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of AuthRoles IDs.
|
||||
func (arq *AuthRolesQuery) IDs(ctx context.Context) ([]int, error) {
|
||||
var ids []int
|
||||
if err := arq.Select(authroles.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := arq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (arq *AuthRolesQuery) Count(ctx context.Context) (int, error) {
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return arq.sqlCount(ctx)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) CountX(ctx context.Context) int {
|
||||
count, err := arq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (arq *AuthRolesQuery) Exist(ctx context.Context) (bool, error) {
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return arq.sqlExist(ctx)
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := arq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the AuthRolesQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (arq *AuthRolesQuery) Clone() *AuthRolesQuery {
|
||||
if arq == nil {
|
||||
return nil
|
||||
}
|
||||
return &AuthRolesQuery{
|
||||
config: arq.config,
|
||||
limit: arq.limit,
|
||||
offset: arq.offset,
|
||||
order: append([]OrderFunc{}, arq.order...),
|
||||
predicates: append([]predicate.AuthRoles{}, arq.predicates...),
|
||||
withToken: arq.withToken.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: arq.sql.Clone(),
|
||||
path: arq.path,
|
||||
unique: arq.unique,
|
||||
}
|
||||
}
|
||||
|
||||
// WithToken tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "token" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (arq *AuthRolesQuery) WithToken(opts ...func(*AuthTokensQuery)) *AuthRolesQuery {
|
||||
query := &AuthTokensQuery{config: arq.config}
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
arq.withToken = query
|
||||
return arq
|
||||
}
|
||||
|
||||
// GroupBy is used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// Role authroles.Role `json:"role,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.AuthRoles.Query().
|
||||
// GroupBy(authroles.FieldRole).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (arq *AuthRolesQuery) GroupBy(field string, fields ...string) *AuthRolesGroupBy {
|
||||
grbuild := &AuthRolesGroupBy{config: arq.config}
|
||||
grbuild.fields = append([]string{field}, fields...)
|
||||
grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) {
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return arq.sqlQuery(ctx), nil
|
||||
}
|
||||
grbuild.label = authroles.Label
|
||||
grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan
|
||||
return grbuild
|
||||
}
|
||||
|
||||
// Select allows the selection one or more fields/columns for the given query,
|
||||
// instead of selecting all fields in the entity.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// Role authroles.Role `json:"role,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.AuthRoles.Query().
|
||||
// Select(authroles.FieldRole).
|
||||
// Scan(ctx, &v)
|
||||
func (arq *AuthRolesQuery) Select(fields ...string) *AuthRolesSelect {
|
||||
arq.fields = append(arq.fields, fields...)
|
||||
selbuild := &AuthRolesSelect{AuthRolesQuery: arq}
|
||||
selbuild.label = authroles.Label
|
||||
selbuild.flds, selbuild.scan = &arq.fields, selbuild.Scan
|
||||
return selbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a AuthRolesSelect configured with the given aggregations.
|
||||
func (arq *AuthRolesQuery) Aggregate(fns ...AggregateFunc) *AuthRolesSelect {
|
||||
return arq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, f := range arq.fields {
|
||||
if !authroles.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if arq.path != nil {
|
||||
prev, err := arq.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
arq.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AuthRoles, error) {
|
||||
var (
|
||||
nodes = []*AuthRoles{}
|
||||
withFKs = arq.withFKs
|
||||
_spec = arq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
arq.withToken != nil,
|
||||
}
|
||||
)
|
||||
if arq.withToken != nil {
|
||||
withFKs = true
|
||||
}
|
||||
if withFKs {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, authroles.ForeignKeys...)
|
||||
}
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*AuthRoles).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &AuthRoles{config: arq.config}
|
||||
nodes = append(nodes, node)
|
||||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
for i := range hooks {
|
||||
hooks[i](ctx, _spec)
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, arq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := arq.withToken; query != nil {
|
||||
if err := arq.loadToken(ctx, query, nodes, nil,
|
||||
func(n *AuthRoles, e *AuthTokens) { n.Edges.Token = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) loadToken(ctx context.Context, query *AuthTokensQuery, nodes []*AuthRoles, init func(*AuthRoles), assign func(*AuthRoles, *AuthTokens)) error {
|
||||
ids := make([]uuid.UUID, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID][]*AuthRoles)
|
||||
for i := range nodes {
|
||||
if nodes[i].auth_tokens_roles == nil {
|
||||
continue
|
||||
}
|
||||
fk := *nodes[i].auth_tokens_roles
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
query.Where(authtokens.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nodeids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "auth_tokens_roles" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := arq.querySpec()
|
||||
_spec.Node.Columns = arq.fields
|
||||
if len(arq.fields) > 0 {
|
||||
_spec.Unique = arq.unique != nil && *arq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, arq.driver, _spec)
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
switch _, err := arq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := &sqlgraph.QuerySpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authroles.Table,
|
||||
Columns: authroles.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
From: arq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := arq.unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := arq.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, authroles.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != authroles.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := arq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := arq.limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := arq.offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := arq.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(arq.driver.Dialect())
|
||||
t1 := builder.Table(authroles.Table)
|
||||
columns := arq.fields
|
||||
if len(columns) == 0 {
|
||||
columns = authroles.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if arq.sql != nil {
|
||||
selector = arq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if arq.unique != nil && *arq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range arq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range arq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := arq.offset; offset != nil {
|
||||
// limit is mandatory for offset clause. We start
|
||||
// with default value, and override it below if needed.
|
||||
selector.Offset(*offset).Limit(math.MaxInt32)
|
||||
}
|
||||
if limit := arq.limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// AuthRolesGroupBy is the group-by builder for AuthRoles entities.
|
||||
type AuthRolesGroupBy struct {
|
||||
config
|
||||
selector
|
||||
fields []string
|
||||
fns []AggregateFunc
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (argb *AuthRolesGroupBy) Aggregate(fns ...AggregateFunc) *AuthRolesGroupBy {
|
||||
argb.fns = append(argb.fns, fns...)
|
||||
return argb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scans the result into the given value.
|
||||
func (argb *AuthRolesGroupBy) Scan(ctx context.Context, v any) error {
|
||||
query, err := argb.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
argb.sql = query
|
||||
return argb.sqlScan(ctx, v)
|
||||
}
|
||||
|
||||
func (argb *AuthRolesGroupBy) sqlScan(ctx context.Context, v any) error {
|
||||
for _, f := range argb.fields {
|
||||
if !authroles.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)}
|
||||
}
|
||||
}
|
||||
selector := argb.sqlQuery()
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := argb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (argb *AuthRolesGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := argb.sql.Select()
|
||||
aggregation := make([]string, 0, len(argb.fns))
|
||||
for _, fn := range argb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(argb.fields)+len(argb.fns))
|
||||
for _, f := range argb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(argb.fields...)...)
|
||||
}
|
||||
|
||||
// AuthRolesSelect is the builder for selecting fields of AuthRoles entities.
|
||||
type AuthRolesSelect struct {
|
||||
*AuthRolesQuery
|
||||
selector
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (ars *AuthRolesSelect) Aggregate(fns ...AggregateFunc) *AuthRolesSelect {
|
||||
ars.fns = append(ars.fns, fns...)
|
||||
return ars
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ars *AuthRolesSelect) Scan(ctx context.Context, v any) error {
|
||||
if err := ars.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
ars.sql = ars.AuthRolesQuery.sqlQuery(ctx)
|
||||
return ars.sqlScan(ctx, v)
|
||||
}
|
||||
|
||||
func (ars *AuthRolesSelect) sqlScan(ctx context.Context, v any) error {
|
||||
aggregation := make([]string, 0, len(ars.fns))
|
||||
for _, fn := range ars.fns {
|
||||
aggregation = append(aggregation, fn(ars.sql))
|
||||
}
|
||||
switch n := len(*ars.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
ars.sql.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
ars.sql.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := ars.sql.Query()
|
||||
if err := ars.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
433
backend/internal/data/ent/authroles_update.go
Normal file
433
backend/internal/data/ent/authroles_update.go
Normal file
|
@ -0,0 +1,433 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// AuthRolesUpdate is the builder for updating AuthRoles entities.
|
||||
type AuthRolesUpdate struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *AuthRolesMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthRolesUpdate builder.
|
||||
func (aru *AuthRolesUpdate) Where(ps ...predicate.AuthRoles) *AuthRolesUpdate {
|
||||
aru.mutation.Where(ps...)
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (aru *AuthRolesUpdate) SetRole(a authroles.Role) *AuthRolesUpdate {
|
||||
aru.mutation.SetRole(a)
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetNillableRole sets the "role" field if the given value is not nil.
|
||||
func (aru *AuthRolesUpdate) SetNillableRole(a *authroles.Role) *AuthRolesUpdate {
|
||||
if a != nil {
|
||||
aru.SetRole(*a)
|
||||
}
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetTokenID sets the "token" edge to the AuthTokens entity by ID.
|
||||
func (aru *AuthRolesUpdate) SetTokenID(id uuid.UUID) *AuthRolesUpdate {
|
||||
aru.mutation.SetTokenID(id)
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetNillableTokenID sets the "token" edge to the AuthTokens entity by ID if the given value is not nil.
|
||||
func (aru *AuthRolesUpdate) SetNillableTokenID(id *uuid.UUID) *AuthRolesUpdate {
|
||||
if id != nil {
|
||||
aru = aru.SetTokenID(*id)
|
||||
}
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetToken sets the "token" edge to the AuthTokens entity.
|
||||
func (aru *AuthRolesUpdate) SetToken(a *AuthTokens) *AuthRolesUpdate {
|
||||
return aru.SetTokenID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthRolesMutation object of the builder.
|
||||
func (aru *AuthRolesUpdate) Mutation() *AuthRolesMutation {
|
||||
return aru.mutation
|
||||
}
|
||||
|
||||
// ClearToken clears the "token" edge to the AuthTokens entity.
|
||||
func (aru *AuthRolesUpdate) ClearToken() *AuthRolesUpdate {
|
||||
aru.mutation.ClearToken()
|
||||
return aru
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (aru *AuthRolesUpdate) Save(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
if len(aru.hooks) == 0 {
|
||||
if err = aru.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
affected, err = aru.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthRolesMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = aru.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
aru.mutation = mutation
|
||||
affected, err = aru.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(aru.hooks) - 1; i >= 0; i-- {
|
||||
if aru.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = aru.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, aru.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (aru *AuthRolesUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := aru.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (aru *AuthRolesUpdate) Exec(ctx context.Context) error {
|
||||
_, err := aru.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (aru *AuthRolesUpdate) ExecX(ctx context.Context) {
|
||||
if err := aru.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (aru *AuthRolesUpdate) check() error {
|
||||
if v, ok := aru.mutation.Role(); ok {
|
||||
if err := authroles.RoleValidator(v); err != nil {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "AuthRoles.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (aru *AuthRolesUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authroles.Table,
|
||||
Columns: authroles.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
if ps := aru.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := aru.mutation.Role(); ok {
|
||||
_spec.SetField(authroles.FieldRole, field.TypeEnum, value)
|
||||
}
|
||||
if aru.mutation.TokenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := aru.mutation.TokenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, aru.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{authroles.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// AuthRolesUpdateOne is the builder for updating a single AuthRoles entity.
|
||||
type AuthRolesUpdateOne struct {
|
||||
config
|
||||
fields []string
|
||||
hooks []Hook
|
||||
mutation *AuthRolesMutation
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (aruo *AuthRolesUpdateOne) SetRole(a authroles.Role) *AuthRolesUpdateOne {
|
||||
aruo.mutation.SetRole(a)
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetNillableRole sets the "role" field if the given value is not nil.
|
||||
func (aruo *AuthRolesUpdateOne) SetNillableRole(a *authroles.Role) *AuthRolesUpdateOne {
|
||||
if a != nil {
|
||||
aruo.SetRole(*a)
|
||||
}
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetTokenID sets the "token" edge to the AuthTokens entity by ID.
|
||||
func (aruo *AuthRolesUpdateOne) SetTokenID(id uuid.UUID) *AuthRolesUpdateOne {
|
||||
aruo.mutation.SetTokenID(id)
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetNillableTokenID sets the "token" edge to the AuthTokens entity by ID if the given value is not nil.
|
||||
func (aruo *AuthRolesUpdateOne) SetNillableTokenID(id *uuid.UUID) *AuthRolesUpdateOne {
|
||||
if id != nil {
|
||||
aruo = aruo.SetTokenID(*id)
|
||||
}
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetToken sets the "token" edge to the AuthTokens entity.
|
||||
func (aruo *AuthRolesUpdateOne) SetToken(a *AuthTokens) *AuthRolesUpdateOne {
|
||||
return aruo.SetTokenID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthRolesMutation object of the builder.
|
||||
func (aruo *AuthRolesUpdateOne) Mutation() *AuthRolesMutation {
|
||||
return aruo.mutation
|
||||
}
|
||||
|
||||
// ClearToken clears the "token" edge to the AuthTokens entity.
|
||||
func (aruo *AuthRolesUpdateOne) ClearToken() *AuthRolesUpdateOne {
|
||||
aruo.mutation.ClearToken()
|
||||
return aruo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (aruo *AuthRolesUpdateOne) Select(field string, fields ...string) *AuthRolesUpdateOne {
|
||||
aruo.fields = append([]string{field}, fields...)
|
||||
return aruo
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated AuthRoles entity.
|
||||
func (aruo *AuthRolesUpdateOne) Save(ctx context.Context) (*AuthRoles, error) {
|
||||
var (
|
||||
err error
|
||||
node *AuthRoles
|
||||
)
|
||||
if len(aruo.hooks) == 0 {
|
||||
if err = aruo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = aruo.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthRolesMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = aruo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aruo.mutation = mutation
|
||||
node, err = aruo.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(aruo.hooks) - 1; i >= 0; i-- {
|
||||
if aruo.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = aruo.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, aruo.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*AuthRoles)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from AuthRolesMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (aruo *AuthRolesUpdateOne) SaveX(ctx context.Context) *AuthRoles {
|
||||
node, err := aruo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (aruo *AuthRolesUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := aruo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (aruo *AuthRolesUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := aruo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (aruo *AuthRolesUpdateOne) check() error {
|
||||
if v, ok := aruo.mutation.Role(); ok {
|
||||
if err := authroles.RoleValidator(v); err != nil {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "AuthRoles.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (aruo *AuthRolesUpdateOne) sqlSave(ctx context.Context) (_node *AuthRoles, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authroles.Table,
|
||||
Columns: authroles.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
id, ok := aruo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "AuthRoles.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := aruo.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, authroles.FieldID)
|
||||
for _, f := range fields {
|
||||
if !authroles.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != authroles.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := aruo.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := aruo.mutation.Role(); ok {
|
||||
_spec.SetField(authroles.FieldRole, field.TypeEnum, value)
|
||||
}
|
||||
if aruo.mutation.TokenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := aruo.mutation.TokenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &AuthRoles{config: aruo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
if err = sqlgraph.UpdateNode(ctx, aruo.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{authroles.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return _node, nil
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
)
|
||||
|
@ -36,9 +37,11 @@ type AuthTokens struct {
|
|||
type AuthTokensEdges struct {
|
||||
// User holds the value of the user edge.
|
||||
User *User `json:"user,omitempty"`
|
||||
// Roles holds the value of the roles edge.
|
||||
Roles *AuthRoles `json:"roles,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
loadedTypes [2]bool
|
||||
}
|
||||
|
||||
// UserOrErr returns the User value or an error if the edge
|
||||
|
@ -54,6 +57,19 @@ func (e AuthTokensEdges) UserOrErr() (*User, error) {
|
|||
return nil, &NotLoadedError{edge: "user"}
|
||||
}
|
||||
|
||||
// RolesOrErr returns the Roles value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AuthTokensEdges) RolesOrErr() (*AuthRoles, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.Roles == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: authroles.Label}
|
||||
}
|
||||
return e.Roles, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "roles"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*AuthTokens) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
|
@ -129,6 +145,11 @@ func (at *AuthTokens) QueryUser() *UserQuery {
|
|||
return (&AuthTokensClient{config: at.config}).QueryUser(at)
|
||||
}
|
||||
|
||||
// QueryRoles queries the "roles" edge of the AuthTokens entity.
|
||||
func (at *AuthTokens) QueryRoles() *AuthRolesQuery {
|
||||
return (&AuthTokensClient{config: at.config}).QueryRoles(at)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this AuthTokens.
|
||||
// Note that you need to call AuthTokens.Unwrap() before calling this method if this AuthTokens
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
|
|
|
@ -23,6 +23,8 @@ const (
|
|||
FieldExpiresAt = "expires_at"
|
||||
// EdgeUser holds the string denoting the user edge name in mutations.
|
||||
EdgeUser = "user"
|
||||
// EdgeRoles holds the string denoting the roles edge name in mutations.
|
||||
EdgeRoles = "roles"
|
||||
// Table holds the table name of the authtokens in the database.
|
||||
Table = "auth_tokens"
|
||||
// UserTable is the table that holds the user relation/edge.
|
||||
|
@ -32,6 +34,13 @@ const (
|
|||
UserInverseTable = "users"
|
||||
// UserColumn is the table column denoting the user relation/edge.
|
||||
UserColumn = "user_auth_tokens"
|
||||
// RolesTable is the table that holds the roles relation/edge.
|
||||
RolesTable = "auth_roles"
|
||||
// RolesInverseTable is the table name for the AuthRoles entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "authroles" package.
|
||||
RolesInverseTable = "auth_roles"
|
||||
// RolesColumn is the table column denoting the roles relation/edge.
|
||||
RolesColumn = "auth_tokens_roles"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for authtokens fields.
|
||||
|
|
|
@ -394,6 +394,34 @@ func HasUserWith(preds ...predicate.User) predicate.AuthTokens {
|
|||
})
|
||||
}
|
||||
|
||||
// HasRoles applies the HasEdge predicate on the "roles" edge.
|
||||
func HasRoles() predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(RolesTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, false, RolesTable, RolesColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasRolesWith applies the HasEdge predicate on the "roles" edge with a given conditions (other predicates).
|
||||
func HasRolesWith(preds ...predicate.AuthRoles) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(RolesInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, false, RolesTable, RolesColumn),
|
||||
)
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.AuthTokens) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
)
|
||||
|
@ -103,6 +104,25 @@ func (atc *AuthTokensCreate) SetUser(u *User) *AuthTokensCreate {
|
|||
return atc.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// SetRolesID sets the "roles" edge to the AuthRoles entity by ID.
|
||||
func (atc *AuthTokensCreate) SetRolesID(id int) *AuthTokensCreate {
|
||||
atc.mutation.SetRolesID(id)
|
||||
return atc
|
||||
}
|
||||
|
||||
// SetNillableRolesID sets the "roles" edge to the AuthRoles entity by ID if the given value is not nil.
|
||||
func (atc *AuthTokensCreate) SetNillableRolesID(id *int) *AuthTokensCreate {
|
||||
if id != nil {
|
||||
atc = atc.SetRolesID(*id)
|
||||
}
|
||||
return atc
|
||||
}
|
||||
|
||||
// SetRoles sets the "roles" edge to the AuthRoles entity.
|
||||
func (atc *AuthTokensCreate) SetRoles(a *AuthRoles) *AuthTokensCreate {
|
||||
return atc.SetRolesID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthTokensMutation object of the builder.
|
||||
func (atc *AuthTokensCreate) Mutation() *AuthTokensMutation {
|
||||
return atc.mutation
|
||||
|
@ -284,6 +304,25 @@ func (atc *AuthTokensCreate) createSpec() (*AuthTokens, *sqlgraph.CreateSpec) {
|
|||
_node.user_auth_tokens = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := atc.mutation.RolesIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ package ent
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
|
@ -11,6 +12,7 @@ import (
|
|||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
|
@ -26,6 +28,7 @@ type AuthTokensQuery struct {
|
|||
fields []string
|
||||
predicates []predicate.AuthTokens
|
||||
withUser *UserQuery
|
||||
withRoles *AuthRolesQuery
|
||||
withFKs bool
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
|
@ -85,6 +88,28 @@ func (atq *AuthTokensQuery) QueryUser() *UserQuery {
|
|||
return query
|
||||
}
|
||||
|
||||
// QueryRoles chains the current query on the "roles" edge.
|
||||
func (atq *AuthTokensQuery) QueryRoles() *AuthRolesQuery {
|
||||
query := &AuthRolesQuery{config: atq.config}
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := atq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(authtokens.Table, authtokens.FieldID, selector),
|
||||
sqlgraph.To(authroles.Table, authroles.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, false, authtokens.RolesTable, authtokens.RolesColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(atq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first AuthTokens entity from the query.
|
||||
// Returns a *NotFoundError when no AuthTokens was found.
|
||||
func (atq *AuthTokensQuery) First(ctx context.Context) (*AuthTokens, error) {
|
||||
|
@ -267,6 +292,7 @@ func (atq *AuthTokensQuery) Clone() *AuthTokensQuery {
|
|||
order: append([]OrderFunc{}, atq.order...),
|
||||
predicates: append([]predicate.AuthTokens{}, atq.predicates...),
|
||||
withUser: atq.withUser.Clone(),
|
||||
withRoles: atq.withRoles.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: atq.sql.Clone(),
|
||||
path: atq.path,
|
||||
|
@ -285,6 +311,17 @@ func (atq *AuthTokensQuery) WithUser(opts ...func(*UserQuery)) *AuthTokensQuery
|
|||
return atq
|
||||
}
|
||||
|
||||
// WithRoles tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "roles" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (atq *AuthTokensQuery) WithRoles(opts ...func(*AuthRolesQuery)) *AuthTokensQuery {
|
||||
query := &AuthRolesQuery{config: atq.config}
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
atq.withRoles = query
|
||||
return atq
|
||||
}
|
||||
|
||||
// GroupBy is used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
//
|
||||
|
@ -359,8 +396,9 @@ func (atq *AuthTokensQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*
|
|||
nodes = []*AuthTokens{}
|
||||
withFKs = atq.withFKs
|
||||
_spec = atq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
loadedTypes = [2]bool{
|
||||
atq.withUser != nil,
|
||||
atq.withRoles != nil,
|
||||
}
|
||||
)
|
||||
if atq.withUser != nil {
|
||||
|
@ -393,6 +431,12 @@ func (atq *AuthTokensQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := atq.withRoles; query != nil {
|
||||
if err := atq.loadRoles(ctx, query, nodes, nil,
|
||||
func(n *AuthTokens, e *AuthRoles) { n.Edges.Roles = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
|
@ -425,6 +469,34 @@ func (atq *AuthTokensQuery) loadUser(ctx context.Context, query *UserQuery, node
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (atq *AuthTokensQuery) loadRoles(ctx context.Context, query *AuthRolesQuery, nodes []*AuthTokens, init func(*AuthTokens), assign func(*AuthTokens, *AuthRoles)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID]*AuthTokens)
|
||||
for i := range nodes {
|
||||
fks = append(fks, nodes[i].ID)
|
||||
nodeids[nodes[i].ID] = nodes[i]
|
||||
}
|
||||
query.withFKs = true
|
||||
query.Where(predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.InValues(authtokens.RolesColumn, fks...))
|
||||
}))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
fk := n.auth_tokens_roles
|
||||
if fk == nil {
|
||||
return fmt.Errorf(`foreign-key "auth_tokens_roles" is nil for node %v`, n.ID)
|
||||
}
|
||||
node, ok := nodeids[*fk]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "auth_tokens_roles" returned %v for node %v`, *fk, n.ID)
|
||||
}
|
||||
assign(node, n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (atq *AuthTokensQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := atq.querySpec()
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
|
@ -75,6 +76,25 @@ func (atu *AuthTokensUpdate) SetUser(u *User) *AuthTokensUpdate {
|
|||
return atu.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// SetRolesID sets the "roles" edge to the AuthRoles entity by ID.
|
||||
func (atu *AuthTokensUpdate) SetRolesID(id int) *AuthTokensUpdate {
|
||||
atu.mutation.SetRolesID(id)
|
||||
return atu
|
||||
}
|
||||
|
||||
// SetNillableRolesID sets the "roles" edge to the AuthRoles entity by ID if the given value is not nil.
|
||||
func (atu *AuthTokensUpdate) SetNillableRolesID(id *int) *AuthTokensUpdate {
|
||||
if id != nil {
|
||||
atu = atu.SetRolesID(*id)
|
||||
}
|
||||
return atu
|
||||
}
|
||||
|
||||
// SetRoles sets the "roles" edge to the AuthRoles entity.
|
||||
func (atu *AuthTokensUpdate) SetRoles(a *AuthRoles) *AuthTokensUpdate {
|
||||
return atu.SetRolesID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthTokensMutation object of the builder.
|
||||
func (atu *AuthTokensUpdate) Mutation() *AuthTokensMutation {
|
||||
return atu.mutation
|
||||
|
@ -86,6 +106,12 @@ func (atu *AuthTokensUpdate) ClearUser() *AuthTokensUpdate {
|
|||
return atu
|
||||
}
|
||||
|
||||
// ClearRoles clears the "roles" edge to the AuthRoles entity.
|
||||
func (atu *AuthTokensUpdate) ClearRoles() *AuthTokensUpdate {
|
||||
atu.mutation.ClearRoles()
|
||||
return atu
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (atu *AuthTokensUpdate) Save(ctx context.Context) (int, error) {
|
||||
var (
|
||||
|
@ -211,6 +237,41 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
|||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if atu.mutation.RolesCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := atu.mutation.RolesIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, atu.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{authtokens.Label}
|
||||
|
@ -275,6 +336,25 @@ func (atuo *AuthTokensUpdateOne) SetUser(u *User) *AuthTokensUpdateOne {
|
|||
return atuo.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// SetRolesID sets the "roles" edge to the AuthRoles entity by ID.
|
||||
func (atuo *AuthTokensUpdateOne) SetRolesID(id int) *AuthTokensUpdateOne {
|
||||
atuo.mutation.SetRolesID(id)
|
||||
return atuo
|
||||
}
|
||||
|
||||
// SetNillableRolesID sets the "roles" edge to the AuthRoles entity by ID if the given value is not nil.
|
||||
func (atuo *AuthTokensUpdateOne) SetNillableRolesID(id *int) *AuthTokensUpdateOne {
|
||||
if id != nil {
|
||||
atuo = atuo.SetRolesID(*id)
|
||||
}
|
||||
return atuo
|
||||
}
|
||||
|
||||
// SetRoles sets the "roles" edge to the AuthRoles entity.
|
||||
func (atuo *AuthTokensUpdateOne) SetRoles(a *AuthRoles) *AuthTokensUpdateOne {
|
||||
return atuo.SetRolesID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthTokensMutation object of the builder.
|
||||
func (atuo *AuthTokensUpdateOne) Mutation() *AuthTokensMutation {
|
||||
return atuo.mutation
|
||||
|
@ -286,6 +366,12 @@ func (atuo *AuthTokensUpdateOne) ClearUser() *AuthTokensUpdateOne {
|
|||
return atuo
|
||||
}
|
||||
|
||||
// ClearRoles clears the "roles" edge to the AuthRoles entity.
|
||||
func (atuo *AuthTokensUpdateOne) ClearRoles() *AuthTokensUpdateOne {
|
||||
atuo.mutation.ClearRoles()
|
||||
return atuo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (atuo *AuthTokensUpdateOne) Select(field string, fields ...string) *AuthTokensUpdateOne {
|
||||
|
@ -441,6 +527,41 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
|||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if atuo.mutation.RolesCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := atuo.mutation.RolesIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &AuthTokens{config: atuo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/hay-kot/homebox/backend/internal/data/ent/migrate"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
|
@ -35,6 +36,8 @@ type Client struct {
|
|||
Schema *migrate.Schema
|
||||
// Attachment is the client for interacting with the Attachment builders.
|
||||
Attachment *AttachmentClient
|
||||
// AuthRoles is the client for interacting with the AuthRoles builders.
|
||||
AuthRoles *AuthRolesClient
|
||||
// AuthTokens is the client for interacting with the AuthTokens builders.
|
||||
AuthTokens *AuthTokensClient
|
||||
// Document is the client for interacting with the Document builders.
|
||||
|
@ -69,6 +72,7 @@ func NewClient(opts ...Option) *Client {
|
|||
func (c *Client) init() {
|
||||
c.Schema = migrate.NewSchema(c.driver)
|
||||
c.Attachment = NewAttachmentClient(c.config)
|
||||
c.AuthRoles = NewAuthRolesClient(c.config)
|
||||
c.AuthTokens = NewAuthTokensClient(c.config)
|
||||
c.Document = NewDocumentClient(c.config)
|
||||
c.DocumentToken = NewDocumentTokenClient(c.config)
|
||||
|
@ -113,6 +117,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
|
|||
ctx: ctx,
|
||||
config: cfg,
|
||||
Attachment: NewAttachmentClient(cfg),
|
||||
AuthRoles: NewAuthRolesClient(cfg),
|
||||
AuthTokens: NewAuthTokensClient(cfg),
|
||||
Document: NewDocumentClient(cfg),
|
||||
DocumentToken: NewDocumentTokenClient(cfg),
|
||||
|
@ -143,6 +148,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
|
|||
ctx: ctx,
|
||||
config: cfg,
|
||||
Attachment: NewAttachmentClient(cfg),
|
||||
AuthRoles: NewAuthRolesClient(cfg),
|
||||
AuthTokens: NewAuthTokensClient(cfg),
|
||||
Document: NewDocumentClient(cfg),
|
||||
DocumentToken: NewDocumentTokenClient(cfg),
|
||||
|
@ -182,6 +188,7 @@ func (c *Client) Close() error {
|
|||
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
|
||||
func (c *Client) Use(hooks ...Hook) {
|
||||
c.Attachment.Use(hooks...)
|
||||
c.AuthRoles.Use(hooks...)
|
||||
c.AuthTokens.Use(hooks...)
|
||||
c.Document.Use(hooks...)
|
||||
c.DocumentToken.Use(hooks...)
|
||||
|
@ -316,6 +323,112 @@ func (c *AttachmentClient) Hooks() []Hook {
|
|||
return c.hooks.Attachment
|
||||
}
|
||||
|
||||
// AuthRolesClient is a client for the AuthRoles schema.
|
||||
type AuthRolesClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewAuthRolesClient returns a client for the AuthRoles from the given config.
|
||||
func NewAuthRolesClient(c config) *AuthRolesClient {
|
||||
return &AuthRolesClient{config: c}
|
||||
}
|
||||
|
||||
// Use adds a list of mutation hooks to the hooks stack.
|
||||
// A call to `Use(f, g, h)` equals to `authroles.Hooks(f(g(h())))`.
|
||||
func (c *AuthRolesClient) Use(hooks ...Hook) {
|
||||
c.hooks.AuthRoles = append(c.hooks.AuthRoles, hooks...)
|
||||
}
|
||||
|
||||
// Create returns a builder for creating a AuthRoles entity.
|
||||
func (c *AuthRolesClient) Create() *AuthRolesCreate {
|
||||
mutation := newAuthRolesMutation(c.config, OpCreate)
|
||||
return &AuthRolesCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// CreateBulk returns a builder for creating a bulk of AuthRoles entities.
|
||||
func (c *AuthRolesClient) CreateBulk(builders ...*AuthRolesCreate) *AuthRolesCreateBulk {
|
||||
return &AuthRolesCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// Update returns an update builder for AuthRoles.
|
||||
func (c *AuthRolesClient) Update() *AuthRolesUpdate {
|
||||
mutation := newAuthRolesMutation(c.config, OpUpdate)
|
||||
return &AuthRolesUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *AuthRolesClient) UpdateOne(ar *AuthRoles) *AuthRolesUpdateOne {
|
||||
mutation := newAuthRolesMutation(c.config, OpUpdateOne, withAuthRoles(ar))
|
||||
return &AuthRolesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *AuthRolesClient) UpdateOneID(id int) *AuthRolesUpdateOne {
|
||||
mutation := newAuthRolesMutation(c.config, OpUpdateOne, withAuthRolesID(id))
|
||||
return &AuthRolesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for AuthRoles.
|
||||
func (c *AuthRolesClient) Delete() *AuthRolesDelete {
|
||||
mutation := newAuthRolesMutation(c.config, OpDelete)
|
||||
return &AuthRolesDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// DeleteOne returns a builder for deleting the given entity.
|
||||
func (c *AuthRolesClient) DeleteOne(ar *AuthRoles) *AuthRolesDeleteOne {
|
||||
return c.DeleteOneID(ar.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a builder for deleting the given entity by its id.
|
||||
func (c *AuthRolesClient) DeleteOneID(id int) *AuthRolesDeleteOne {
|
||||
builder := c.Delete().Where(authroles.ID(id))
|
||||
builder.mutation.id = &id
|
||||
builder.mutation.op = OpDeleteOne
|
||||
return &AuthRolesDeleteOne{builder}
|
||||
}
|
||||
|
||||
// Query returns a query builder for AuthRoles.
|
||||
func (c *AuthRolesClient) Query() *AuthRolesQuery {
|
||||
return &AuthRolesQuery{
|
||||
config: c.config,
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns a AuthRoles entity by its id.
|
||||
func (c *AuthRolesClient) Get(ctx context.Context, id int) (*AuthRoles, error) {
|
||||
return c.Query().Where(authroles.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (c *AuthRolesClient) GetX(ctx context.Context, id int) *AuthRoles {
|
||||
obj, err := c.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// QueryToken queries the token edge of a AuthRoles.
|
||||
func (c *AuthRolesClient) QueryToken(ar *AuthRoles) *AuthTokensQuery {
|
||||
query := &AuthTokensQuery{config: c.config}
|
||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||
id := ar.ID
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(authroles.Table, authroles.FieldID, id),
|
||||
sqlgraph.To(authtokens.Table, authtokens.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, true, authroles.TokenTable, authroles.TokenColumn),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(ar.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *AuthRolesClient) Hooks() []Hook {
|
||||
return c.hooks.AuthRoles
|
||||
}
|
||||
|
||||
// AuthTokensClient is a client for the AuthTokens schema.
|
||||
type AuthTokensClient struct {
|
||||
config
|
||||
|
@ -417,6 +530,22 @@ func (c *AuthTokensClient) QueryUser(at *AuthTokens) *UserQuery {
|
|||
return query
|
||||
}
|
||||
|
||||
// QueryRoles queries the roles edge of a AuthTokens.
|
||||
func (c *AuthTokensClient) QueryRoles(at *AuthTokens) *AuthRolesQuery {
|
||||
query := &AuthRolesQuery{config: c.config}
|
||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||
id := at.ID
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(authtokens.Table, authtokens.FieldID, id),
|
||||
sqlgraph.To(authroles.Table, authroles.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, false, authtokens.RolesTable, authtokens.RolesColumn),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(at.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *AuthTokensClient) Hooks() []Hook {
|
||||
return c.hooks.AuthTokens
|
||||
|
|
|
@ -25,6 +25,7 @@ type config struct {
|
|||
// hooks per client, for fast access.
|
||||
type hooks struct {
|
||||
Attachment []ent.Hook
|
||||
AuthRoles []ent.Hook
|
||||
AuthTokens []ent.Hook
|
||||
Document []ent.Hook
|
||||
DocumentToken []ent.Hook
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
|
@ -42,6 +43,7 @@ type OrderFunc func(*sql.Selector)
|
|||
func columnChecker(table string) func(string) error {
|
||||
checks := map[string]func(string) bool{
|
||||
attachment.Table: attachment.ValidColumn,
|
||||
authroles.Table: authroles.ValidColumn,
|
||||
authtokens.Table: authtokens.ValidColumn,
|
||||
document.Table: document.ValidColumn,
|
||||
documenttoken.Table: documenttoken.ValidColumn,
|
||||
|
|
|
@ -22,6 +22,19 @@ func (f AttachmentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value,
|
|||
return f(ctx, mv)
|
||||
}
|
||||
|
||||
// The AuthRolesFunc type is an adapter to allow the use of ordinary
|
||||
// function as AuthRoles mutator.
|
||||
type AuthRolesFunc func(context.Context, *ent.AuthRolesMutation) (ent.Value, error)
|
||||
|
||||
// Mutate calls f(ctx, m).
|
||||
func (f AuthRolesFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
|
||||
mv, ok := m.(*ent.AuthRolesMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.AuthRolesMutation", m)
|
||||
}
|
||||
return f(ctx, mv)
|
||||
}
|
||||
|
||||
// The AuthTokensFunc type is an adapter to allow the use of ordinary
|
||||
// function as AuthTokens mutator.
|
||||
type AuthTokensFunc func(context.Context, *ent.AuthTokensMutation) (ent.Value, error)
|
||||
|
|
|
@ -37,6 +37,26 @@ var (
|
|||
},
|
||||
},
|
||||
}
|
||||
// AuthRolesColumns holds the columns for the "auth_roles" table.
|
||||
AuthRolesColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "role", Type: field.TypeEnum, Enums: []string{"admin", "user", "attachments"}, Default: "user"},
|
||||
{Name: "auth_tokens_roles", Type: field.TypeUUID, Unique: true, Nullable: true},
|
||||
}
|
||||
// AuthRolesTable holds the schema information for the "auth_roles" table.
|
||||
AuthRolesTable = &schema.Table{
|
||||
Name: "auth_roles",
|
||||
Columns: AuthRolesColumns,
|
||||
PrimaryKey: []*schema.Column{AuthRolesColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "auth_roles_auth_tokens_roles",
|
||||
Columns: []*schema.Column{AuthRolesColumns[2]},
|
||||
RefColumns: []*schema.Column{AuthTokensColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
},
|
||||
}
|
||||
// AuthTokensColumns holds the columns for the "auth_tokens" table.
|
||||
AuthTokensColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeUUID},
|
||||
|
@ -385,6 +405,7 @@ var (
|
|||
// Tables holds all the tables in the schema.
|
||||
Tables = []*schema.Table{
|
||||
AttachmentsTable,
|
||||
AuthRolesTable,
|
||||
AuthTokensTable,
|
||||
DocumentsTable,
|
||||
DocumentTokensTable,
|
||||
|
@ -402,6 +423,7 @@ var (
|
|||
func init() {
|
||||
AttachmentsTable.ForeignKeys[0].RefTable = DocumentsTable
|
||||
AttachmentsTable.ForeignKeys[1].RefTable = ItemsTable
|
||||
AuthRolesTable.ForeignKeys[0].RefTable = AuthTokensTable
|
||||
AuthTokensTable.ForeignKeys[0].RefTable = UsersTable
|
||||
DocumentsTable.ForeignKeys[0].RefTable = GroupsTable
|
||||
DocumentTokensTable.ForeignKeys[0].RefTable = DocumentsTable
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
|
@ -36,6 +37,7 @@ const (
|
|||
|
||||
// Node types.
|
||||
TypeAttachment = "Attachment"
|
||||
TypeAuthRoles = "AuthRoles"
|
||||
TypeAuthTokens = "AuthTokens"
|
||||
TypeDocument = "Document"
|
||||
TypeDocumentToken = "DocumentToken"
|
||||
|
@ -599,6 +601,384 @@ func (m *AttachmentMutation) ResetEdge(name string) error {
|
|||
return fmt.Errorf("unknown Attachment edge %s", name)
|
||||
}
|
||||
|
||||
// AuthRolesMutation represents an operation that mutates the AuthRoles nodes in the graph.
|
||||
type AuthRolesMutation struct {
|
||||
config
|
||||
op Op
|
||||
typ string
|
||||
id *int
|
||||
role *authroles.Role
|
||||
clearedFields map[string]struct{}
|
||||
token *uuid.UUID
|
||||
clearedtoken bool
|
||||
done bool
|
||||
oldValue func(context.Context) (*AuthRoles, error)
|
||||
predicates []predicate.AuthRoles
|
||||
}
|
||||
|
||||
var _ ent.Mutation = (*AuthRolesMutation)(nil)
|
||||
|
||||
// authrolesOption allows management of the mutation configuration using functional options.
|
||||
type authrolesOption func(*AuthRolesMutation)
|
||||
|
||||
// newAuthRolesMutation creates new mutation for the AuthRoles entity.
|
||||
func newAuthRolesMutation(c config, op Op, opts ...authrolesOption) *AuthRolesMutation {
|
||||
m := &AuthRolesMutation{
|
||||
config: c,
|
||||
op: op,
|
||||
typ: TypeAuthRoles,
|
||||
clearedFields: make(map[string]struct{}),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(m)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// withAuthRolesID sets the ID field of the mutation.
|
||||
func withAuthRolesID(id int) authrolesOption {
|
||||
return func(m *AuthRolesMutation) {
|
||||
var (
|
||||
err error
|
||||
once sync.Once
|
||||
value *AuthRoles
|
||||
)
|
||||
m.oldValue = func(ctx context.Context) (*AuthRoles, error) {
|
||||
once.Do(func() {
|
||||
if m.done {
|
||||
err = errors.New("querying old values post mutation is not allowed")
|
||||
} else {
|
||||
value, err = m.Client().AuthRoles.Get(ctx, id)
|
||||
}
|
||||
})
|
||||
return value, err
|
||||
}
|
||||
m.id = &id
|
||||
}
|
||||
}
|
||||
|
||||
// withAuthRoles sets the old AuthRoles of the mutation.
|
||||
func withAuthRoles(node *AuthRoles) authrolesOption {
|
||||
return func(m *AuthRolesMutation) {
|
||||
m.oldValue = func(context.Context) (*AuthRoles, error) {
|
||||
return node, nil
|
||||
}
|
||||
m.id = &node.ID
|
||||
}
|
||||
}
|
||||
|
||||
// Client returns a new `ent.Client` from the mutation. If the mutation was
|
||||
// executed in a transaction (ent.Tx), a transactional client is returned.
|
||||
func (m AuthRolesMutation) Client() *Client {
|
||||
client := &Client{config: m.config}
|
||||
client.init()
|
||||
return client
|
||||
}
|
||||
|
||||
// Tx returns an `ent.Tx` for mutations that were executed in transactions;
|
||||
// it returns an error otherwise.
|
||||
func (m AuthRolesMutation) Tx() (*Tx, error) {
|
||||
if _, ok := m.driver.(*txDriver); !ok {
|
||||
return nil, errors.New("ent: mutation is not running in a transaction")
|
||||
}
|
||||
tx := &Tx{config: m.config}
|
||||
tx.init()
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// ID returns the ID value in the mutation. Note that the ID is only available
|
||||
// if it was provided to the builder or after it was returned from the database.
|
||||
func (m *AuthRolesMutation) ID() (id int, exists bool) {
|
||||
if m.id == nil {
|
||||
return
|
||||
}
|
||||
return *m.id, true
|
||||
}
|
||||
|
||||
// IDs queries the database and returns the entity ids that match the mutation's predicate.
|
||||
// That means, if the mutation is applied within a transaction with an isolation level such
|
||||
// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated
|
||||
// or updated by the mutation.
|
||||
func (m *AuthRolesMutation) IDs(ctx context.Context) ([]int, error) {
|
||||
switch {
|
||||
case m.op.Is(OpUpdateOne | OpDeleteOne):
|
||||
id, exists := m.ID()
|
||||
if exists {
|
||||
return []int{id}, nil
|
||||
}
|
||||
fallthrough
|
||||
case m.op.Is(OpUpdate | OpDelete):
|
||||
return m.Client().AuthRoles.Query().Where(m.predicates...).IDs(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
|
||||
}
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (m *AuthRolesMutation) SetRole(a authroles.Role) {
|
||||
m.role = &a
|
||||
}
|
||||
|
||||
// Role returns the value of the "role" field in the mutation.
|
||||
func (m *AuthRolesMutation) Role() (r authroles.Role, exists bool) {
|
||||
v := m.role
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldRole returns the old "role" field's value of the AuthRoles entity.
|
||||
// If the AuthRoles object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *AuthRolesMutation) OldRole(ctx context.Context) (v authroles.Role, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldRole is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldRole requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldRole: %w", err)
|
||||
}
|
||||
return oldValue.Role, nil
|
||||
}
|
||||
|
||||
// ResetRole resets all changes to the "role" field.
|
||||
func (m *AuthRolesMutation) ResetRole() {
|
||||
m.role = nil
|
||||
}
|
||||
|
||||
// SetTokenID sets the "token" edge to the AuthTokens entity by id.
|
||||
func (m *AuthRolesMutation) SetTokenID(id uuid.UUID) {
|
||||
m.token = &id
|
||||
}
|
||||
|
||||
// ClearToken clears the "token" edge to the AuthTokens entity.
|
||||
func (m *AuthRolesMutation) ClearToken() {
|
||||
m.clearedtoken = true
|
||||
}
|
||||
|
||||
// TokenCleared reports if the "token" edge to the AuthTokens entity was cleared.
|
||||
func (m *AuthRolesMutation) TokenCleared() bool {
|
||||
return m.clearedtoken
|
||||
}
|
||||
|
||||
// TokenID returns the "token" edge ID in the mutation.
|
||||
func (m *AuthRolesMutation) TokenID() (id uuid.UUID, exists bool) {
|
||||
if m.token != nil {
|
||||
return *m.token, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TokenIDs returns the "token" edge IDs in the mutation.
|
||||
// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use
|
||||
// TokenID instead. It exists only for internal usage by the builders.
|
||||
func (m *AuthRolesMutation) TokenIDs() (ids []uuid.UUID) {
|
||||
if id := m.token; id != nil {
|
||||
ids = append(ids, *id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ResetToken resets all changes to the "token" edge.
|
||||
func (m *AuthRolesMutation) ResetToken() {
|
||||
m.token = nil
|
||||
m.clearedtoken = false
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthRolesMutation builder.
|
||||
func (m *AuthRolesMutation) Where(ps ...predicate.AuthRoles) {
|
||||
m.predicates = append(m.predicates, ps...)
|
||||
}
|
||||
|
||||
// Op returns the operation name.
|
||||
func (m *AuthRolesMutation) Op() Op {
|
||||
return m.op
|
||||
}
|
||||
|
||||
// Type returns the node type of this mutation (AuthRoles).
|
||||
func (m *AuthRolesMutation) Type() string {
|
||||
return m.typ
|
||||
}
|
||||
|
||||
// Fields returns all fields that were changed during this mutation. Note that in
|
||||
// order to get all numeric fields that were incremented/decremented, call
|
||||
// AddedFields().
|
||||
func (m *AuthRolesMutation) Fields() []string {
|
||||
fields := make([]string, 0, 1)
|
||||
if m.role != nil {
|
||||
fields = append(fields, authroles.FieldRole)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
// Field returns the value of a field with the given name. The second boolean
|
||||
// return value indicates that this field was not set, or was not defined in the
|
||||
// schema.
|
||||
func (m *AuthRolesMutation) Field(name string) (ent.Value, bool) {
|
||||
switch name {
|
||||
case authroles.FieldRole:
|
||||
return m.Role()
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// OldField returns the old value of the field from the database. An error is
|
||||
// returned if the mutation operation is not UpdateOne, or the query to the
|
||||
// database failed.
|
||||
func (m *AuthRolesMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
|
||||
switch name {
|
||||
case authroles.FieldRole:
|
||||
return m.OldRole(ctx)
|
||||
}
|
||||
return nil, fmt.Errorf("unknown AuthRoles field %s", name)
|
||||
}
|
||||
|
||||
// SetField sets the value of a field with the given name. It returns an error if
|
||||
// the field is not defined in the schema, or if the type mismatched the field
|
||||
// type.
|
||||
func (m *AuthRolesMutation) SetField(name string, value ent.Value) error {
|
||||
switch name {
|
||||
case authroles.FieldRole:
|
||||
v, ok := value.(authroles.Role)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetRole(v)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown AuthRoles field %s", name)
|
||||
}
|
||||
|
||||
// AddedFields returns all numeric fields that were incremented/decremented during
|
||||
// this mutation.
|
||||
func (m *AuthRolesMutation) AddedFields() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddedField returns the numeric value that was incremented/decremented on a field
|
||||
// with the given name. The second boolean return value indicates that this field
|
||||
// was not set, or was not defined in the schema.
|
||||
func (m *AuthRolesMutation) AddedField(name string) (ent.Value, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// AddField adds the value to the field with the given name. It returns an error if
|
||||
// the field is not defined in the schema, or if the type mismatched the field
|
||||
// type.
|
||||
func (m *AuthRolesMutation) AddField(name string, value ent.Value) error {
|
||||
switch name {
|
||||
}
|
||||
return fmt.Errorf("unknown AuthRoles numeric field %s", name)
|
||||
}
|
||||
|
||||
// ClearedFields returns all nullable fields that were cleared during this
|
||||
// mutation.
|
||||
func (m *AuthRolesMutation) ClearedFields() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FieldCleared returns a boolean indicating if a field with the given name was
|
||||
// cleared in this mutation.
|
||||
func (m *AuthRolesMutation) FieldCleared(name string) bool {
|
||||
_, ok := m.clearedFields[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ClearField clears the value of the field with the given name. It returns an
|
||||
// error if the field is not defined in the schema.
|
||||
func (m *AuthRolesMutation) ClearField(name string) error {
|
||||
return fmt.Errorf("unknown AuthRoles nullable field %s", name)
|
||||
}
|
||||
|
||||
// ResetField resets all changes in the mutation for the field with the given name.
|
||||
// It returns an error if the field is not defined in the schema.
|
||||
func (m *AuthRolesMutation) ResetField(name string) error {
|
||||
switch name {
|
||||
case authroles.FieldRole:
|
||||
m.ResetRole()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown AuthRoles field %s", name)
|
||||
}
|
||||
|
||||
// AddedEdges returns all edge names that were set/added in this mutation.
|
||||
func (m *AuthRolesMutation) AddedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
if m.token != nil {
|
||||
edges = append(edges, authroles.EdgeToken)
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// AddedIDs returns all IDs (to other nodes) that were added for the given edge
|
||||
// name in this mutation.
|
||||
func (m *AuthRolesMutation) AddedIDs(name string) []ent.Value {
|
||||
switch name {
|
||||
case authroles.EdgeToken:
|
||||
if id := m.token; id != nil {
|
||||
return []ent.Value{*id}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemovedEdges returns all edge names that were removed in this mutation.
|
||||
func (m *AuthRolesMutation) RemovedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
return edges
|
||||
}
|
||||
|
||||
// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with
|
||||
// the given name in this mutation.
|
||||
func (m *AuthRolesMutation) RemovedIDs(name string) []ent.Value {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearedEdges returns all edge names that were cleared in this mutation.
|
||||
func (m *AuthRolesMutation) ClearedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
if m.clearedtoken {
|
||||
edges = append(edges, authroles.EdgeToken)
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// EdgeCleared returns a boolean which indicates if the edge with the given name
|
||||
// was cleared in this mutation.
|
||||
func (m *AuthRolesMutation) EdgeCleared(name string) bool {
|
||||
switch name {
|
||||
case authroles.EdgeToken:
|
||||
return m.clearedtoken
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ClearEdge clears the value of the edge with the given name. It returns an error
|
||||
// if that edge is not defined in the schema.
|
||||
func (m *AuthRolesMutation) ClearEdge(name string) error {
|
||||
switch name {
|
||||
case authroles.EdgeToken:
|
||||
m.ClearToken()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown AuthRoles unique edge %s", name)
|
||||
}
|
||||
|
||||
// ResetEdge resets all changes to the edge with the given name in this mutation.
|
||||
// It returns an error if the edge is not defined in the schema.
|
||||
func (m *AuthRolesMutation) ResetEdge(name string) error {
|
||||
switch name {
|
||||
case authroles.EdgeToken:
|
||||
m.ResetToken()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown AuthRoles edge %s", name)
|
||||
}
|
||||
|
||||
// AuthTokensMutation represents an operation that mutates the AuthTokens nodes in the graph.
|
||||
type AuthTokensMutation struct {
|
||||
config
|
||||
|
@ -612,6 +992,8 @@ type AuthTokensMutation struct {
|
|||
clearedFields map[string]struct{}
|
||||
user *uuid.UUID
|
||||
cleareduser bool
|
||||
roles *int
|
||||
clearedroles bool
|
||||
done bool
|
||||
oldValue func(context.Context) (*AuthTokens, error)
|
||||
predicates []predicate.AuthTokens
|
||||
|
@ -904,6 +1286,45 @@ func (m *AuthTokensMutation) ResetUser() {
|
|||
m.cleareduser = false
|
||||
}
|
||||
|
||||
// SetRolesID sets the "roles" edge to the AuthRoles entity by id.
|
||||
func (m *AuthTokensMutation) SetRolesID(id int) {
|
||||
m.roles = &id
|
||||
}
|
||||
|
||||
// ClearRoles clears the "roles" edge to the AuthRoles entity.
|
||||
func (m *AuthTokensMutation) ClearRoles() {
|
||||
m.clearedroles = true
|
||||
}
|
||||
|
||||
// RolesCleared reports if the "roles" edge to the AuthRoles entity was cleared.
|
||||
func (m *AuthTokensMutation) RolesCleared() bool {
|
||||
return m.clearedroles
|
||||
}
|
||||
|
||||
// RolesID returns the "roles" edge ID in the mutation.
|
||||
func (m *AuthTokensMutation) RolesID() (id int, exists bool) {
|
||||
if m.roles != nil {
|
||||
return *m.roles, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RolesIDs returns the "roles" edge IDs in the mutation.
|
||||
// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use
|
||||
// RolesID instead. It exists only for internal usage by the builders.
|
||||
func (m *AuthTokensMutation) RolesIDs() (ids []int) {
|
||||
if id := m.roles; id != nil {
|
||||
ids = append(ids, *id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ResetRoles resets all changes to the "roles" edge.
|
||||
func (m *AuthTokensMutation) ResetRoles() {
|
||||
m.roles = nil
|
||||
m.clearedroles = false
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthTokensMutation builder.
|
||||
func (m *AuthTokensMutation) Where(ps ...predicate.AuthTokens) {
|
||||
m.predicates = append(m.predicates, ps...)
|
||||
|
@ -1073,10 +1494,13 @@ func (m *AuthTokensMutation) ResetField(name string) error {
|
|||
|
||||
// AddedEdges returns all edge names that were set/added in this mutation.
|
||||
func (m *AuthTokensMutation) AddedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
edges := make([]string, 0, 2)
|
||||
if m.user != nil {
|
||||
edges = append(edges, authtokens.EdgeUser)
|
||||
}
|
||||
if m.roles != nil {
|
||||
edges = append(edges, authtokens.EdgeRoles)
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
|
@ -1088,13 +1512,17 @@ func (m *AuthTokensMutation) AddedIDs(name string) []ent.Value {
|
|||
if id := m.user; id != nil {
|
||||
return []ent.Value{*id}
|
||||
}
|
||||
case authtokens.EdgeRoles:
|
||||
if id := m.roles; id != nil {
|
||||
return []ent.Value{*id}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemovedEdges returns all edge names that were removed in this mutation.
|
||||
func (m *AuthTokensMutation) RemovedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
edges := make([]string, 0, 2)
|
||||
return edges
|
||||
}
|
||||
|
||||
|
@ -1106,10 +1534,13 @@ func (m *AuthTokensMutation) RemovedIDs(name string) []ent.Value {
|
|||
|
||||
// ClearedEdges returns all edge names that were cleared in this mutation.
|
||||
func (m *AuthTokensMutation) ClearedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
edges := make([]string, 0, 2)
|
||||
if m.cleareduser {
|
||||
edges = append(edges, authtokens.EdgeUser)
|
||||
}
|
||||
if m.clearedroles {
|
||||
edges = append(edges, authtokens.EdgeRoles)
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
|
@ -1119,6 +1550,8 @@ func (m *AuthTokensMutation) EdgeCleared(name string) bool {
|
|||
switch name {
|
||||
case authtokens.EdgeUser:
|
||||
return m.cleareduser
|
||||
case authtokens.EdgeRoles:
|
||||
return m.clearedroles
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -1130,6 +1563,9 @@ func (m *AuthTokensMutation) ClearEdge(name string) error {
|
|||
case authtokens.EdgeUser:
|
||||
m.ClearUser()
|
||||
return nil
|
||||
case authtokens.EdgeRoles:
|
||||
m.ClearRoles()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown AuthTokens unique edge %s", name)
|
||||
}
|
||||
|
@ -1141,6 +1577,9 @@ func (m *AuthTokensMutation) ResetEdge(name string) error {
|
|||
case authtokens.EdgeUser:
|
||||
m.ResetUser()
|
||||
return nil
|
||||
case authtokens.EdgeRoles:
|
||||
m.ResetRoles()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown AuthTokens edge %s", name)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ import (
|
|||
// Attachment is the predicate function for attachment builders.
|
||||
type Attachment func(*sql.Selector)
|
||||
|
||||
// AuthRoles is the predicate function for authroles builders.
|
||||
type AuthRoles func(*sql.Selector)
|
||||
|
||||
// AuthTokens is the predicate function for authtokens builders.
|
||||
type AuthTokens func(*sql.Selector)
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ func init() {
|
|||
attachmentDescID := attachmentMixinFields0[0].Descriptor()
|
||||
// attachment.DefaultID holds the default value on creation for the id field.
|
||||
attachment.DefaultID = attachmentDescID.Default.(func() uuid.UUID)
|
||||
authrolesFields := schema.AuthRoles{}.Fields()
|
||||
_ = authrolesFields
|
||||
authtokensMixin := schema.AuthTokens{}.Mixin()
|
||||
authtokensMixinFields0 := authtokensMixin[0].Fields()
|
||||
_ = authtokensMixinFields0
|
||||
|
|
34
backend/internal/data/ent/schema/auth_roles.go
Normal file
34
backend/internal/data/ent/schema/auth_roles.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
)
|
||||
|
||||
// AuthRoles holds the schema definition for the AuthRoles entity.
|
||||
type AuthRoles struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
// Fields of the AuthRoles.
|
||||
func (AuthRoles) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.Enum("role").
|
||||
Default("user").
|
||||
Values(
|
||||
"admin", // can do everything - currently unused
|
||||
"user", // default login role
|
||||
"attachments", // Read Attachments
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// Edges of the AuthRoles.
|
||||
func (AuthRoles) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.From("token", AuthTokens.Type).
|
||||
Ref("roles").
|
||||
Unique(),
|
||||
}
|
||||
}
|
|
@ -37,6 +37,8 @@ func (AuthTokens) Edges() []ent.Edge {
|
|||
edge.From("user", User.Type).
|
||||
Ref("auth_tokens").
|
||||
Unique(),
|
||||
edge.To("roles", AuthRoles.Type).
|
||||
Unique(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ type Tx struct {
|
|||
config
|
||||
// Attachment is the client for interacting with the Attachment builders.
|
||||
Attachment *AttachmentClient
|
||||
// AuthRoles is the client for interacting with the AuthRoles builders.
|
||||
AuthRoles *AuthRolesClient
|
||||
// AuthTokens is the client for interacting with the AuthTokens builders.
|
||||
AuthTokens *AuthTokensClient
|
||||
// Document is the client for interacting with the Document builders.
|
||||
|
@ -166,6 +168,7 @@ func (tx *Tx) Client() *Client {
|
|||
|
||||
func (tx *Tx) init() {
|
||||
tx.Attachment = NewAttachmentClient(tx.config)
|
||||
tx.AuthRoles = NewAuthRolesClient(tx.config)
|
||||
tx.AuthTokens = NewAuthTokensClient(tx.config)
|
||||
tx.Document = NewDocumentClient(tx.config)
|
||||
tx.DocumentToken = NewDocumentTokenClient(tx.config)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
-- create "auth_roles" table
|
||||
CREATE TABLE `auth_roles` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `role` text NOT NULL DEFAULT 'user', `auth_tokens_roles` uuid NULL, CONSTRAINT `auth_roles_auth_tokens_roles` FOREIGN KEY (`auth_tokens_roles`) REFERENCES `auth_tokens` (`id`) ON DELETE SET NULL);
|
||||
-- create index "auth_roles_auth_tokens_roles_key" to table: "auth_roles"
|
||||
CREATE UNIQUE INDEX `auth_roles_auth_tokens_roles_key` ON `auth_roles` (`auth_tokens_roles`);
|
|
@ -1,7 +1,8 @@
|
|||
h1:z1tbZ3fYByqxL78Z+ov8mfQVjXcwsZeEcT0i+2DZ8a8=
|
||||
h1:oo2QbYbKkbf4oTfkRXqo9XGPp8S76j33WQvDZITv5s8=
|
||||
20220929052825_init.sql h1:ZlCqm1wzjDmofeAcSX3jE4h4VcdTNGpRg2eabztDy9Q=
|
||||
20221001210956_group_invitations.sql h1:YQKJFtE39wFOcRNbZQ/d+ZlHwrcfcsZlcv/pLEYdpjw=
|
||||
20221009173029_add_user_roles.sql h1:vWmzAfgEWQeGk0Vn70zfVPCcfEZth3E0JcvyKTjpYyU=
|
||||
20221020043305_allow_nesting_types.sql h1:4AyJpZ7l7SSJtJAQETYY802FHJ64ufYPJTqvwdiGn3M=
|
||||
20221101041931_add_archived_field.sql h1:L2WxiOh1svRn817cNURgqnEQg6DIcodZ1twK4tvxW94=
|
||||
20221113012312_add_asset_id_field.sql h1:DjD7e1PS8OfxGBWic8h0nO/X6CNnHEMqQjDCaaQ3M3Q=
|
||||
20221203053132_add_token_roles.sql h1:wFTIh+KBoHfLfy/L0ZmJz4cNXKHdACG9ZK/yvVKjF0M=
|
||||
|
|
|
@ -6,7 +6,10 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/set"
|
||||
)
|
||||
|
||||
type TokenRepository struct {
|
||||
|
@ -47,9 +50,31 @@ func (r *TokenRepository) GetUserFromToken(ctx context.Context, token []byte) (U
|
|||
return mapUserOut(user), nil
|
||||
}
|
||||
|
||||
// Creates a token for a user
|
||||
func (r *TokenRepository) CreateToken(ctx context.Context, createToken UserAuthTokenCreate) (UserAuthToken, error) {
|
||||
func (r *TokenRepository) GetRoles(ctx context.Context, token string) (*set.Set[string], error) {
|
||||
tokenHash := hasher.HashToken(token)
|
||||
|
||||
roles, err := r.db.AuthRoles.
|
||||
Query().
|
||||
Where(authroles.HasTokenWith(
|
||||
authtokens.Token(tokenHash),
|
||||
)).
|
||||
All(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roleSet := set.Make[string](len(roles))
|
||||
|
||||
for _, role := range roles {
|
||||
roleSet.Insert(role.Role.String())
|
||||
}
|
||||
|
||||
return &roleSet, nil
|
||||
}
|
||||
|
||||
// Creates a token for a user
|
||||
func (r *TokenRepository) CreateToken(ctx context.Context, createToken UserAuthTokenCreate, roles ...authroles.Role) (UserAuthToken, error) {
|
||||
dbToken, err := r.db.AuthTokens.Create().
|
||||
SetToken(createToken.TokenHash).
|
||||
SetUserID(createToken.UserID).
|
||||
|
@ -60,6 +85,17 @@ func (r *TokenRepository) CreateToken(ctx context.Context, createToken UserAuthT
|
|||
return UserAuthToken{}, err
|
||||
}
|
||||
|
||||
for _, role := range roles {
|
||||
_, err := r.db.AuthRoles.Create().
|
||||
SetRole(role).
|
||||
SetToken(dbToken).
|
||||
Save(ctx)
|
||||
|
||||
if err != nil {
|
||||
return UserAuthToken{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return UserAuthToken{
|
||||
UserAuthTokenCreate: UserAuthTokenCreate{
|
||||
TokenHash: dbToken.Token,
|
||||
|
|
|
@ -8,6 +8,12 @@ type Set[T key] struct {
|
|||
mp map[T]struct{}
|
||||
}
|
||||
|
||||
func Make[T key](size int) Set[T] {
|
||||
return Set[T]{
|
||||
mp: make(map[T]struct{}, size),
|
||||
}
|
||||
}
|
||||
|
||||
func New[T key](v ...T) Set[T] {
|
||||
mp := make(map[T]struct{}, len(v))
|
||||
|
||||
|
|
|
@ -10,7 +10,12 @@
|
|||
<span class="ml-2 w-0 flex-1 truncate"> {{ attachment.document.title }}</span>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0">
|
||||
<button class="font-medium" @click="getAttachmentUrl(attachment)">Download</button>
|
||||
<a class="tooltip mr-2" data-tip="Download" :href="attachmentURL(attachment.id)" target="_blank">
|
||||
<Icon class="h-5 w-5" name="mdi-download" />
|
||||
</a>
|
||||
<a class="tooltip" data-tip="Open" :href="attachmentURL(attachment.id)" target="_blank">
|
||||
<Icon class="h-5 w-5" name="mdi-open-in-new" />
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -31,25 +36,9 @@
|
|||
});
|
||||
|
||||
const api = useUserApi();
|
||||
const toast = useNotifier();
|
||||
async function getAttachmentUrl(attachment: ItemAttachment) {
|
||||
const url = await api.items.getAttachmentUrl(props.itemId, attachment.id);
|
||||
|
||||
if (!url) {
|
||||
toast.error("Failed to get attachment url");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!document) {
|
||||
window.open(url, "_blank");
|
||||
return;
|
||||
}
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.target = "_blank";
|
||||
link.setAttribute("download", attachment.document.title);
|
||||
link.click();
|
||||
function attachmentURL(attachmentId: string) {
|
||||
return api.authURL(`/items/${props.itemId}/attachments/${attachmentId}`);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -43,5 +43,5 @@ export function useUserApi(): UserClient {
|
|||
requests.addResponseInterceptor(observer.handler);
|
||||
}
|
||||
|
||||
return new UserClient(requests);
|
||||
return new UserClient(requests, authStore.attachmentToken);
|
||||
}
|
||||
|
|
|
@ -27,9 +27,21 @@ export function parseDate<T>(obj: T, keys: Array<keyof T> = []): T {
|
|||
|
||||
export class BaseAPI {
|
||||
http: Requests;
|
||||
attachmentToken: string;
|
||||
|
||||
constructor(requests: Requests) {
|
||||
constructor(requests: Requests, attachmentToken = "") {
|
||||
this.http = requests;
|
||||
this.attachmentToken = attachmentToken;
|
||||
}
|
||||
|
||||
// if a attachmentToken is present it will be added to URL as a query param
|
||||
// this is done with a simple appending of the query param to the URL. If your
|
||||
// URL already has a query param, this will not work.
|
||||
authURL(url: string): string {
|
||||
if (this.attachmentToken) {
|
||||
return `/api/v1${url}?access_token=${this.attachmentToken}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
import { BaseAPI, route } from "../base";
|
||||
import { parseDate } from "../base/base-api";
|
||||
import {
|
||||
ItemAttachmentToken,
|
||||
ItemAttachmentUpdate,
|
||||
ItemCreate,
|
||||
ItemOut,
|
||||
ItemSummary,
|
||||
ItemUpdate,
|
||||
} from "../types/data-contracts";
|
||||
import { ItemAttachmentUpdate, ItemCreate, ItemOut, ItemSummary, ItemUpdate } from "../types/data-contracts";
|
||||
import { AttachmentTypes, PaginationResult } from "../types/non-generated";
|
||||
|
||||
export type ItemsQuery = {
|
||||
|
@ -79,18 +72,6 @@ export class ItemsApi extends BaseAPI {
|
|||
});
|
||||
}
|
||||
|
||||
async getAttachmentUrl(id: string, attachmentId: string): Promise<string> {
|
||||
const payload = await this.http.get<ItemAttachmentToken>({
|
||||
url: route(`/items/${id}/attachments/${attachmentId}`),
|
||||
});
|
||||
|
||||
if (!payload.data) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return route(`/items/${id}/attachments/download`, { token: payload.data.token });
|
||||
}
|
||||
|
||||
async deleteAttachment(id: string, attachmentId: string) {
|
||||
return await this.http.delete<void>({ url: route(`/items/${id}/attachments/${attachmentId}`) });
|
||||
}
|
||||
|
|
|
@ -324,6 +324,7 @@ export interface ItemAttachmentToken {
|
|||
}
|
||||
|
||||
export interface TokenResponse {
|
||||
attachmentToken: string;
|
||||
expiresAt: Date;
|
||||
token: string;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ export class UserClient extends BaseAPI {
|
|||
user: UserApi;
|
||||
actions: ActionsAPI;
|
||||
|
||||
constructor(requests: Requests) {
|
||||
super(requests);
|
||||
constructor(requests: Requests, attachmentToken: string) {
|
||||
super(requests, attachmentToken);
|
||||
|
||||
this.locations = new LocationsApi(requests);
|
||||
this.labels = new LabelsApi(requests);
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
authStore.$patch({
|
||||
token: data.token,
|
||||
expires: data.expiresAt,
|
||||
attachmentToken: data.attachmentToken,
|
||||
});
|
||||
|
||||
navigateTo("/home");
|
||||
|
|
|
@ -27,17 +27,32 @@
|
|||
});
|
||||
|
||||
type FilteredAttachments = {
|
||||
photos: ItemAttachment[];
|
||||
attachments: ItemAttachment[];
|
||||
warranty: ItemAttachment[];
|
||||
manuals: ItemAttachment[];
|
||||
receipts: ItemAttachment[];
|
||||
};
|
||||
|
||||
type Photo = {
|
||||
src: string;
|
||||
};
|
||||
|
||||
const photos = computed<Photo[]>(() => {
|
||||
return (
|
||||
item.value?.attachments.reduce((acc, cur) => {
|
||||
if (cur.type === "photo") {
|
||||
acc.push({
|
||||
src: api.authURL(`/items/${item.value.id}/attachments/${cur.id}`),
|
||||
});
|
||||
}
|
||||
return acc;
|
||||
}, [] as Photo[]) || []
|
||||
);
|
||||
});
|
||||
|
||||
const attachments = computed<FilteredAttachments>(() => {
|
||||
if (!item.value) {
|
||||
return {
|
||||
photos: [],
|
||||
attachments: [],
|
||||
manuals: [],
|
||||
warranty: [],
|
||||
|
@ -48,8 +63,9 @@
|
|||
return item.value.attachments.reduce(
|
||||
(acc, attachment) => {
|
||||
if (attachment.type === "photo") {
|
||||
acc.photos.push(attachment);
|
||||
} else if (attachment.type === "warranty") {
|
||||
return acc;
|
||||
}
|
||||
if (attachment.type === "warranty") {
|
||||
acc.warranty.push(attachment);
|
||||
} else if (attachment.type === "manual") {
|
||||
acc.manuals.push(attachment);
|
||||
|
@ -61,7 +77,6 @@
|
|||
return acc;
|
||||
},
|
||||
{
|
||||
photos: [] as ItemAttachment[],
|
||||
attachments: [] as ItemAttachment[],
|
||||
warranty: [] as ItemAttachment[],
|
||||
manuals: [] as ItemAttachment[],
|
||||
|
@ -144,7 +159,6 @@
|
|||
}
|
||||
|
||||
return (
|
||||
attachments.value.photos.length > 0 ||
|
||||
attachments.value.attachments.length > 0 ||
|
||||
attachments.value.warranty.length > 0 ||
|
||||
attachments.value.manuals.length > 0 ||
|
||||
|
@ -163,10 +177,6 @@
|
|||
});
|
||||
};
|
||||
|
||||
if (attachments.value.photos.length > 0) {
|
||||
push("Photos");
|
||||
}
|
||||
|
||||
if (attachments.value.attachments.length > 0) {
|
||||
push("Attachments");
|
||||
}
|
||||
|
@ -292,10 +302,43 @@
|
|||
toast.success("Item deleted");
|
||||
navigateTo("/home");
|
||||
}
|
||||
|
||||
const refDialog = ref<HTMLDialogElement>();
|
||||
const dialoged = reactive({
|
||||
src: "",
|
||||
});
|
||||
|
||||
function openDialog(img: Photo) {
|
||||
refDialog.value.showModal();
|
||||
dialoged.src = img.src;
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
refDialog.value.close();
|
||||
}
|
||||
|
||||
const refDialogBody = ref<HTMLDivElement>();
|
||||
onClickOutside(refDialogBody, () => {
|
||||
closeDialog();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseContainer v-if="item" class="pb-8">
|
||||
<dialog ref="refDialog" class="z-[999] fixed bg-transparent">
|
||||
<div ref="refDialogBody" class="relative">
|
||||
<div class="absolute right-0 -mt-3 -mr-3 sm:-mt-4 sm:-mr-4 space-x-1">
|
||||
<a class="btn btn-sm sm:btn-md btn-primary btn-circle" :href="dialoged.src" download>
|
||||
<Icon class="h-5 w-5" name="mdi-download" />
|
||||
</a>
|
||||
<button class="btn btn-sm sm:btn-md btn-primary btn-circle" @click="closeDialog()">
|
||||
<Icon class="h-5 w-5" name="mdi-close" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<img class="max-w-[80vw] max-h-[80vh]" :src="dialoged.src" />
|
||||
</div>
|
||||
</dialog>
|
||||
<section class="px-3">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="form-control"></div>
|
||||
|
@ -353,6 +396,15 @@
|
|||
<DetailsSection :details="itemDetails" />
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard>
|
||||
<template #title> Photos </template>
|
||||
<div class="container p-4 flex flex-wrap gap-2 mx-auto max-h-[500px] overflow-scroll">
|
||||
<button v-for="(img, i) in photos" :key="i" @click="openDialog(img)">
|
||||
<img class="rounded max-h-[200px]" :src="img.src" />
|
||||
</button>
|
||||
</div>
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard v-if="showAttachments">
|
||||
<template #title> Attachments </template>
|
||||
<DetailsSection :details="attachmentDetails">
|
||||
|
@ -377,13 +429,6 @@
|
|||
:item-id="item.id"
|
||||
/>
|
||||
</template>
|
||||
<template #photos>
|
||||
<ItemAttachmentsList
|
||||
v-if="attachments.photos.length > 0"
|
||||
:attachments="attachments.photos"
|
||||
:item-id="item.id"
|
||||
/>
|
||||
</template>
|
||||
<template #receipts>
|
||||
<ItemAttachmentsList
|
||||
v-if="attachments.receipts.length > 0"
|
||||
|
@ -419,3 +464,10 @@
|
|||
</section>
|
||||
</BaseContainer>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
/* Style dialog background */
|
||||
dialog::backdrop {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -6,6 +6,7 @@ import { UserOut } from "~~/lib/api/types/data-contracts";
|
|||
export const useAuthStore = defineStore("auth", {
|
||||
state: () => ({
|
||||
token: useLocalStorage("pinia/auth/token", ""),
|
||||
attachmentToken: useLocalStorage("pinia/auth/attachmentToken", ""),
|
||||
expires: useLocalStorage("pinia/auth/expires", ""),
|
||||
self: null as UserOut | null,
|
||||
}),
|
||||
|
@ -27,6 +28,7 @@ export const useAuthStore = defineStore("auth", {
|
|||
const result = await api.user.logout();
|
||||
|
||||
this.token = "";
|
||||
this.attachmentToken = "";
|
||||
this.expires = "";
|
||||
this.self = null;
|
||||
|
||||
|
|
Loading…
Reference in a new issue