splitted one operator module to file, account, image operators; splitted operator functions; etc
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -100,7 +99,7 @@ func (oper *Operator) deleteFilesInCollection(ctx context.Context, collection st
|
||||
}
|
||||
for _, file := range files {
|
||||
if !dryRun {
|
||||
oper.logg.Debugf("Delete file %s/%s", file.Collection, file.Name)
|
||||
oper.logg.Debugf("Delete file %s/%s", file.Collection, file.Name)
|
||||
err = oper.store.DeleteFile(file.Collection, file.Name)
|
||||
if err != nil {
|
||||
oper.logg.Warningf("%v", err)
|
||||
@@ -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"
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -52,9 +52,9 @@ func (hand *Handler) CheckAccess(rctx *router.Context) (bool, string, error) {
|
||||
|
||||
accountID = terms.AnonymousID
|
||||
|
||||
hand.logg.Debugf("URL: %s", rctx.URL().String())
|
||||
hand.logg.Debugf("URL: %s", rctx.URL().String())
|
||||
authHeader := rctx.GetHeader("Authorization")
|
||||
hand.logg.Debugf("Authorization: %s", authHeader)
|
||||
hand.logg.Debugf("Authorization: %s", authHeader)
|
||||
if authHeader != "" {
|
||||
username, password, err = auxhttp.ParseBasicAuth(authHeader)
|
||||
if err != nil {
|
||||
|
||||
+11
-11
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
+15
-5
@@ -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
|
||||
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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
+36
-8
@@ -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,
|
||||
MainDB: srv.mdb,
|
||||
FileOper: srv.fiop,
|
||||
AccOper: srv.acop,
|
||||
ImageOper: srv.imop,
|
||||
}
|
||||
srv.hand, err = handler.NewHandler(handlerParams)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user