splitted one operator module to file, account, image operators; splitted operator functions; etc

This commit is contained in:
2026-03-05 11:32:32 +02:00
parent 9ecd25ed0b
commit 80d6a244cf
54 changed files with 1049 additions and 826 deletions
-2
View File
@@ -68,7 +68,6 @@ EXTRA_mstored_SOURCES += \
\
app/operator/account.go \
app/operator/blob.go \
app/operator/file.go \
app/operator/grant.go \
app/operator/imgaux.go \
app/operator/manifest.go \
@@ -103,7 +102,6 @@ EXTRA_mstored_SOURCES += \
pkg/client/account.go \
pkg/client/client.go \
pkg/client/fileaux.go \
pkg/client/file.go \
pkg/client/grant.go \
pkg/client/httpcall.go \
pkg/client/imageaux.go \
+19 -19
View File
@@ -376,26 +376,26 @@ EXTRA_mstored_SOURCES = cmd/mstored/starter/starter.go \
app/maindb/grant.go app/maindb/init.go app/maindb/maindb.go \
app/maindb/manifest.go app/maindb/scheme.go \
app/operator/account.go app/operator/blob.go \
app/operator/file.go app/operator/grant.go \
app/operator/imgaux.go app/operator/manifest.go \
app/operator/ociaux.go app/operator/operator.go \
app/operator/service.go app/operator/version.go \
app/router/bindobj.go app/router/context.go \
app/router/corsmw.go app/router/loggingmw.go \
app/router/pathc.go app/router/recovermw.go \
app/router/router.go app/server/server.go \
app/service/service.go app/storage/storage.go \
pkg/auxhttp/basic.go pkg/auxhttp/crange.go \
pkg/auxoci/ociaux.go pkg/auxpwd/passwd.go \
pkg/auxtool/cleandir.go pkg/auxtool/fileex.go \
pkg/auxtool/randstr.go pkg/auxtool/tmpfile.go \
pkg/auxtool/unixnow.go pkg/auxutar/utar.go pkg/auxuuid/uuid.go \
app/operator/grant.go app/operator/imgaux.go \
app/operator/manifest.go app/operator/ociaux.go \
app/operator/operator.go app/operator/service.go \
app/operator/version.go app/router/bindobj.go \
app/router/context.go app/router/corsmw.go \
app/router/loggingmw.go app/router/pathc.go \
app/router/recovermw.go app/router/router.go \
app/server/server.go app/service/service.go \
app/storage/storage.go pkg/auxhttp/basic.go \
pkg/auxhttp/crange.go pkg/auxoci/ociaux.go \
pkg/auxpwd/passwd.go pkg/auxtool/cleandir.go \
pkg/auxtool/fileex.go pkg/auxtool/randstr.go \
pkg/auxtool/tmpfile.go pkg/auxtool/unixnow.go \
pkg/auxutar/utar.go pkg/auxuuid/uuid.go \
pkg/auxx509/x509cert.go pkg/client/account.go \
pkg/client/client.go pkg/client/fileaux.go pkg/client/file.go \
pkg/client/grant.go pkg/client/httpcall.go \
pkg/client/imageaux.go pkg/client/imagedelete.go \
pkg/client/imageinfo.go pkg/client/imagepull.go \
pkg/client/imagepush.go pkg/client/service.go
pkg/client/client.go pkg/client/fileaux.go pkg/client/grant.go \
pkg/client/httpcall.go pkg/client/imageaux.go \
pkg/client/imagedelete.go pkg/client/imageinfo.go \
pkg/client/imagepull.go pkg/client/imagepush.go \
pkg/client/service.go
CWD = $(shell pwd)
EXTRA_DIST = vendor/ \
\
+70
View File
@@ -0,0 +1,70 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package accoper
import (
"context"
"fmt"
"mstore/pkg/auxpwd"
"mstore/pkg/auxtool"
"mstore/pkg/auxuuid"
"mstore/pkg/descr"
)
type CreateAccountParams struct {
Username string `json:"username"`
Password string `json:"password"`
}
type CreateAccountResult struct {
AccountID string `json:"accountId"`
}
func (oper *Operator) CreateAccount(ctx context.Context, operatorID string, params *CreateAccountParams) (*CreateAccountResult, error) {
var err error
res := &CreateAccountResult{}
if params.Username == "" {
err := fmt.Errorf("Empty username parameters")
return res, err
}
if params.Password == "" {
err := fmt.Errorf("Empty password parameter")
return res, err
}
accountExists, _, err := oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if accountExists {
err := fmt.Errorf("Account with thist name already exists")
return res, err
}
now := auxtool.TimeNow()
passhash := auxpwd.MakeSHA256Hash([]byte(params.Password))
accountDescr := &descr.Account{
ID: auxuuid.NewUUID(),
Username: params.Username,
Passhash: passhash,
Disabled: false,
CreatedAt: now,
UpdatedAt: now,
CreatedBy: operatorID,
UpdatedBy: operatorID,
}
err = oper.mdb.InsertAccount(ctx, accountDescr)
if err != nil {
return res, err
}
res.AccountID = accountDescr.ID
return res, err
}
+98
View File
@@ -0,0 +1,98 @@
package accoper
import (
"context"
"fmt"
"regexp"
"mstore/pkg/auxtool"
"mstore/pkg/auxuuid"
"mstore/pkg/descr"
)
// CreateGrant
type CreateGrantParams struct {
AccountID string `json:"accountID"`
Username string `json:"username"`
Right string `json:"operation"`
Pattern string `json:"pattern"`
}
type CreateGrantResult struct {
GrantID string `json:"grantId"`
}
func (oper *Operator) CreateGrant(ctx context.Context, operatorID string, params *CreateGrantParams) (*CreateGrantResult, error) {
var err error
res := &CreateGrantResult{}
if params.AccountID == "" {
err := fmt.Errorf("Empty accountId parameters")
return res, err
}
if params.Right == "" {
err := fmt.Errorf("Empty operation parameter")
return res, err
}
if params.Pattern == "" {
err := fmt.Errorf("Empty pattern parameter")
return res, err
}
_, err = regexp.Compile(params.Pattern)
if err != nil {
err := fmt.Errorf("Cannot compile regexp %s: %v", err)
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
grantExists, _, err := oper.mdb.GetGrantByAccoundIDRightPattern(ctx, params.AccountID, params.Right, params.Pattern)
if err != nil {
return res, err
}
if grantExists {
err := fmt.Errorf("Grant with this right already exists")
return res, err
}
oper.logg.Debugf("Call CreateGrant")
now := auxtool.TimeNow()
grantDescr := &descr.Grant{
ID: auxuuid.NewUUID(),
AccountID: accountDescr.ID,
Right: params.Right,
Pattern: params.Pattern,
CreatedAt: now,
UpdatedAt: now,
CreatedBy: operatorID,
UpdatedBy: operatorID,
}
err = oper.mdb.InsertGrant(ctx, grantDescr)
if err != nil {
return res, err
}
res.GrantID = grantDescr.ID
return res, err
}
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package accoper
import (
"context"
"fmt"
"mstore/pkg/descr"
)
type DeleteAccountParams struct {
Username string `json:"username"`
AccountID string `json:"accountId"`
}
type DeleteAccountResult struct{}
func (oper *Operator) DeleteAccount(ctx context.Context, operatorID string, params *DeleteAccountParams) (*DeleteAccountResult, error) {
var err error
res := &DeleteAccountResult{}
if params.Username == "" && params.AccountID == "" {
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
if accountDescr == nil {
err := fmt.Errorf("Null account desriptor")
return res, err
}
err = oper.mdb.DeleteAllGrantsForAccountID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
err = oper.mdb.DeleteAccountByID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
return res, err
}
+41
View File
@@ -0,0 +1,41 @@
package accoper
import (
"context"
"fmt"
"mstore/pkg/descr"
)
// DeleteGrant
type DeleteGrantParams struct {
GrantID string `json:"grantId"`
}
type DeleteGrantResult struct{}
func (oper *Operator) DeleteGrant(ctx context.Context, operatorID string, params *DeleteGrantParams) (*DeleteGrantResult, error) {
var err error
res := &DeleteGrantResult{}
if params.GrantID == "" {
err := fmt.Errorf("Empty grantId parameter")
return res, err
}
var grantDescr *descr.Grant
var grantExists bool
grantExists, grantDescr, err = oper.mdb.GetGrantByID(ctx, params.GrantID)
if err != nil {
return res, err
}
if !grantExists {
err := fmt.Errorf("Grant with ID %s dont exists", params.GrantID)
return res, err
}
err = oper.mdb.DeleteGrantByID(ctx, grantDescr.ID)
if err != nil {
return res, err
}
return res, err
}
+84
View File
@@ -0,0 +1,84 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package accoper
import (
"context"
"fmt"
"mstore/pkg/descr"
)
// GetAccount
type GetAccountParams struct {
Username string `json:"username"`
AccountID string `json:"accountId"`
}
type GetAccountResult struct {
Account *descr.AccountShort `json:"account"`
}
func (oper *Operator) GetAccount(ctx context.Context, operatorID string, params *GetAccountParams) (*GetAccountResult, error) {
var err error
res := &GetAccountResult{}
if params.Username == "" && params.AccountID == "" {
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
if accountDescr == nil {
err := fmt.Errorf("Null account desriptor")
return res, err
}
accountShort := &descr.AccountShort{
ID: accountDescr.ID,
Username: accountDescr.Username,
CreatedAt: accountDescr.CreatedAt,
UpdatedAt: accountDescr.UpdatedAt,
CreatedBy: accountDescr.CreatedBy,
UpdatedBy: accountDescr.UpdatedBy,
Disabled: accountDescr.Disabled,
Grants: make([]descr.Grant, 0),
}
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
accountShort.Grants = grantDescrs
res.Account = accountShort
return res, err
}
+40
View File
@@ -0,0 +1,40 @@
package accoper
import (
"context"
"fmt"
"mstore/pkg/descr"
)
// Get Grants
type GetGrantParams struct {
GrantID string `json:"grantId"`
}
type GetGrantResult struct {
Grant *descr.Grant `json:"grant"`
}
func (oper *Operator) GetGrant(ctx context.Context, operatorID string, params *GetGrantParams) (*GetGrantResult, error) {
var err error
res := &GetGrantResult{}
if params.GrantID == "" {
err := fmt.Errorf("Empty grantId parameter")
return res, err
}
var grantDescr *descr.Grant
var grantExists bool
grantExists, grantDescr, err = oper.mdb.GetGrantByID(ctx, params.GrantID)
if err != nil {
return res, err
}
if !grantExists {
err := fmt.Errorf("Grant with ID %s dont exists", params.GrantID)
return res, err
}
res.Grant = grantDescr
return res, err
}
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package accoper
import (
"context"
"mstore/pkg/descr"
)
type ListAccountsParams struct{}
type ListAccountsResult struct {
Accounts []descr.AccountShort `json:"accounts"`
}
func (oper *Operator) ListAccounts(ctx context.Context, params *ListAccountsParams) (*ListAccountsResult, error) {
var err error
res := &ListAccountsResult{}
accountDescrs, err := oper.mdb.ReducedListAccounts(ctx)
if err != nil {
return res, err
}
for _, accountDescr := range accountDescrs {
accountShort := descr.AccountShort{
ID: accountDescr.ID,
Username: accountDescr.Username,
Disabled: accountDescr.Disabled,
CreatedAt: accountDescr.CreatedAt,
UpdatedAt: accountDescr.UpdatedAt,
CreatedBy: accountDescr.CreatedBy,
UpdatedBy: accountDescr.UpdatedBy,
Grants: make([]descr.Grant, 0),
}
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
accountShort.Grants = grantDescrs
res.Accounts = append(res.Accounts, accountShort)
}
return res, err
}
+56
View File
@@ -0,0 +1,56 @@
package accoper
import (
"context"
"fmt"
"mstore/pkg/descr"
)
// ListGrants
type ListGrantsParams struct {
Username string
AccountID string
}
type ListGrantsResult struct {
Grants []descr.Grant `json:"grants"`
}
func (oper *Operator) ListGrants(ctx context.Context, operatorID string, params *ListGrantsParams) (*ListGrantsResult, error) {
var err error
res := &ListGrantsResult{
Grants: make([]descr.Grant, 0),
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
accountID := accountDescr.ID
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountID)
if err != nil {
return res, err
}
res.Grants = grantDescrs
return res, err
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package accoper
import (
"mstore/app/locker"
@@ -37,6 +37,6 @@ func NewOperator(params *OperatorParams) (*Operator, error) {
}
oper.iLock = locker.NewLocker()
oper.fLock = locker.NewLocker()
oper.logg = logger.NewLoggerWithSubject("operator")
oper.logg = logger.NewLoggerWithSubject("imageoper")
return oper, err
}
+86
View File
@@ -0,0 +1,86 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package accoper
import (
"context"
"fmt"
"mstore/pkg/auxpwd"
"mstore/pkg/auxtool"
"mstore/pkg/descr"
)
type UpdateAccountParams struct {
Username string `json:"username"`
AccountID string `json:"accountId"`
NewUsername string `json:"newUsername"`
NewPassword string `json:"newPassword"`
Disabled bool `json:"disabled"`
}
type UpdateAccountResult struct{}
func (oper *Operator) UpdateAccount(ctx context.Context, operatorID string, params *UpdateAccountParams) (*UpdateAccountResult, error) {
var err error
res := &UpdateAccountResult{}
if params.Username == "" && params.AccountID == "" {
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
if accountDescr == nil {
err := fmt.Errorf("Null account desriptor")
return res, err
}
now := auxtool.TimeNow()
if params.NewUsername != "" {
accountDescr.UpdatedAt = now
accountDescr.Username = params.NewUsername
}
if params.NewPassword != "" {
accountDescr.UpdatedAt = now
passhash := auxpwd.MakeSHA256Hash([]byte(params.NewPassword))
accountDescr.Passhash = passhash
}
if params.Disabled != accountDescr.Disabled {
accountDescr.UpdatedAt = now
accountDescr.Disabled = params.Disabled
}
err = oper.mdb.UpdateAccountByID(ctx, accountDescr.ID, accountDescr)
if err != nil {
return res, err
}
return res, err
}
+52
View File
@@ -0,0 +1,52 @@
package accoper
import (
"context"
"fmt"
"mstore/pkg/auxtool"
"mstore/pkg/descr"
)
// UpdateGrant
type UpdateGrantParams struct {
GrantID string
NewPattern string
}
type UpdateGrantResult struct{}
func (oper *Operator) UpdateGrant(ctx context.Context, operatorID string, params *UpdateGrantParams) (*UpdateGrantResult, error) {
var err error
res := &UpdateGrantResult{}
if params.NewPattern == "" {
err := fmt.Errorf("Empty newPattern parameter")
return res, err
}
if params.GrantID == "" {
err := fmt.Errorf("Empty grantId parameter")
return res, err
}
var grantDescr *descr.Grant
var grantExists bool
grantExists, grantDescr, err = oper.mdb.GetGrantByID(ctx, params.GrantID)
if err != nil {
return res, err
}
if !grantExists {
err := fmt.Errorf("Grant with ID %s dont exists", params.GrantID)
return res, err
}
now := auxtool.TimeNow()
if params.NewPattern != "" {
grantDescr.UpdatedAt = now
grantDescr.UpdatedBy = operatorID
grantDescr.Pattern = params.NewPattern
}
err = oper.mdb.UpdateGrantByID(ctx, grantDescr.ID, grantDescr)
if err != nil {
return res, err
}
return res, err
}
+10
View File
@@ -0,0 +1,10 @@
package config
const (
confdir = "/home/ziggi/Projects/mstore/etc/mstore"
rundir = "/home/ziggi/Projects/mstore/tmp/run"
logdir = "/home/ziggi/Projects/mstore/tmp/log"
datadir = "/home/ziggi/Projects/mstore/tmp/data"
version = "0.2.0"
srvname = "mstored"
)
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package fileoper
import (
"context"
@@ -17,7 +17,6 @@ import (
"mstore/pkg/filecli"
)
// DeleteColletion
type DeleteColletionParams struct {
Path string
@@ -116,5 +115,3 @@ func (oper *Operator) deleteFilesInCollection(ctx context.Context, collection st
}
return res, err
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package fileoper
import (
"context"
@@ -15,7 +15,6 @@ import (
"path"
)
// DeleteFile
type DeleteFileParams struct {
Filepath string
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package fileoper
import (
"context"
@@ -81,4 +81,3 @@ func (oper *Operator) FileInfo(ctx context.Context, operatorID string, params *F
}
return code, res, err
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package fileoper
import (
"context"
@@ -77,4 +77,3 @@ func (oper *Operator) GetFile(ctx context.Context, operatorID string, params *Ge
code := http.StatusOK
return code, res, err
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package fileoper
import (
"context"
@@ -150,4 +150,3 @@ func (oper *Operator) listAllCollections(ctx context.Context) ([]string, error)
slices.Sort(res)
return res, err
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package fileoper
import (
"context"
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package fileoper
import (
"mstore/app/locker"
"mstore/app/logger"
"mstore/app/maindb"
"mstore/app/storage"
)
type OperatorParams struct {
MainDB *maindb.Database
Store *storage.Storage
}
type Operator struct {
mdb *maindb.Database
store *storage.Storage
logg *logger.Logger
iLock *locker.Locker
fLock *locker.Locker
}
func NewOperator(params *OperatorParams) (*Operator, error) {
var err error
oper := &Operator{
mdb: params.MainDB,
store: params.Store,
}
oper.iLock = locker.NewLocker()
oper.fLock = locker.NewLocker()
oper.logg = logger.NewLoggerWithSubject("fileoper")
return oper, err
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package fileoper
import (
"context"
@@ -118,4 +118,3 @@ func (oper *Operator) PutFile(ctx context.Context, operatorID string, params *Pu
code := http.StatusOK
return code, res, err
}
+11 -11
View File
@@ -12,7 +12,7 @@ package handler
import (
"fmt"
"mstore/app/operator"
"mstore/app/accoper"
"mstore/app/router"
"mstore/pkg/terms"
)
@@ -21,7 +21,7 @@ import (
func (hand *Handler) CreateAccount(rctx *router.Context) {
var err error
params := &operator.CreateAccountParams{}
params := &accoper.CreateAccountParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -41,7 +41,7 @@ func (hand *Handler) CreateAccount(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.CreateAccount(rctx.Ctx, operatorID, params)
res, err := hand.acop.CreateAccount(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("Operation error: %v", err)
hand.SendError(rctx, err)
@@ -54,7 +54,7 @@ func (hand *Handler) CreateAccount(rctx *router.Context) {
func (hand *Handler) GetAccount(rctx *router.Context) {
var err error
params := &operator.GetAccountParams{}
params := &accoper.GetAccountParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -74,7 +74,7 @@ func (hand *Handler) GetAccount(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.GetAccount(rctx.Ctx, operatorID, params)
res, err := hand.acop.GetAccount(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("Operation error: %v", err)
hand.SendError(rctx, err)
@@ -87,7 +87,7 @@ func (hand *Handler) GetAccount(rctx *router.Context) {
func (hand *Handler) ListAccounts(rctx *router.Context) {
var err error
params := &operator.ListAccountsParams{}
params := &accoper.ListAccountsParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -107,7 +107,7 @@ func (hand *Handler) ListAccounts(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.ListAccounts(rctx.Ctx, params)
res, err := hand.acop.ListAccounts(rctx.Ctx, params)
if err != nil {
hand.logg.Errorf("ListAccounts error: %v", err)
hand.SendError(rctx, err)
@@ -120,7 +120,7 @@ func (hand *Handler) ListAccounts(rctx *router.Context) {
func (hand *Handler) UpdateAccount(rctx *router.Context) {
var err error
params := &operator.UpdateAccountParams{}
params := &accoper.UpdateAccountParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -140,7 +140,7 @@ func (hand *Handler) UpdateAccount(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.UpdateAccount(rctx.Ctx, operatorID, params)
res, err := hand.acop.UpdateAccount(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("UpdateAccount error: %v", err)
hand.SendError(rctx, err)
@@ -153,7 +153,7 @@ func (hand *Handler) UpdateAccount(rctx *router.Context) {
func (hand *Handler) DeleteAccount(rctx *router.Context) {
var err error
params := &operator.DeleteAccountParams{}
params := &accoper.DeleteAccountParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -173,7 +173,7 @@ func (hand *Handler) DeleteAccount(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.DeleteAccount(rctx.Ctx, operatorID, params)
res, err := hand.acop.DeleteAccount(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("DeleteAccount error: %v", err)
hand.SendError(rctx, err)
+13 -15
View File
@@ -14,7 +14,7 @@ import (
"io"
"net/http"
"mstore/app/operator"
"mstore/app/imageoper"
"mstore/app/router"
"mstore/pkg/terms"
)
@@ -26,7 +26,7 @@ func (hand *Handler) BlobExists(rctx *router.Context) {
//hand.DumpHeaders("BlobExists", rctx)
params := &operator.BlobExistsParams{
params := &imageoper.BlobExistsParams{
Name: name,
Digest: digest,
}
@@ -43,7 +43,7 @@ func (hand *Handler) BlobExists(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.BlobExists(ctx, operatorID, params)
res, code, err := hand.imop.BlobExists(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("BlobExist error: %v", err)
}
@@ -75,7 +75,7 @@ func (hand *Handler) PostUpload(rctx *router.Context) {
mount := rctx.GetQuery("mount")
from := rctx.GetQuery("from")
params := &operator.PostUploadParams{
params := &imageoper.PostUploadParams{
Name: name,
Digest: digest,
Mount: mount,
@@ -93,7 +93,7 @@ func (hand *Handler) PostUpload(rctx *router.Context) {
return
}
// Execution of the operation
res, code, err := hand.oper.PostUpload(rctx.Ctx, operatorID, params)
res, code, err := hand.imop.PostUpload(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("PostUpload error: %v", err)
} else {
@@ -104,8 +104,6 @@ func (hand *Handler) PostUpload(rctx *router.Context) {
rctx.SetStatus(code)
}
// PATCH /v2/<name>/blobs/uploads/<reference> 202 404/416
func (hand *Handler) PatchUpload(rctx *router.Context) {
@@ -117,7 +115,7 @@ func (hand *Handler) PatchUpload(rctx *router.Context) {
reference, _ := rctx.GetSubpath("reference")
reader := rctx.Request.Body
params := &operator.PatchUploadParams{
params := &imageoper.PatchUploadParams{
ContentLength: contentLength,
ContentType: contentType,
ContentRange: contentRange,
@@ -138,7 +136,7 @@ func (hand *Handler) PatchUpload(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.PatchUpload(ctx, operatorID, params)
res, code, err := hand.imop.PatchUpload(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("PatchUpload error: %v", err)
}
@@ -162,7 +160,7 @@ func (hand *Handler) PutUpload(rctx *router.Context) {
digest := rctx.GetQuery("digest")
reader := rctx.Request.Body
params := &operator.PutUploadParams{
params := &imageoper.PutUploadParams{
ContentLength: contentLength,
ContentType: contentType,
ContentRange: contentRange,
@@ -183,7 +181,7 @@ func (hand *Handler) PutUpload(rctx *router.Context) {
return
}
// Execution of the operation
res, code, err := hand.oper.PutUpload(rctx.Ctx, operatorID, params)
res, code, err := hand.imop.PutUpload(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("PutUpload error: %v", err)
}
@@ -197,7 +195,7 @@ func (hand *Handler) GetBlob(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
digest, _ := rctx.GetSubpath("digest")
params := &operator.GetBlobParams{
params := &imageoper.GetBlobParams{
Name: name,
Digest: digest,
}
@@ -214,7 +212,7 @@ func (hand *Handler) GetBlob(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.GetBlob(ctx, operatorID, params)
res, code, err := hand.imop.GetBlob(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("GetBlob error: %v", err)
}
@@ -243,7 +241,7 @@ func (hand *Handler) DeleteBlob(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
digest, _ := rctx.GetSubpath("digest")
params := &operator.DeleteBlobParams{
params := &imageoper.DeleteBlobParams{
Name: name,
Digest: digest,
}
@@ -260,7 +258,7 @@ func (hand *Handler) DeleteBlob(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
_, code, err := hand.oper.DeleteBlob(ctx, operatorID, params)
_, code, err := hand.imop.DeleteBlob(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("DeleteBlob error: %v", err)
}
+15 -15
View File
@@ -13,7 +13,7 @@ import (
"io"
"net/http"
"mstore/app/operator"
"mstore/app/fileoper"
"mstore/app/router"
"mstore/pkg/terms"
)
@@ -23,7 +23,7 @@ const zeroContentLength = "0"
func (hand *Handler) FileInfo(rctx *router.Context) {
filepath, _ := rctx.GetSubpath("filepath")
params := &operator.FileInfoParams{
params := &fileoper.FileInfoParams{
Filepath: filepath,
}
// Rigth checking
@@ -39,7 +39,7 @@ func (hand *Handler) FileInfo(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
code, res, err := hand.oper.FileInfo(ctx, operatorID, params)
code, res, err := hand.fiop.FileInfo(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("FileInfo error: %v", err)
rctx.SetStatus(code)
@@ -65,7 +65,7 @@ func (hand *Handler) PutFile(rctx *router.Context) {
contentType := rctx.GetHeader("Content-Type")
filepath, _ := rctx.GetSubpath("filepath")
params := &operator.PutFileParams{
params := &fileoper.PutFileParams{
Filepath: filepath,
ContentType: contentType,
ContentSize: contentSize,
@@ -84,7 +84,7 @@ func (hand *Handler) PutFile(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
code, _, err := hand.oper.PutFile(ctx, operatorID, params)
code, _, err := hand.fiop.PutFile(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("PutFile error: %v", err)
rctx.SetStatus(code)
@@ -96,7 +96,7 @@ func (hand *Handler) PutFile(rctx *router.Context) {
func (hand *Handler) GetFile(rctx *router.Context) {
filepath, _ := rctx.GetSubpath("filepath")
params := &operator.GetFileParams{
params := &fileoper.GetFileParams{
Filepath: filepath,
}
// Rigth checking
@@ -112,7 +112,7 @@ func (hand *Handler) GetFile(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
code, res, err := hand.oper.GetFile(ctx, operatorID, params)
code, res, err := hand.fiop.GetFile(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("PutFile error: %v", err)
rctx.SetStatus(code)
@@ -144,7 +144,7 @@ func (hand *Handler) GetFile(rctx *router.Context) {
func (hand *Handler) DeleteFile(rctx *router.Context) {
filepath, _ := rctx.GetSubpath("filepath")
params := &operator.DeleteFileParams{
params := &fileoper.DeleteFileParams{
Filepath: filepath,
}
// Rigth checking
@@ -160,7 +160,7 @@ func (hand *Handler) DeleteFile(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
code, _, err := hand.oper.DeleteFile(ctx, operatorID, params)
code, _, err := hand.fiop.DeleteFile(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("DeleteFIle error: %v", err)
}
@@ -174,7 +174,7 @@ func (hand *Handler) ListFiles(rctx *router.Context) {
if filepath == "" {
filepath = "/"
}
params := &operator.ListFilesParams{
params := &fileoper.ListFilesParams{
Filepath: filepath,
}
err := rctx.BindQuery(params)
@@ -197,7 +197,7 @@ func (hand *Handler) ListFiles(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
code, res, err := hand.oper.ListFiles(ctx, operatorID, params)
code, res, err := hand.fiop.ListFiles(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("ListFiles error: %v", err)
rctx.SetStatus(code)
@@ -212,7 +212,7 @@ func (hand *Handler) ListCollections(rctx *router.Context) {
if cpath == "" {
cpath = "/"
}
params := &operator.ListCollectionsParams{
params := &fileoper.ListCollectionsParams{
Path: cpath,
}
err := rctx.BindQuery(params)
@@ -234,7 +234,7 @@ func (hand *Handler) ListCollections(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
code, res, err := hand.oper.ListCollections(ctx, operatorID, params)
code, res, err := hand.fiop.ListCollections(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("ListCollections error: %v", err)
rctx.SetStatus(code)
@@ -249,7 +249,7 @@ func (hand *Handler) DeleteCollection(rctx *router.Context) {
if cpath == "" {
cpath = "/"
}
params := &operator.DeleteColletionParams{
params := &fileoper.DeleteColletionParams{
Path: cpath,
}
err := rctx.BindQuery(params)
@@ -272,7 +272,7 @@ func (hand *Handler) DeleteCollection(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
code, res, err := hand.oper.DeleteColletion(ctx, operatorID, params)
code, res, err := hand.fiop.DeleteColletion(ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("DeleteColletion error: %v", err)
rctx.SetStatus(code)
+11 -11
View File
@@ -12,7 +12,7 @@ package handler
import (
"fmt"
"mstore/app/operator"
"mstore/app/accoper"
"mstore/app/router"
"mstore/pkg/terms"
)
@@ -21,7 +21,7 @@ import (
func (hand *Handler) CreateGrant(rctx *router.Context) {
var err error
params := &operator.CreateGrantParams{}
params := &accoper.CreateGrantParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -41,7 +41,7 @@ func (hand *Handler) CreateGrant(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.CreateGrant(rctx.Ctx, operatorID, params)
res, err := hand.acop.CreateGrant(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("CreateGrant error: %v", err)
hand.SendError(rctx, err)
@@ -54,7 +54,7 @@ func (hand *Handler) CreateGrant(rctx *router.Context) {
func (hand *Handler) GetGrant(rctx *router.Context) {
var err error
params := &operator.GetGrantParams{}
params := &accoper.GetGrantParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -74,7 +74,7 @@ func (hand *Handler) GetGrant(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.GetGrant(rctx.Ctx, operatorID, params)
res, err := hand.acop.GetGrant(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("CreateGrant error: %v", err)
hand.SendError(rctx, err)
@@ -87,7 +87,7 @@ func (hand *Handler) GetGrant(rctx *router.Context) {
func (hand *Handler) ListGrants(rctx *router.Context) {
var err error
params := &operator.ListGrantsParams{}
params := &accoper.ListGrantsParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -107,7 +107,7 @@ func (hand *Handler) ListGrants(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.ListGrants(rctx.Ctx, operatorID, params)
res, err := hand.acop.ListGrants(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("ListGrants error: %v", err)
hand.SendError(rctx, err)
@@ -120,7 +120,7 @@ func (hand *Handler) ListGrants(rctx *router.Context) {
func (hand *Handler) UpdateGrant(rctx *router.Context) {
var err error
params := &operator.UpdateGrantParams{}
params := &accoper.UpdateGrantParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -140,7 +140,7 @@ func (hand *Handler) UpdateGrant(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.UpdateGrant(rctx.Ctx, operatorID, params)
res, err := hand.acop.UpdateGrant(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("UpdateGrant error: %v", err)
hand.SendError(rctx, err)
@@ -153,7 +153,7 @@ func (hand *Handler) UpdateGrant(rctx *router.Context) {
func (hand *Handler) DeleteGrant(rctx *router.Context) {
var err error
params := &operator.DeleteGrantParams{}
params := &accoper.DeleteGrantParams{}
err = rctx.BindJSON(params)
if err != nil {
hand.SendError(rctx, err)
@@ -173,7 +173,7 @@ func (hand *Handler) DeleteGrant(rctx *router.Context) {
return
}
// Execution of the operation
res, err := hand.oper.DeleteGrant(rctx.Ctx, operatorID, params)
res, err := hand.acop.DeleteGrant(rctx.Ctx, operatorID, params)
if err != nil {
hand.logg.Errorf("DeleteGrant error: %v", err)
hand.SendError(rctx, err)
+14 -4
View File
@@ -12,28 +12,38 @@ package handler
import (
"mstore/app/logger"
"mstore/app/maindb"
"mstore/app/operator"
"mstore/app/router"
"mstore/app/accoper"
"mstore/app/fileoper"
"mstore/app/imageoper"
yaml "go.yaml.in/yaml/v4"
)
type HandlerParams struct {
Operator *operator.Operator
MainDB *maindb.Database
FileOper *fileoper.Operator
AccOper *accoper.Operator
ImageOper *imageoper.Operator
}
type Handler struct {
oper *operator.Operator
mdb *maindb.Database
logg *logger.Logger
fiop *fileoper.Operator
acop *accoper.Operator
imop *imageoper.Operator
}
func NewHandler(params *HandlerParams) (*Handler, error) {
var err error
hand := &Handler{
oper: params.Operator,
mdb: params.MainDB,
fiop: params.FileOper,
acop: params.AccOper,
imop: params.ImageOper,
}
hand.logg = logger.NewLoggerWithSubject("handler")
return hand, err
+15 -15
View File
@@ -12,7 +12,7 @@ package handler
import (
"net/http"
"mstore/app/operator"
"mstore/app/imageoper"
"mstore/app/router"
"mstore/pkg/terms"
)
@@ -23,7 +23,7 @@ func (hand *Handler) ManifestExists(rctx *router.Context) {
//hand.DumpHeaders("ManigestExists:\n", rctx)
params := &operator.ManifestExistsParams{
params := &imageoper.ManifestExistsParams{
Name: name,
Reference: reference,
}
@@ -40,7 +40,7 @@ func (hand *Handler) ManifestExists(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.ManifestExists(ctx, params)
res, code, err := hand.imop.ManifestExists(ctx, params)
if err != nil {
hand.logg.Errorf("ManifestExist error: %v", err)
} else if code == http.StatusOK {
@@ -62,7 +62,7 @@ func (hand *Handler) PutManifest(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
params := &operator.PutManifestParams{
params := &imageoper.PutManifestParams{
ContentType: contentType,
ContentLength: contentLength,
Name: name,
@@ -82,7 +82,7 @@ func (hand *Handler) PutManifest(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.PutManifest(ctx, params)
res, code, err := hand.imop.PutManifest(ctx, params)
if err != nil {
hand.logg.Errorf("PutManifest error: %v", err)
} else {
@@ -98,7 +98,7 @@ func (hand *Handler) GetManifest(rctx *router.Context) {
//hand.DumpHeaders("GetManigest", rctx)
params := &operator.GetManifestParams{
params := &imageoper.GetManifestParams{
Name: name,
Reference: reference,
}
@@ -115,7 +115,7 @@ func (hand *Handler) GetManifest(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.GetManifest(ctx, params)
res, code, err := hand.imop.GetManifest(ctx, params)
if err != nil {
hand.logg.Errorf("GetManifest error: %v", err)
rctx.SetStatus(code)
@@ -138,7 +138,7 @@ func (hand *Handler) DeleteManifest(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
params := &operator.DeleteManifestParams{
params := &imageoper.DeleteManifestParams{
Name: name,
Reference: reference,
}
@@ -155,7 +155,7 @@ func (hand *Handler) DeleteManifest(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
_, code, err := hand.oper.DeleteManifest(ctx, params)
_, code, err := hand.imop.DeleteManifest(ctx, params)
if err != nil {
hand.logg.Errorf("DeleteManifest error: %v", err)
}
@@ -167,7 +167,7 @@ func (hand *Handler) DeleteManifest(rctx *router.Context) {
func (hand *Handler) GetReferer(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
digest, _ := rctx.GetSubpath("digest")
params := &operator.GetRefererParams{
params := &imageoper.GetRefererParams{
Name: name,
Digest: digest,
}
@@ -183,7 +183,7 @@ func (hand *Handler) GetReferer(rctx *router.Context) {
return
}
// Execution of the operation
res, code, err := hand.oper.GetReferer(rctx.Ctx, params)
res, code, err := hand.imop.GetReferer(rctx.Ctx, params)
if err != nil {
hand.logg.Errorf("GetReferer error: %v", err)
}
@@ -194,7 +194,7 @@ func (hand *Handler) GetReferer(rctx *router.Context) {
// GET /v2/<name>/tags/list?n=<integer>&last=<integer>
func (hand *Handler) GetTags(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
params := &operator.GetTagsParams{
params := &imageoper.GetTagsParams{
Name: name,
}
// Rigth checking
@@ -210,7 +210,7 @@ func (hand *Handler) GetTags(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.GetTags(ctx, params)
res, code, err := hand.imop.GetTags(ctx, params)
if err != nil {
hand.logg.Errorf("GetTags error: %v", err)
}
@@ -219,7 +219,7 @@ func (hand *Handler) GetTags(rctx *router.Context) {
// GET /v2/_catalog?n=1000 200 404
func (hand *Handler) ListManifests(rctx *router.Context) {
params := &operator.ListManifestsParams{}
params := &imageoper.ListManifestsParams{}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, "_catalog")
@@ -233,7 +233,7 @@ func (hand *Handler) ListManifests(rctx *router.Context) {
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.oper.ListManifests(ctx, params)
res, code, err := hand.imop.ListManifests(ctx, params)
if err != nil {
hand.logg.Errorf("ListManifests error: %v", err)
}
+3 -3
View File
@@ -10,12 +10,12 @@
package handler
import (
"mstore/app/operator"
"mstore/app/imageoper"
"mstore/app/router"
)
func (hand *Handler) SendHello(rctx *router.Context) {
params := &operator.SendHelloParams{}
res, _ := hand.oper.SendHello(params)
params := &imageoper.SendHelloParams{}
res, _ := hand.imop.SendHello(params)
hand.SendResult(rctx, res)
}
+3 -3
View File
@@ -12,13 +12,13 @@ package handler
import (
"net/http"
"mstore/app/operator"
"mstore/app/imageoper"
"mstore/app/router"
)
// GET /v2/ 200 404/401
func (hand *Handler) GetVersion(rctx *router.Context) {
params := &operator.GetVersionParams{}
params := &imageoper.GetVersionParams{}
//hand.DumpHeaders("GetVersion", rctx)
authorization := rctx.GetHeader("Authorization")
@@ -28,7 +28,7 @@ func (hand *Handler) GetVersion(rctx *router.Context) {
return
}
ctx := rctx.GetContext()
_, code, err := hand.oper.GetVersion(ctx, params)
_, code, err := hand.imop.GetVersion(ctx, params)
if err != nil {
hand.logg.Errorf("GetVersion error: %v", err)
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package imageoper
import (
"context"
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package imageoper
import (
"encoding/hex"
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package imageoper
import (
"bytes"
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package imageoper
import (
"encoding/json"
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package imageoper
import (
"mstore/app/locker"
"mstore/app/logger"
"mstore/app/maindb"
"mstore/app/storage"
)
type OperatorParams struct {
MainDB *maindb.Database
Store *storage.Storage
}
type Operator struct {
mdb *maindb.Database
store *storage.Storage
logg *logger.Logger
iLock *locker.Locker
fLock *locker.Locker
}
func NewOperator(params *OperatorParams) (*Operator, error) {
var err error
oper := &Operator{
mdb: params.MainDB,
store: params.Store,
}
oper.iLock = locker.NewLocker()
oper.fLock = locker.NewLocker()
oper.logg = logger.NewLoggerWithSubject("imageoper")
return oper, err
}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package imageoper
type SendHelloParams struct{}
@@ -7,7 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package operator
package imageoper
import (
"context"
-284
View File
@@ -1,284 +0,0 @@
package operator
import (
"context"
"fmt"
"mstore/pkg/auxpwd"
"mstore/pkg/auxtool"
"mstore/pkg/auxuuid"
"mstore/pkg/descr"
)
type CreateAccountParams struct {
Username string `json:"username"`
Password string `json:"password"`
}
type CreateAccountResult struct {
AccountID string `json:"accountId"`
}
func (oper *Operator) CreateAccount(ctx context.Context, operatorID string, params *CreateAccountParams) (*CreateAccountResult, error) {
var err error
res := &CreateAccountResult{}
if params.Username == "" {
err := fmt.Errorf("Empty username parameters")
return res, err
}
if params.Password == "" {
err := fmt.Errorf("Empty password parameter")
return res, err
}
accountExists, _, err := oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if accountExists {
err := fmt.Errorf("Account with thist name already exists")
return res, err
}
now := auxtool.TimeNow()
passhash := auxpwd.MakeSHA256Hash([]byte(params.Password))
accountDescr := &descr.Account{
ID: auxuuid.NewUUID(),
Username: params.Username,
Passhash: passhash,
Disabled: false,
CreatedAt: now,
UpdatedAt: now,
CreatedBy: operatorID,
UpdatedBy: operatorID,
}
err = oper.mdb.InsertAccount(ctx, accountDescr)
if err != nil {
return res, err
}
res.AccountID = accountDescr.ID
return res, err
}
// GetAccount
type GetAccountParams struct {
Username string `json:"username"`
AccountID string `json:"accountId"`
}
type GetAccountResult struct {
Account *descr.AccountShort `json:"account"`
}
func (oper *Operator) GetAccount(ctx context.Context, operatorID string, params *GetAccountParams) (*GetAccountResult, error) {
var err error
res := &GetAccountResult{}
if params.Username == "" && params.AccountID == "" {
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
if accountDescr == nil {
err := fmt.Errorf("Null account desriptor")
return res, err
}
accountShort := &descr.AccountShort{
ID: accountDescr.ID,
Username: accountDescr.Username,
CreatedAt: accountDescr.CreatedAt,
UpdatedAt: accountDescr.UpdatedAt,
CreatedBy: accountDescr.CreatedBy,
UpdatedBy: accountDescr.UpdatedBy,
Disabled: accountDescr.Disabled,
Grants: make([]descr.Grant, 0),
}
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
accountShort.Grants = grantDescrs
res.Account = accountShort
return res, err
}
type UpdateAccountParams struct {
Username string `json:"username"`
AccountID string `json:"accountId"`
NewUsername string `json:"newUsername"`
NewPassword string `json:"newPassword"`
Disabled bool `json:"disabled"`
}
type UpdateAccountResult struct{}
func (oper *Operator) UpdateAccount(ctx context.Context, operatorID string, params *UpdateAccountParams) (*UpdateAccountResult, error) {
var err error
res := &UpdateAccountResult{}
if params.Username == "" && params.AccountID == "" {
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
if accountDescr == nil {
err := fmt.Errorf("Null account desriptor")
return res, err
}
now := auxtool.TimeNow()
if params.NewUsername != "" {
accountDescr.UpdatedAt = now
accountDescr.Username = params.NewUsername
}
if params.NewPassword != "" {
accountDescr.UpdatedAt = now
passhash := auxpwd.MakeSHA256Hash([]byte(params.NewPassword))
accountDescr.Passhash = passhash
}
if params.Disabled != accountDescr.Disabled {
accountDescr.UpdatedAt = now
accountDescr.Disabled = params.Disabled
}
err = oper.mdb.UpdateAccountByID(ctx, accountDescr.ID, accountDescr)
if err != nil {
return res, err
}
return res, err
}
type DeleteAccountParams struct {
Username string `json:"username"`
AccountID string `json:"accountId"`
}
type DeleteAccountResult struct{}
func (oper *Operator) DeleteAccount(ctx context.Context, operatorID string, params *DeleteAccountParams) (*DeleteAccountResult, error) {
var err error
res := &DeleteAccountResult{}
if params.Username == "" && params.AccountID == "" {
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
if accountDescr == nil {
err := fmt.Errorf("Null account desriptor")
return res, err
}
err = oper.mdb.DeleteAllGrantsForAccountID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
err = oper.mdb.DeleteAccountByID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
return res, err
}
type ListAccountsParams struct{}
type ListAccountsResult struct {
Accounts []descr.AccountShort `json:"accounts"`
}
func (oper *Operator) ListAccounts(ctx context.Context, params *ListAccountsParams) (*ListAccountsResult, error) {
var err error
res := &ListAccountsResult{}
accountDescrs, err := oper.mdb.ReducedListAccounts(ctx)
if err != nil {
return res, err
}
for _, accountDescr := range accountDescrs {
accountShort := descr.AccountShort{
ID: accountDescr.ID,
Username: accountDescr.Username,
Disabled: accountDescr.Disabled,
CreatedAt: accountDescr.CreatedAt,
UpdatedAt: accountDescr.UpdatedAt,
CreatedBy: accountDescr.CreatedBy,
UpdatedBy: accountDescr.UpdatedBy,
Grants: make([]descr.Grant, 0),
}
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountDescr.ID)
if err != nil {
return res, err
}
accountShort.Grants = grantDescrs
res.Accounts = append(res.Accounts, accountShort)
}
return res, err
}
-254
View File
@@ -1,254 +0,0 @@
package operator
import (
"context"
"fmt"
"regexp"
"mstore/pkg/auxtool"
"mstore/pkg/auxuuid"
"mstore/pkg/descr"
)
// CreateGrant
type CreateGrantParams struct {
AccountID string `json:"accountID"`
Username string `json:"username"`
Right string `json:"operation"`
Pattern string `json:"pattern"`
}
type CreateGrantResult struct {
GrantID string `json:"grantId"`
}
func (oper *Operator) CreateGrant(ctx context.Context, operatorID string, params *CreateGrantParams) (*CreateGrantResult, error) {
var err error
res := &CreateGrantResult{}
if params.AccountID == "" {
err := fmt.Errorf("Empty accountId parameters")
return res, err
}
if params.Right == "" {
err := fmt.Errorf("Empty operation parameter")
return res, err
}
if params.Pattern == "" {
err := fmt.Errorf("Empty pattern parameter")
return res, err
}
_, err = regexp.Compile(params.Pattern)
if err != nil {
err := fmt.Errorf("Cannot compile regexp %s: %v", err)
return res, err
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
grantExists, _, err := oper.mdb.GetGrantByAccoundIDRightPattern(ctx, params.AccountID, params.Right, params.Pattern)
if err != nil {
return res, err
}
if grantExists {
err := fmt.Errorf("Grant with this right already exists")
return res, err
}
oper.logg.Debugf("Call CreateGrant")
now := auxtool.TimeNow()
grantDescr := &descr.Grant{
ID: auxuuid.NewUUID(),
AccountID: accountDescr.ID,
Right: params.Right,
Pattern: params.Pattern,
CreatedAt: now,
UpdatedAt: now,
CreatedBy: operatorID,
UpdatedBy: operatorID,
}
err = oper.mdb.InsertGrant(ctx, grantDescr)
if err != nil {
return res, err
}
res.GrantID = grantDescr.ID
return res, err
}
// UpdateGrant
type UpdateGrantParams struct {
GrantID string
NewPattern string
}
type UpdateGrantResult struct{}
func (oper *Operator) UpdateGrant(ctx context.Context, operatorID string, params *UpdateGrantParams) (*UpdateGrantResult, error) {
var err error
res := &UpdateGrantResult{}
if params.NewPattern == "" {
err := fmt.Errorf("Empty newPattern parameter")
return res, err
}
if params.GrantID == "" {
err := fmt.Errorf("Empty grantId parameter")
return res, err
}
var grantDescr *descr.Grant
var grantExists bool
grantExists, grantDescr, err = oper.mdb.GetGrantByID(ctx, params.GrantID)
if err != nil {
return res, err
}
if !grantExists {
err := fmt.Errorf("Grant with ID %s dont exists", params.GrantID)
return res, err
}
now := auxtool.TimeNow()
if params.NewPattern != "" {
grantDescr.UpdatedAt = now
grantDescr.UpdatedBy = operatorID
grantDescr.Pattern = params.NewPattern
}
err = oper.mdb.UpdateGrantByID(ctx, grantDescr.ID, grantDescr)
if err != nil {
return res, err
}
return res, err
}
// DeleteGrant
type DeleteGrantParams struct {
GrantID string `json:"grantId"`
}
type DeleteGrantResult struct{}
func (oper *Operator) DeleteGrant(ctx context.Context, operatorID string, params *DeleteGrantParams) (*DeleteGrantResult, error) {
var err error
res := &DeleteGrantResult{}
if params.GrantID == "" {
err := fmt.Errorf("Empty grantId parameter")
return res, err
}
var grantDescr *descr.Grant
var grantExists bool
grantExists, grantDescr, err = oper.mdb.GetGrantByID(ctx, params.GrantID)
if err != nil {
return res, err
}
if !grantExists {
err := fmt.Errorf("Grant with ID %s dont exists", params.GrantID)
return res, err
}
err = oper.mdb.DeleteGrantByID(ctx, grantDescr.ID)
if err != nil {
return res, err
}
return res, err
}
// ListGrants
type ListGrantsParams struct {
Username string
AccountID string
}
type ListGrantsResult struct {
Grants []descr.Grant `json:"grants"`
}
func (oper *Operator) ListGrants(ctx context.Context, operatorID string, params *ListGrantsParams) (*ListGrantsResult, error) {
var err error
res := &ListGrantsResult{
Grants: make([]descr.Grant, 0),
}
var accountDescr *descr.Account
var accountExists bool
switch {
case params.AccountID != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
return res, err
}
case params.Username != "":
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
if err != nil {
return res, err
}
if !accountExists {
err := fmt.Errorf("Account with name %s dont exists", params.Username)
return res, err
}
default:
err := fmt.Errorf("Empty username and accountId parameter")
return res, err
}
accountID := accountDescr.ID
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountID)
if err != nil {
return res, err
}
res.Grants = grantDescrs
return res, err
}
// Get Grants
type GetGrantParams struct {
GrantID string `json:"grantId"`
}
type GetGrantResult struct {
Grant *descr.Grant `json:"grant"`
}
func (oper *Operator) GetGrant(ctx context.Context, operatorID string, params *GetGrantParams) (*GetGrantResult, error) {
var err error
res := &GetGrantResult{}
if params.GrantID == "" {
err := fmt.Errorf("Empty grantId parameter")
return res, err
}
var grantDescr *descr.Grant
var grantExists bool
grantExists, grantDescr, err = oper.mdb.GetGrantByID(ctx, params.GrantID)
if err != nil {
return res, err
}
if !grantExists {
err := fmt.Errorf("Grant with ID %s dont exists", params.GrantID)
return res, err
}
res.Grant = grantDescr
return res, err
}
+35 -7
View File
@@ -25,18 +25,23 @@ import (
"mstore/app/handler"
"mstore/app/logger"
"mstore/app/maindb"
"mstore/app/operator"
"mstore/app/service"
"mstore/app/storage"
"mstore/pkg/auxtool"
"mstore/pkg/descr"
"mstore/app/accoper"
"mstore/app/fileoper"
"mstore/app/imageoper"
yaml "go.yaml.in/yaml/v4"
)
type Server struct {
conf *config.Config
oper *operator.Operator
fiop *fileoper.Operator
acop *accoper.Operator
imop *imageoper.Operator
svc *service.Service
mdb *maindb.Database
hand *handler.Handler
@@ -248,21 +253,44 @@ func (srv *Server) Build() error {
store := storage.NewStorage(datadir)
srv.stor = store
// Creating operator
srv.logg.Infof("Creating operator")
operatorParams := &operator.OperatorParams{
// Creating account operator
srv.logg.Infof("Creating account operator")
accoperParams := &accoper.OperatorParams{
MainDB: srv.mdb,
Store: srv.stor,
}
srv.oper, err = operator.NewOperator(operatorParams)
srv.acop, err = accoper.NewOperator(accoperParams)
if err != nil {
return err
}
// Creating file operator
srv.logg.Infof("Creating file operator")
fileoperParams := &fileoper.OperatorParams{
MainDB: srv.mdb,
Store: srv.stor,
}
srv.fiop, err = fileoper.NewOperator(fileoperParams)
if err != nil {
return err
}
// Creating operator
srv.logg.Infof("Creating operator")
imageoperParams := &imageoper.OperatorParams{
MainDB: srv.mdb,
Store: srv.stor,
}
srv.imop, err = imageoper.NewOperator(imageoperParams)
if err != nil {
return err
}
// Creating handler
srv.logg.Infof("Creating handler")
handlerParams := &handler.HandlerParams{
Operator: srv.oper,
MainDB: srv.mdb,
FileOper: srv.fiop,
AccOper: srv.acop,
ImageOper: srv.imop,
}
srv.hand, err = handler.NewHandler(handlerParams)
if err != nil {
+1 -1
View File
@@ -12,8 +12,8 @@ package filecmd
import (
"context"
"encoding/json"
"time"
"fmt"
"time"
"github.com/spf13/cobra"
-1
View File
@@ -26,7 +26,6 @@ import (
const (
indexMediaType = "application/vnd.oci.image.index.v1+json"
manifestMediaType = "application/vnd.oci.image.manifest.v1+json"
)
func (cli *Client) ImageManifest(ctx context.Context, imagepath string) (any, error) {
-5
View File
@@ -26,8 +26,6 @@ type File struct {
UpdatedBy string `db:"updated_by" json:"updatedBy,omitempty" yaml:"updatedBy,omitempty"`
}
type Files struct {
files []File
}
@@ -56,8 +54,6 @@ func (fi *Files) Array() []File {
return fi.files
}
func (fi *Files) List() []string {
list := make([]string, 0)
for _, file := range fi.files {
@@ -65,4 +61,3 @@ func (fi *Files) List() []string {
}
return list
}
-2
View File
@@ -38,7 +38,6 @@ func (cli *Client) UseMiddleware(mwFunc MiddlewareFunc) {
cli.httpClient.Transport = mwFunc(cli.httpClient.Transport)
}
// BasicAuthMiddleware
func NewBasicAuthMiddleware(user, pass string) MiddlewareFunc {
return func(next http.RoundTripper) http.RoundTripper {
@@ -110,7 +109,6 @@ func (wrap *DefaultTransport) RoundTrip(req *http.Request) (*http.Response, erro
return wrap.transport.RoundTrip(req)
}
// ExampleMiddleware
func NewExampleMiddleware() MiddlewareFunc {
return func(next http.RoundTripper) http.RoundTripper {
+1 -1
View File
@@ -3,8 +3,8 @@ package filecli
import (
"net/url"
"path"
"strings"
"strconv"
"strings"
)
const (
+1 -1
View File
@@ -15,10 +15,10 @@ import (
//"math/rand"
//"os"
//"path/filepath"
"bytes"
"sync"
"testing"
"time"
"bytes"
"mstore/app/server"
"mstore/pkg/client"