working commit

This commit is contained in:
2026-02-07 14:10:54 +02:00
parent 90905ace89
commit cd274d614a
12 changed files with 124 additions and 276 deletions
+33 -10
View File
@@ -1,3 +1,13 @@
/*
* 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 descr
const (
@@ -8,17 +18,30 @@ const (
)
type Account struct {
ID int64 `json:"id" yaml:"id" db:"id"`
Username string `json:"username" yaml:"username" db:"username"`
Passhash string `json:"passhash" yaml:"passhash" db:"passhash"`
Disabled bool `json:"disabled" yaml:"disabled" db:"disabled"`
CreatedAt string `json:"createdAt" yaml:"createdAt" db:"created_at"`
UpdatedAt string `json:"updatedAt,omitempty" yaml:"updatedAt,omitempty" db:"updated_at"`
ID string `json:"id" db:"id"`
Username string `json:"username" db:"username"`
Passhash string `json:"passhash" db:"passhash"`
Disabled bool `json:"disabled" db:"disabled"`
CreatedAt string `json:"createdAt" db:"created_at"`
UpdatedAt string `json:"updatedAt,omitempty" db:"updated_at"`
}
type Grant struct {
ID int64 `json:"id" yaml:"id" db:"id"`
AccountID int64 `json:"accountID" yaml:"accountID" db:"account_id"`
Operation string `json:"operation" yaml:"operation" db:"operation"`
CreatedAt string `json:"createdAt" yaml:"createdAt" db:"created_at"`
ID string `json:"id" db:"id"`
AccountID string `json:"accountID" db:"account_id"`
Operation string `json:"operation" db:"operation"`
CreatedAt string `json:"createdAt" db:"created_at"`
}
type GrantShortDescr struct {
Operation string `json:"operation"`
CreatedAt string `json:"createdAt"`
}
type AccountShortDescr struct {
Username string `json:"username"`
Disabled bool `json:"disabled"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt,omitempty"`
Grants []GrantShortDescr `json:"grants"`
}
+8 -8
View File
@@ -36,14 +36,14 @@ func (hand *Handler) CheckAccess(rctx *router.Context) (bool, error) {
var res bool
authHeader := rctx.GetHeader("Authorization")
if authHeader != "" {
hand.logg.Debugf("Authorization header is %s", authHeader)
username, password, err := auxhttp.ParseBasicAuth(authHeader)
if err != nil {
return res, err
}
hand.logg.Debugf("Authorization username is %s:%s", username, password)
}
if authHeader != "" {
hand.logg.Debugf("Authorization header is %s", authHeader)
username, password, err := auxhttp.ParseBasicAuth(authHeader)
if err != nil {
return res, err
}
hand.logg.Debugf("Authorization username is %s:%s", username, password)
}
res = true
+1
View File
@@ -7,6 +7,7 @@
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package handler
import (
+9 -9
View File
@@ -31,24 +31,23 @@ func (hand *Handler) FileExists(rctx *router.Context) {
rctx.SetStatus(code)
return
}
// TODO
rctx.SetHeader("Content-Type", res.ContentType)
rctx.SetHeader("Content-Length", res.ContentLength)
rctx.SetHeader("Content-Size", res.ContentSize)
rctx.SetHeader("Content-Digest", res.ContentDigest)
//rctx.SetHeader("Content-Length", zeroContentLength)
rctx.SetHeader("Content-Length", zeroContentLength)
rctx.SetStatus(code)
}
func (hand *Handler) PutFile(rctx *router.Context) {
contentLength := rctx.GetHeader("Content-Length")
contentSize := rctx.GetHeader("Content-Size")
contentType := rctx.GetHeader("Content-Type")
filepath, _ := rctx.GetSubpath("filepath")
params := &operator.PutFileParams{
Filepath: filepath,
ContentLength: contentLength,
ContentType: contentType,
Source: rctx.Request.Body,
Filepath: filepath,
ContentType: contentType,
ContentSize: contentSize,
Source: rctx.Request.Body,
}
ctx := rctx.GetContext()
@@ -76,8 +75,9 @@ func (hand *Handler) GetFile(rctx *router.Context) {
}
rctx.SetHeader("Content-Type", res.ContentType)
rctx.SetHeader("Content-Length", res.ContentLength)
rctx.SetHeader("Content-Size", res.ContentSize)
rctx.SetHeader("Content-Digest", res.ContentDigest)
rctx.SetHeader("Content-Length", res.ContentSize)
rctx.SetStatus(code)
if res.Source != nil {
+7 -7
View File
@@ -10,7 +10,7 @@
package handler
import (
"net/http"
"net/http"
"mstore/app/operator"
"mstore/app/router"
@@ -21,12 +21,12 @@ func (hand *Handler) GetVersion(rctx *router.Context) {
params := &operator.GetVersionParams{}
hand.DumpHeaders("GetVersion", rctx)
authorization := rctx.GetHeader("Authorization")
if authorization == "" {
rctx.SetHeader("WWW-Authenticate", `Basic realm="mstore"`)
rctx.SetStatus(http.StatusUnauthorized)
return
}
authorization := rctx.GetHeader("Authorization")
if authorization == "" {
rctx.SetHeader("WWW-Authenticate", `Basic realm="mstore"`)
rctx.SetStatus(http.StatusUnauthorized)
return
}
ctx := rctx.GetContext()
_, code, err := hand.oper.GetVersion(ctx, params)
if err != nil {
+3 -3
View File
@@ -19,7 +19,7 @@ func (db *Database) InsertAccount(ctx context.Context, account *descr.Account) e
return err
}
func (db *Database) UpdateAccountByID(ctx context.Context, accountID int64, account *descr.Account) error {
func (db *Database) UpdateAccountByID(ctx context.Context, accountID string, account *descr.Account) error {
var err error
request := `UPDATE accounts SET username = $1, passhash = $2, disabled = $3, updated_at = $4 WHERE id = $6`
@@ -52,7 +52,7 @@ func (db *Database) CompletedListAccounts(ctx context.Context) ([]descr.Account,
return res, err
}
func (db *Database) GetAccountByID(ctx context.Context, accountID int64) (bool, *descr.Account, error) {
func (db *Database) GetAccountByID(ctx context.Context, accountID string) (bool, *descr.Account, error) {
var err error
var res *descr.Account
var exists bool
@@ -90,7 +90,7 @@ func (db *Database) GetAccountByUsername(ctx context.Context, username string) (
return exists, res, err
}
func (db *Database) DeleteAccountByID(ctx context.Context, accountID int64) error {
func (db *Database) DeleteAccountByID(ctx context.Context, accountID string) error {
var err error
request := `DELETE FROM accounts WHERE id = $1`
+4 -4
View File
@@ -17,7 +17,7 @@ func (db *Database) InsertGrant(ctx context.Context, grant *descr.Grant) error {
return err
}
func (db *Database) ListGrantsByAccountID(ctx context.Context, accountID int64) ([]descr.Grant, error) {
func (db *Database) ListGrantsByAccountID(ctx context.Context, accountID string) ([]descr.Grant, error) {
var err error
request := `SELECT * FROM grants WHERE account_id = $1`
res := make([]descr.Grant, 0)
@@ -39,7 +39,7 @@ func (db *Database) ListGrants(ctx context.Context) ([]descr.Grant, error) {
return res, err
}
func (db *Database) GetGrant(ctx context.Context, accountID int64, operation string) (bool, *descr.Grant, error) {
func (db *Database) GetGrant(ctx context.Context, accountID, operation string) (bool, *descr.Grant, error) {
var err error
res := &descr.Grant{}
request := `SELECT * FROM grants WHERE account_id = $1 AND operation = $2 LIMIT 1`
@@ -56,7 +56,7 @@ func (db *Database) GetGrant(ctx context.Context, accountID int64, operation str
return true, res, err
}
func (db *Database) DeleteGrantByAccountID(ctx context.Context, grantID int64, operation string) error {
func (db *Database) DeleteGrantByAccountID(ctx context.Context, grantID, operation string) error {
var err error
request := `DELETE FROM grants WHERE account_id = $1 AND operation = $2`
_, err = db.db.Exec(request, grantID, operation)
@@ -66,7 +66,7 @@ func (db *Database) DeleteGrantByAccountID(ctx context.Context, grantID int64, o
return err
}
func (db *Database) DeleteAllGrantsForAccountID(ctx context.Context, grantID int64) error {
func (db *Database) DeleteAllGrantsForAccountID(ctx context.Context, grantID string) error {
var err error
request := `DELETE FROM grants WHERE account_id = $1`
_, err = db.db.Exec(request, grantID)
+2 -2
View File
@@ -58,7 +58,7 @@ const schema = `
--- DROP TABLE IF EXISTS accounts;
CREATE TABLE IF NOT EXISTS accounts (
id INT NOT NULL,
id TEXT NOT NULL,
username TEXT NOT NULL,
passhash TEXT NOT NULL,
created_at TEXT NOT NULL,
@@ -72,7 +72,7 @@ const schema = `
--- DROP TABLE IF EXISTS grants;
CREATE TABLE IF NOT EXISTS grants (
id INT NOT NULL,
id TEXT NOT NULL,
account_id INT NOT NULL,
operation TEXT NOT NULL,
created_at TEXT NOT NULL
+11 -11
View File
@@ -31,7 +31,7 @@ type FileExistsParams struct {
}
type FileExistsResult struct {
ContentType string
ContentLength string
ContentSize string
ContentDigest string
}
@@ -64,7 +64,7 @@ func (oper *Operator) FileExists(ctx context.Context, param *FileExistsParams) (
return code, res, err
}
res = &FileExistsResult{
ContentLength: strconv.FormatInt(fileDescr.Size, 10),
ContentSize: strconv.FormatInt(fileDescr.Size, 10),
ContentType: fileDescr.Type,
ContentDigest: fileDescr.Checksum,
}
@@ -73,10 +73,10 @@ func (oper *Operator) FileExists(ctx context.Context, param *FileExistsParams) (
// PutFile
type PutFileParams struct {
ContentType string
ContentLength string
Filepath string
Source io.ReadCloser
ContentType string
ContentSize string
Filepath string
Source io.ReadCloser
}
type PutFileResult struct{}
@@ -86,12 +86,12 @@ func (oper *Operator) PutFile(ctx context.Context, param *PutFileParams) (int, *
var err error
res := &PutFileResult{}
if param.ContentLength == "" {
if param.ContentSize == "" {
code := http.StatusLengthRequired
err = fmt.Errorf("Content-Length is empty")
err = fmt.Errorf("Required Content-Size header is empty")
return code, res, err
}
size, err := strconv.ParseInt(param.ContentLength, 10, 64)
size, err := strconv.ParseInt(param.ContentSize, 10, 64)
if err != nil {
code := http.StatusLengthRequired
return code, res, err
@@ -166,7 +166,7 @@ type GetFileParams struct {
}
type GetFileResult struct {
ContentType string
ContentLength string
ContentSize string
ContentDigest string
Source io.ReadCloser
}
@@ -200,7 +200,7 @@ func (oper *Operator) GetFile(ctx context.Context, param *GetFileParams) (int, *
return code, res, err
}
res = &GetFileResult{
ContentLength: strconv.FormatInt(fileDescr.Size, 10),
ContentSize: strconv.FormatInt(fileDescr.Size, 10),
ContentType: fileDescr.Type,
ContentDigest: fileDescr.Checksum,
Source: reader,
+6
View File
@@ -97,6 +97,12 @@ func (svc *Service) Build() error {
svc.rout.Get(`/v2/{name}/tags/list`, svc.hand.GetTags)
svc.rout.Get(`/v2/{name}/referrers/{digest}`, svc.hand.GetReferer)
svc.rout.Post(`/v3/account/create`, svc.hand.CreateAccount)
svc.rout.Post(`/v3/account/get`, svc.hand.GetAccount)
svc.rout.Post(`/v3/accounts/list`, svc.hand.ListAccounts)
svc.rout.Post(`/v3/account/update`, svc.hand.UpdateAccount)
svc.rout.Post(`/v3/account/delete`, svc.hand.DeleteAccount)
svc.rout.NotFound(svc.hand.NotFound)
selector := svc.rout.Selector()