bump reva

Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
jkoberg
2023-04-21 09:09:59 +02:00
parent 84351f78e9
commit a5486c2726
15 changed files with 379 additions and 348 deletions
+1
View File
@@ -12,3 +12,4 @@ https://github.com/owncloud/ocis/pull/5714
https://github.com/owncloud/ocis/pull/5845 https://github.com/owncloud/ocis/pull/5845
https://github.com/owncloud/ocis/pull/5921 https://github.com/owncloud/ocis/pull/5921
https://github.com/owncloud/ocis/pull/5984 https://github.com/owncloud/ocis/pull/5984
https://github.com/owncloud/ocis/pull/6066
+1 -1
View File
@@ -14,7 +14,7 @@ require (
github.com/coreos/go-oidc v2.2.1+incompatible github.com/coreos/go-oidc v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.4.0 github.com/coreos/go-oidc/v3 v3.4.0
github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965 github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965
github.com/cs3org/reva/v2 v2.12.1-0.20230417084429-b3d96f9db80c github.com/cs3org/reva/v2 v2.12.1-0.20230420073005-11edad1f09fe
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/egirna/icap-client v0.1.1 github.com/egirna/icap-client v0.1.1
+2 -4
View File
@@ -627,10 +627,8 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4= github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc= github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc=
github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA= github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA=
github.com/cs3org/reva/v2 v2.12.1-0.20230417084429-b3d96f9db80c h1:H6OjKTaRowZfAU/Hwvv4W0pLFFH/KNbHaNVNw3ANoHU= github.com/cs3org/reva/v2 v2.12.1-0.20230420073005-11edad1f09fe h1:VwL3XmxMC/lYar2xVHQYcrC6L38/DE+qIh2hYg1X3tc=
github.com/cs3org/reva/v2 v2.12.1-0.20230417084429-b3d96f9db80c/go.mod h1:FNAYs5H3xs8v0OFmNgZtiMAzIMXd/6TJmO0uZuNn8pQ= github.com/cs3org/reva/v2 v2.12.1-0.20230420073005-11edad1f09fe/go.mod h1:FNAYs5H3xs8v0OFmNgZtiMAzIMXd/6TJmO0uZuNn8pQ=
github.com/cs3org/reva/v2 v2.12.1-0.20230331184913-eca8953fb6e9 h1:zUMD0UvKVPbR3UaodnA0GXuBycxrIuaO8Kshgi3iKKI=
github.com/cs3org/reva/v2 v2.12.1-0.20230331184913-eca8953fb6e9/go.mod h1:FNAYs5H3xs8v0OFmNgZtiMAzIMXd/6TJmO0uZuNn8pQ=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
+3 -3
View File
@@ -1,4 +1,4 @@
coverage.out coverage.out
/nbproject/private/ /nbproject/private/
/nbproject/ /nbproject/
/coverage.txt /coverage.txt
+1 -1
View File
@@ -32,7 +32,7 @@
.LSOverride .LSOverride
# Icon must end with two \r # Icon must end with two \r
Icon Icon
# Thumbnails # Thumbnails
._* ._*
+9 -8
View File
@@ -173,16 +173,17 @@ func (h *sharesHandler) createShare(w http.ResponseWriter, r *http.Request) {
var role *conversions.Role var role *conversions.Role
pval, ok := options["permissions"].(int) pval, ok := options["permissions"].(int)
if !ok { if !ok {
role = conversions.NewViewerRole() WriteError(w, r, APIErrorInvalidParameter, "permissions not provided", nil)
} else { return
permissions, err = conversions.NewPermissions(pval)
if err != nil {
WriteError(w, r, APIErrorInvalidParameter, err.Error(), nil)
return
}
role = conversions.RoleFromOCSPermissions(permissions)
} }
permissions, err = conversions.NewPermissions(pval)
if err != nil {
WriteError(w, r, APIErrorInvalidParameter, err.Error(), nil)
return
}
role = conversions.RoleFromOCSPermissions(permissions)
val, err := json.Marshal(role.CS3ResourcePermissions()) val, err := json.Marshal(role.CS3ResourcePermissions())
if err != nil { if err != nil {
WriteError(w, r, APIErrorServerError, "could not encode role", nil) WriteError(w, r, APIErrorServerError, "could not encode role", nil)
@@ -133,16 +133,16 @@ func (r *Role) WebDAVPermissions(isDir, isShared, isMountpoint, isPublic bool) s
} }
// RoleFromName creates a role from the name // RoleFromName creates a role from the name
func RoleFromName(name string) *Role { func RoleFromName(name string, sharing bool) *Role {
switch name { switch name {
case RoleDenied: case RoleDenied:
return NewDeniedRole() return NewDeniedRole()
case RoleViewer: case RoleViewer:
return NewViewerRole() return NewViewerRole(sharing)
case RoleSpaceViewer: case RoleSpaceViewer:
return NewSpaceViewerRole() return NewSpaceViewerRole()
case RoleEditor: case RoleEditor:
return NewEditorRole() return NewEditorRole(sharing)
case RoleSpaceEditor: case RoleSpaceEditor:
return NewSpaceEditorRole() return NewSpaceEditorRole()
case RoleFileEditor: case RoleFileEditor:
@@ -174,12 +174,16 @@ func NewDeniedRole() *Role {
} }
} }
// NewViewerRole creates a viewer role // NewViewerRole creates a viewer role. `sharing` indicates if sharing permission should be added
func NewViewerRole() *Role { func NewViewerRole(sharing bool) *Role {
p := PermissionRead
if sharing {
p |= PermissionShare
}
return &Role{ return &Role{
Name: RoleViewer, Name: RoleViewer,
cS3ResourcePermissions: &provider.ResourcePermissions{ cS3ResourcePermissions: &provider.ResourcePermissions{
AddGrant: true, AddGrant: sharing,
GetPath: true, GetPath: true,
GetQuota: true, GetQuota: true,
InitiateFileDownload: true, InitiateFileDownload: true,
@@ -187,7 +191,7 @@ func NewViewerRole() *Role {
ListRecycle: true, ListRecycle: true,
Stat: true, Stat: true,
}, },
ocsPermissions: PermissionRead | PermissionShare, ocsPermissions: p,
} }
} }
@@ -208,12 +212,16 @@ func NewSpaceViewerRole() *Role {
} }
} }
// NewEditorRole creates an editor role // NewEditorRole creates an editor role. `sharing` indicates if sharing permission should be added
func NewEditorRole() *Role { func NewEditorRole(sharing bool) *Role {
p := PermissionRead | PermissionCreate | PermissionWrite | PermissionDelete
if sharing {
p |= PermissionShare
}
return &Role{ return &Role{
Name: RoleEditor, Name: RoleEditor,
cS3ResourcePermissions: &provider.ResourcePermissions{ cS3ResourcePermissions: &provider.ResourcePermissions{
AddGrant: true, AddGrant: sharing,
CreateContainer: true, CreateContainer: true,
Delete: true, Delete: true,
GetPath: true, GetPath: true,
@@ -227,7 +235,7 @@ func NewEditorRole() *Role {
RestoreRecycleItem: true, RestoreRecycleItem: true,
Stat: true, Stat: true,
}, },
ocsPermissions: PermissionRead | PermissionCreate | PermissionWrite | PermissionDelete | PermissionShare, ocsPermissions: p,
} }
} }
@@ -331,6 +339,7 @@ func NewManagerRole() *Role {
// RoleFromOCSPermissions tries to map ocs permissions to a role // RoleFromOCSPermissions tries to map ocs permissions to a role
// TODO: rethink using this. ocs permissions cannot be assigned 1:1 to roles // TODO: rethink using this. ocs permissions cannot be assigned 1:1 to roles
// NOTE: If resharing=false in the system this function will return SpaceViewerRole instead ViewerRole
func RoleFromOCSPermissions(p Permissions) *Role { func RoleFromOCSPermissions(p Permissions) *Role {
if p == PermissionInvalid { if p == PermissionInvalid {
return NewNoneRole() return NewNoneRole()
@@ -339,13 +348,13 @@ func RoleFromOCSPermissions(p Permissions) *Role {
if p.Contain(PermissionRead) { if p.Contain(PermissionRead) {
if p.Contain(PermissionWrite) && p.Contain(PermissionCreate) && p.Contain(PermissionDelete) { if p.Contain(PermissionWrite) && p.Contain(PermissionCreate) && p.Contain(PermissionDelete) {
if p.Contain(PermissionShare) { if p.Contain(PermissionShare) {
return NewEditorRole() return NewEditorRole(true)
} }
return NewSpaceEditorRole() return NewSpaceEditorRole()
} }
if p == PermissionRead|PermissionShare { if p == PermissionRead|PermissionShare {
return NewViewerRole() return NewViewerRole(true)
} }
if p == PermissionRead { if p == PermissionRead {
return NewSpaceViewerRole() return NewSpaceViewerRole()
@@ -64,6 +64,8 @@ import (
const ( const (
storageIDPrefix string = "shared::" storageIDPrefix string = "shared::"
_resharingDefault bool = false
) )
var ( var (
@@ -84,6 +86,7 @@ type Handler struct {
resourceInfoCache cache.ResourceInfoCache resourceInfoCache cache.ResourceInfoCache
resourceInfoCacheTTL time.Duration resourceInfoCacheTTL time.Duration
deniable bool deniable bool
resharing bool
getClient GatewayClientGetter getClient GatewayClientGetter
} }
@@ -134,6 +137,7 @@ func (h *Handler) Init(c *config.Config) {
h.userIdentifierCache = ttlcache.NewCache() h.userIdentifierCache = ttlcache.NewCache()
_ = h.userIdentifierCache.SetTTL(time.Second * time.Duration(c.UserIdentifierCacheTTL)) _ = h.userIdentifierCache.SetTTL(time.Second * time.Duration(c.UserIdentifierCacheTTL))
h.deniable = c.EnableDenials h.deniable = c.EnableDenials
h.resharing = resharing(c)
cache, err := getCacheManager(c) cache, err := getCacheManager(c)
if err == nil { if err == nil {
@@ -288,7 +292,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) {
response.WriteOCSSuccess(w, r, s) response.WriteOCSSuccess(w, r, s)
case int(conversions.ShareTypePublicLink): case int(conversions.ShareTypePublicLink):
// public links default to read only // public links default to read only
_, _, ocsErr := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole()) _, _, ocsErr := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole(h.resharing))
if ocsErr != nil && ocsErr.Error != conversions.ErrZeroPermission { if ocsErr != nil && ocsErr.Error != conversions.ErrZeroPermission {
response.WriteOCSError(w, r, http.StatusNotFound, "No share permission", nil) response.WriteOCSError(w, r, http.StatusNotFound, "No share permission", nil)
return return
@@ -306,7 +310,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) {
response.WriteOCSSuccess(w, r, s) response.WriteOCSSuccess(w, r, s)
case int(conversions.ShareTypeFederatedCloudShare): case int(conversions.ShareTypeFederatedCloudShare):
// federated shares default to read only // federated shares default to read only
if role, val, err := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole()); err == nil { if role, val, err := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole(h.resharing)); err == nil {
h.createFederatedCloudShare(w, r, statRes.Info, role, val) h.createFederatedCloudShare(w, r, statRes.Info, role, val)
} }
case int(conversions.ShareTypeSpaceMembershipUser), int(conversions.ShareTypeSpaceMembershipGroup): case int(conversions.ShareTypeSpaceMembershipUser), int(conversions.ShareTypeSpaceMembershipGroup):
@@ -396,7 +400,7 @@ func (h *Handler) extractPermissions(reqRole string, reqPermissions string, ri *
// the share role overrides the requested permissions // the share role overrides the requested permissions
if reqRole != "" { if reqRole != "" {
role = conversions.RoleFromName(reqRole) role = conversions.RoleFromName(reqRole, h.resharing)
} }
// if the role is unknown - fall back to reqPermissions or defaultPermissions // if the role is unknown - fall back to reqPermissions or defaultPermissions
@@ -1545,3 +1549,10 @@ func sufficientPermissions(existing, requested *provider.ResourcePermissions, is
rp := conversions.RoleFromResourcePermissions(requested, islink).OCSPermissions() rp := conversions.RoleFromResourcePermissions(requested, islink).OCSPermissions()
return ep.Contain(rp) return ep.Contain(rp)
} }
func resharing(c *config.Config) bool {
if c != nil && c.Capabilities.Capabilities != nil && c.Capabilities.Capabilities.FilesSharing != nil {
return bool(c.Capabilities.Capabilities.FilesSharing.Resharing)
}
return _resharingDefault
}
+2 -14
View File
@@ -128,20 +128,8 @@ func SharePermToInt(p *provider.ResourcePermissions) int {
// IntTosharePerm retrieves read/write permissions from an integer // IntTosharePerm retrieves read/write permissions from an integer
func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions { func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions {
switch p { perms, _ := conversions.NewPermissions(p)
case 1: return conversions.RoleFromOCSPermissions(perms).CS3ResourcePermissions()
return conversions.NewViewerRole().CS3ResourcePermissions()
case 15:
if itemType == "folder" {
return conversions.NewEditorRole().CS3ResourcePermissions()
}
return conversions.NewFileEditorRole().CS3ResourcePermissions()
case 4:
return conversions.NewUploaderRole().CS3ResourcePermissions()
default:
// TODO we may have other options, for now this is a denial
return &provider.ResourcePermissions{}
}
} }
// IntToShareState retrieves the received share state from an integer // IntToShareState retrieves the received share state from an integer
@@ -32,6 +32,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/bluele/gcache"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/appctx" "github.com/cs3org/reva/v2/pkg/appctx"
"github.com/cs3org/reva/v2/pkg/errtypes" "github.com/cs3org/reva/v2/pkg/errtypes"
@@ -78,6 +79,8 @@ type Tree struct {
blobstore Blobstore blobstore Blobstore
options *options.Options options *options.Options
idCache gcache.Cache
} }
// PermissionCheckFunc defined a function used to check resource permissions // PermissionCheckFunc defined a function used to check resource permissions
@@ -89,6 +92,7 @@ func New(lu PathLookup, bs Blobstore, o *options.Options) *Tree {
lookup: lu, lookup: lu,
blobstore: bs, blobstore: bs,
options: o, options: o,
idCache: gcache.New(1_000_000).LRU().Build(),
} }
} }
@@ -271,6 +275,7 @@ func (t *Tree) Move(ctx context.Context, oldNode *node.Node, newNode *node.Node)
if err != nil { if err != nil {
return errors.Wrap(err, "Decomposedfs: could not move child") return errors.Wrap(err, "Decomposedfs: could not move child")
} }
t.idCache.Remove(filepath.Join(oldNode.ParentPath(), oldNode.Name))
// update target parentid and name // update target parentid and name
attribs := node.Attributes{} attribs := node.Attributes{}
@@ -360,9 +365,19 @@ func (t *Tree) ListFolder(ctx context.Context, n *node.Node) ([]*node.Node, erro
for i := 0; i < numWorkers; i++ { for i := 0; i < numWorkers; i++ {
g.Go(func() error { g.Go(func() error {
for name := range work { for name := range work {
nodeID, err := readChildNodeFromLink(filepath.Join(dir, name)) nodeID := ""
if err != nil { path := filepath.Join(dir, name)
return err if val, err := t.idCache.Get(path); err == nil {
nodeID = val.(string)
} else {
nodeID, err = readChildNodeFromLink(path)
if err != nil {
return err
}
err = t.idCache.Set(path, nodeID)
if err != nil {
return err
}
} }
child, err := node.ReadNode(ctx, t.lookup, n.SpaceID, nodeID, false, n, true) child, err := node.ReadNode(ctx, t.lookup, n.SpaceID, nodeID, false, n, true)
@@ -481,7 +496,9 @@ func (t *Tree) Delete(ctx context.Context, n *node.Node) (err error) {
_ = os.Remove(n.LockFilePath()) _ = os.Remove(n.LockFilePath())
// finally remove the entry from the parent dir // finally remove the entry from the parent dir
err = os.Remove(filepath.Join(n.ParentPath(), n.Name)) path := filepath.Join(n.ParentPath(), n.Name)
err = os.Remove(path)
t.idCache.Remove(path)
if err != nil { if err != nil {
// To roll back changes // To roll back changes
// TODO revert the rename // TODO revert the rename
+8 -2
View File
@@ -84,6 +84,8 @@ const LockTypeKey = "reva.lock.type"
var hiddenReg = regexp.MustCompile(`\.sys\..#.`) var hiddenReg = regexp.MustCompile(`\.sys\..#.`)
var _resharing = false
func (c *Config) init() { func (c *Config) init() {
c.Namespace = path.Clean(c.Namespace) c.Namespace = path.Clean(c.Namespace)
if !strings.HasPrefix(c.Namespace, "/") { if !strings.HasPrefix(c.Namespace, "/") {
@@ -2121,15 +2123,19 @@ func (fs *eosfs) permissionSet(ctx context.Context, eosFileInfo *eosclient.FileI
// The logged-in user is the owner but we may be impersonating them // The logged-in user is the owner but we may be impersonating them
// on behalf of a public share accessor. // on behalf of a public share accessor.
// NOTE: This will grant the user full access when the opaque is nil
// it is likely that this can be used for attacks
if u.Opaque != nil { if u.Opaque != nil {
// FIXME: "editor" and "viewer" are not sufficient anymore, they could have different permissions
// The role names should not be hardcoded any more as they will come from config in the future
if publicShare, ok := u.Opaque.Map["public-share-role"]; ok { if publicShare, ok := u.Opaque.Map["public-share-role"]; ok {
if string(publicShare.Value) == "editor" { if string(publicShare.Value) == "editor" {
return conversions.NewEditorRole().CS3ResourcePermissions() return conversions.NewEditorRole(_resharing).CS3ResourcePermissions()
} else if string(publicShare.Value) == "uploader" { } else if string(publicShare.Value) == "uploader" {
return conversions.NewUploaderRole().CS3ResourcePermissions() return conversions.NewUploaderRole().CS3ResourcePermissions()
} }
// Default to viewer role // Default to viewer role
return conversions.NewViewerRole().CS3ResourcePermissions() return conversions.NewViewerRole(_resharing).CS3ResourcePermissions()
} }
} }
+226 -226
View File
@@ -1,226 +1,226 @@
# Imaging # Imaging
[![GoDoc](https://godoc.org/github.com/disintegration/imaging?status.svg)](https://godoc.org/github.com/disintegration/imaging) [![GoDoc](https://godoc.org/github.com/disintegration/imaging?status.svg)](https://godoc.org/github.com/disintegration/imaging)
[![Build Status](https://travis-ci.org/disintegration/imaging.svg?branch=master)](https://travis-ci.org/disintegration/imaging) [![Build Status](https://travis-ci.org/disintegration/imaging.svg?branch=master)](https://travis-ci.org/disintegration/imaging)
[![Coverage Status](https://coveralls.io/repos/github/disintegration/imaging/badge.svg?branch=master&service=github)](https://coveralls.io/github/disintegration/imaging?branch=master) [![Coverage Status](https://coveralls.io/repos/github/disintegration/imaging/badge.svg?branch=master&service=github)](https://coveralls.io/github/disintegration/imaging?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/disintegration/imaging)](https://goreportcard.com/report/github.com/disintegration/imaging) [![Go Report Card](https://goreportcard.com/badge/github.com/disintegration/imaging)](https://goreportcard.com/report/github.com/disintegration/imaging)
Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.). Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.).
All the image processing functions provided by the package accept any image type that implements `image.Image` interface All the image processing functions provided by the package accept any image type that implements `image.Image` interface
as an input, and return a new image of `*image.NRGBA` type (32bit RGBA colors, non-premultiplied alpha). as an input, and return a new image of `*image.NRGBA` type (32bit RGBA colors, non-premultiplied alpha).
## Installation ## Installation
go get -u github.com/disintegration/imaging go get -u github.com/disintegration/imaging
## Documentation ## Documentation
http://godoc.org/github.com/disintegration/imaging http://godoc.org/github.com/disintegration/imaging
## Usage examples ## Usage examples
A few usage examples can be found below. See the documentation for the full list of supported functions. A few usage examples can be found below. See the documentation for the full list of supported functions.
### Image resizing ### Image resizing
```go ```go
// Resize srcImage to size = 128x128px using the Lanczos filter. // Resize srcImage to size = 128x128px using the Lanczos filter.
dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos) dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
// Resize srcImage to width = 800px preserving the aspect ratio. // Resize srcImage to width = 800px preserving the aspect ratio.
dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos) dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
// Scale down srcImage to fit the 800x600px bounding box. // Scale down srcImage to fit the 800x600px bounding box.
dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos) dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
// Resize and crop the srcImage to fill the 100x100px area. // Resize and crop the srcImage to fill the 100x100px area.
dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos) dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
``` ```
Imaging supports image resizing using various resampling filters. The most notable ones: Imaging supports image resizing using various resampling filters. The most notable ones:
- `Lanczos` - A high-quality resampling filter for photographic images yielding sharp results. - `Lanczos` - A high-quality resampling filter for photographic images yielding sharp results.
- `CatmullRom` - A sharp cubic filter that is faster than Lanczos filter while providing similar results. - `CatmullRom` - A sharp cubic filter that is faster than Lanczos filter while providing similar results.
- `MitchellNetravali` - A cubic filter that produces smoother results with less ringing artifacts than CatmullRom. - `MitchellNetravali` - A cubic filter that produces smoother results with less ringing artifacts than CatmullRom.
- `Linear` - Bilinear resampling filter, produces smooth output. Faster than cubic filters. - `Linear` - Bilinear resampling filter, produces smooth output. Faster than cubic filters.
- `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor. - `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor.
- `NearestNeighbor` - Fastest resampling filter, no antialiasing. - `NearestNeighbor` - Fastest resampling filter, no antialiasing.
The full list of supported filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct. The full list of supported filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct.
**Resampling filters comparison** **Resampling filters comparison**
Original image: Original image:
![srcImage](testdata/branches.png) ![srcImage](testdata/branches.png)
The same image resized from 600x400px to 150x100px using different resampling filters. The same image resized from 600x400px to 150x100px using different resampling filters.
From faster (lower quality) to slower (higher quality): From faster (lower quality) to slower (higher quality):
Filter | Resize result Filter | Resize result
--------------------------|--------------------------------------------- --------------------------|---------------------------------------------
`imaging.NearestNeighbor` | ![dstImage](testdata/out_resize_nearest.png) `imaging.NearestNeighbor` | ![dstImage](testdata/out_resize_nearest.png)
`imaging.Linear` | ![dstImage](testdata/out_resize_linear.png) `imaging.Linear` | ![dstImage](testdata/out_resize_linear.png)
`imaging.CatmullRom` | ![dstImage](testdata/out_resize_catrom.png) `imaging.CatmullRom` | ![dstImage](testdata/out_resize_catrom.png)
`imaging.Lanczos` | ![dstImage](testdata/out_resize_lanczos.png) `imaging.Lanczos` | ![dstImage](testdata/out_resize_lanczos.png)
### Gaussian Blur ### Gaussian Blur
```go ```go
dstImage := imaging.Blur(srcImage, 0.5) dstImage := imaging.Blur(srcImage, 0.5)
``` ```
Sigma parameter allows to control the strength of the blurring effect. Sigma parameter allows to control the strength of the blurring effect.
Original image | Sigma = 0.5 | Sigma = 1.5 Original image | Sigma = 0.5 | Sigma = 1.5
-----------------------------------|----------------------------------------|--------------------------------------- -----------------------------------|----------------------------------------|---------------------------------------
![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png) ![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
### Sharpening ### Sharpening
```go ```go
dstImage := imaging.Sharpen(srcImage, 0.5) dstImage := imaging.Sharpen(srcImage, 0.5)
``` ```
`Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect. `Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
Original image | Sigma = 0.5 | Sigma = 1.5 Original image | Sigma = 0.5 | Sigma = 1.5
-----------------------------------|-------------------------------------------|------------------------------------------ -----------------------------------|-------------------------------------------|------------------------------------------
![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png) ![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
### Gamma correction ### Gamma correction
```go ```go
dstImage := imaging.AdjustGamma(srcImage, 0.75) dstImage := imaging.AdjustGamma(srcImage, 0.75)
``` ```
Original image | Gamma = 0.75 | Gamma = 1.25 Original image | Gamma = 0.75 | Gamma = 1.25
-----------------------------------|------------------------------------------|----------------------------------------- -----------------------------------|------------------------------------------|-----------------------------------------
![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png) ![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
### Contrast adjustment ### Contrast adjustment
```go ```go
dstImage := imaging.AdjustContrast(srcImage, 20) dstImage := imaging.AdjustContrast(srcImage, 20)
``` ```
Original image | Contrast = 15 | Contrast = -15 Original image | Contrast = 15 | Contrast = -15
-----------------------------------|--------------------------------------------|------------------------------------------- -----------------------------------|--------------------------------------------|-------------------------------------------
![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png) ![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png)
### Brightness adjustment ### Brightness adjustment
```go ```go
dstImage := imaging.AdjustBrightness(srcImage, 20) dstImage := imaging.AdjustBrightness(srcImage, 20)
``` ```
Original image | Brightness = 10 | Brightness = -10 Original image | Brightness = 10 | Brightness = -10
-----------------------------------|----------------------------------------------|--------------------------------------------- -----------------------------------|----------------------------------------------|---------------------------------------------
![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png) ![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
### Saturation adjustment ### Saturation adjustment
```go ```go
dstImage := imaging.AdjustSaturation(srcImage, 20) dstImage := imaging.AdjustSaturation(srcImage, 20)
``` ```
Original image | Saturation = 30 | Saturation = -30 Original image | Saturation = 30 | Saturation = -30
-----------------------------------|----------------------------------------------|--------------------------------------------- -----------------------------------|----------------------------------------------|---------------------------------------------
![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_saturation_p30.png) | ![dstImage](testdata/out_saturation_m30.png) ![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_saturation_p30.png) | ![dstImage](testdata/out_saturation_m30.png)
## FAQ ## FAQ
### Incorrect image orientation after processing (e.g. an image appears rotated after resizing) ### Incorrect image orientation after processing (e.g. an image appears rotated after resizing)
Most probably, the given image contains the EXIF orientation tag. Most probably, the given image contains the EXIF orientation tag.
The stadard `image/*` packages do not support loading and saving The stadard `image/*` packages do not support loading and saving
this kind of information. To fix the issue, try opening images with this kind of information. To fix the issue, try opening images with
the `AutoOrientation` decode option. If this option is set to `true`, the `AutoOrientation` decode option. If this option is set to `true`,
the image orientation is changed after decoding, according to the the image orientation is changed after decoding, according to the
orientation tag (if present). Here's the example: orientation tag (if present). Here's the example:
```go ```go
img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true)) img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
``` ```
### What's the difference between `imaging` and `gift` packages? ### What's the difference between `imaging` and `gift` packages?
[imaging](https://github.com/disintegration/imaging) [imaging](https://github.com/disintegration/imaging)
is designed to be a lightweight and simple image manipulation package. is designed to be a lightweight and simple image manipulation package.
It provides basic image processing functions and a few helper functions It provides basic image processing functions and a few helper functions
such as `Open` and `Save`. It consistently returns *image.NRGBA image such as `Open` and `Save`. It consistently returns *image.NRGBA image
type (8 bits per channel, RGBA). type (8 bits per channel, RGBA).
[gift](https://github.com/disintegration/gift) [gift](https://github.com/disintegration/gift)
supports more advanced image processing, for example, sRGB/Linear color supports more advanced image processing, for example, sRGB/Linear color
space conversions. It also supports different output image types space conversions. It also supports different output image types
(e.g. 16 bits per channel) and provides easy-to-use API for chaining (e.g. 16 bits per channel) and provides easy-to-use API for chaining
multiple processing steps together. multiple processing steps together.
## Example code ## Example code
```go ```go
package main package main
import ( import (
"image" "image"
"image/color" "image/color"
"log" "log"
"github.com/disintegration/imaging" "github.com/disintegration/imaging"
) )
func main() { func main() {
// Open a test image. // Open a test image.
src, err := imaging.Open("testdata/flowers.png") src, err := imaging.Open("testdata/flowers.png")
if err != nil { if err != nil {
log.Fatalf("failed to open image: %v", err) log.Fatalf("failed to open image: %v", err)
} }
// Crop the original image to 300x300px size using the center anchor. // Crop the original image to 300x300px size using the center anchor.
src = imaging.CropAnchor(src, 300, 300, imaging.Center) src = imaging.CropAnchor(src, 300, 300, imaging.Center)
// Resize the cropped image to width = 200px preserving the aspect ratio. // Resize the cropped image to width = 200px preserving the aspect ratio.
src = imaging.Resize(src, 200, 0, imaging.Lanczos) src = imaging.Resize(src, 200, 0, imaging.Lanczos)
// Create a blurred version of the image. // Create a blurred version of the image.
img1 := imaging.Blur(src, 5) img1 := imaging.Blur(src, 5)
// Create a grayscale version of the image with higher contrast and sharpness. // Create a grayscale version of the image with higher contrast and sharpness.
img2 := imaging.Grayscale(src) img2 := imaging.Grayscale(src)
img2 = imaging.AdjustContrast(img2, 20) img2 = imaging.AdjustContrast(img2, 20)
img2 = imaging.Sharpen(img2, 2) img2 = imaging.Sharpen(img2, 2)
// Create an inverted version of the image. // Create an inverted version of the image.
img3 := imaging.Invert(src) img3 := imaging.Invert(src)
// Create an embossed version of the image using a convolution filter. // Create an embossed version of the image using a convolution filter.
img4 := imaging.Convolve3x3( img4 := imaging.Convolve3x3(
src, src,
[9]float64{ [9]float64{
-1, -1, 0, -1, -1, 0,
-1, 1, 1, -1, 1, 1,
0, 1, 1, 0, 1, 1,
}, },
nil, nil,
) )
// Create a new image and paste the four produced images into it. // Create a new image and paste the four produced images into it.
dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0}) dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
dst = imaging.Paste(dst, img1, image.Pt(0, 0)) dst = imaging.Paste(dst, img1, image.Pt(0, 0))
dst = imaging.Paste(dst, img2, image.Pt(0, 200)) dst = imaging.Paste(dst, img2, image.Pt(0, 200))
dst = imaging.Paste(dst, img3, image.Pt(200, 0)) dst = imaging.Paste(dst, img3, image.Pt(200, 0))
dst = imaging.Paste(dst, img4, image.Pt(200, 200)) dst = imaging.Paste(dst, img4, image.Pt(200, 200))
// Save the resulting image as JPEG. // Save the resulting image as JPEG.
err = imaging.Save(dst, "testdata/out_example.jpg") err = imaging.Save(dst, "testdata/out_example.jpg")
if err != nil { if err != nil {
log.Fatalf("failed to save image: %v", err) log.Fatalf("failed to save image: %v", err)
} }
} }
``` ```
Output: Output:
![dstImage](testdata/out_example.jpg) ![dstImage](testdata/out_example.jpg)
+33 -33
View File
@@ -1,33 +1,33 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/go-logfmt/logfmt.svg)](https://pkg.go.dev/github.com/go-logfmt/logfmt) [![Go Reference](https://pkg.go.dev/badge/github.com/go-logfmt/logfmt.svg)](https://pkg.go.dev/github.com/go-logfmt/logfmt)
[![Go Report Card](https://goreportcard.com/badge/go-logfmt/logfmt)](https://goreportcard.com/report/go-logfmt/logfmt) [![Go Report Card](https://goreportcard.com/badge/go-logfmt/logfmt)](https://goreportcard.com/report/go-logfmt/logfmt)
[![Github Actions](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml/badge.svg)](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml) [![Github Actions](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml/badge.svg)](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml)
[![Coverage Status](https://coveralls.io/repos/github/go-logfmt/logfmt/badge.svg?branch=master)](https://coveralls.io/github/go-logfmt/logfmt?branch=master) [![Coverage Status](https://coveralls.io/repos/github/go-logfmt/logfmt/badge.svg?branch=master)](https://coveralls.io/github/go-logfmt/logfmt?branch=master)
# logfmt # logfmt
Package logfmt implements utilities to marshal and unmarshal data in the [logfmt Package logfmt implements utilities to marshal and unmarshal data in the [logfmt
format](https://brandur.org/logfmt). It provides an API similar to format](https://brandur.org/logfmt). It provides an API similar to
[encoding/json](http://golang.org/pkg/encoding/json/) and [encoding/json](http://golang.org/pkg/encoding/json/) and
[encoding/xml](http://golang.org/pkg/encoding/xml/). [encoding/xml](http://golang.org/pkg/encoding/xml/).
The logfmt format was first documented by Brandur Leach in [this The logfmt format was first documented by Brandur Leach in [this
article](https://brandur.org/logfmt). The format has not been formally article](https://brandur.org/logfmt). The format has not been formally
standardized. The most authoritative public specification to date has been the standardized. The most authoritative public specification to date has been the
documentation of a Go Language [package](http://godoc.org/github.com/kr/logfmt) documentation of a Go Language [package](http://godoc.org/github.com/kr/logfmt)
written by Blake Mizerany and Keith Rarick. written by Blake Mizerany and Keith Rarick.
## Goals ## Goals
This project attempts to conform as closely as possible to the prior art, while This project attempts to conform as closely as possible to the prior art, while
also removing ambiguity where necessary to provide well behaved encoder and also removing ambiguity where necessary to provide well behaved encoder and
decoder implementations. decoder implementations.
## Non-goals ## Non-goals
This project does not attempt to formally standardize the logfmt format. In the This project does not attempt to formally standardize the logfmt format. In the
event that logfmt is standardized this project would take conforming to the event that logfmt is standardized this project would take conforming to the
standard as a goal. standard as a goal.
## Versioning ## Versioning
Package logfmt publishes releases via [semver](http://semver.org/) compatible Git tags prefixed with a single 'v'. Package logfmt publishes releases via [semver](http://semver.org/) compatible Git tags prefixed with a single 'v'.
+35 -35
View File
@@ -1,35 +1,35 @@
Developer Certificate of Origin Developer Certificate of Origin
Version 1.1 Version 1.1
Copyright (C) 2015- Klaus Post & Contributors. Copyright (C) 2015- Klaus Post & Contributors.
Email: klauspost@gmail.com Email: klauspost@gmail.com
Everyone is permitted to copy and distribute verbatim copies of this Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed. license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1 Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that: By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I (a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license have the right to submit it under the open source license
indicated in the file; or indicated in the file; or
(b) The contribution is based upon previous work that, to the best (b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that license and I have the right under that license to submit that
work with modifications, whether created in whole or in part work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated permitted to submit under a different license), as indicated
in the file; or in the file; or
(c) The contribution was provided directly to me by some other (c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified person who certified (a), (b) or (c) and I have not modified
it. it.
(d) I understand and agree that this project and the contribution (d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved. this project or the open source license(s) involved.
+1 -1
View File
@@ -349,7 +349,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
github.com/cs3org/go-cs3apis/cs3/types/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1
# github.com/cs3org/reva/v2 v2.12.1-0.20230417084429-b3d96f9db80c # github.com/cs3org/reva/v2 v2.12.1-0.20230420073005-11edad1f09fe
## explicit; go 1.19 ## explicit; go 1.19
github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/internal/grace
github.com/cs3org/reva/v2/cmd/revad/runtime github.com/cs3org/reva/v2/cmd/revad/runtime