mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-03-13 18:00:34 -05:00
Merge remote-tracking branch 'origin/master' into onlyoffice-ext
This commit is contained in:
135
.drone.star
135
.drone.star
@@ -16,7 +16,7 @@ config = {
|
||||
},
|
||||
'apiTests': {
|
||||
'coreBranch': 'master',
|
||||
'coreCommit': '773cf3ea127430699f3bfb4c1b24e96a271a8884',
|
||||
'coreCommit': '8ff1bda2f3c09500b92775c666c1b2236876edd3',
|
||||
'numberOfParts': 10
|
||||
},
|
||||
'uiTests': {
|
||||
@@ -93,40 +93,36 @@ config = {
|
||||
'from_secret': 'private_rocketchat',
|
||||
},
|
||||
}
|
||||
def getTestSuiteNames():
|
||||
keys = config['modules'].keys()
|
||||
|
||||
def getPipelineNames(pipelines=[]):
|
||||
"""getPipelineNames returns names of pipelines as a string array
|
||||
|
||||
Args:
|
||||
pipelines: array of drone pipelines
|
||||
|
||||
Returns:
|
||||
names of the given pipelines as string array
|
||||
"""
|
||||
names = []
|
||||
for key in keys:
|
||||
names.append('linting&unitTests-%s' % (key))
|
||||
for pipeline in pipelines:
|
||||
names.append(pipeline['name'])
|
||||
return names
|
||||
|
||||
def getUITestSuiteNames():
|
||||
return config['uiTests']['suites'].keys()
|
||||
|
||||
def getUITestSuites():
|
||||
return config['uiTests']['suites']
|
||||
|
||||
def getCoreApiTestPipelineNames():
|
||||
names = []
|
||||
for runPart in range(1, config['apiTests']['numberOfParts'] + 1):
|
||||
names.append('Core-API-Tests-owncloud-storage-%s' % runPart)
|
||||
names.append('Core-API-Tests-ocis-storage-%s' % runPart)
|
||||
return names
|
||||
|
||||
def getDependsOnAllTestPipelines(ctx):
|
||||
dependencies = getTestSuiteNames() + [
|
||||
'upload-coverage',
|
||||
'localApiTests-apiOcisSpecific-owncloud',
|
||||
'localApiTests-apiOcisSpecific-ocis',
|
||||
'localApiTests-apiBasic-owncloud',
|
||||
'localApiTests-apiBasic-ocis',
|
||||
] + getCoreApiTestPipelineNames() + getUITestSuiteNames() + ['accountsUITests']
|
||||
|
||||
return dependencies
|
||||
|
||||
def main(ctx):
|
||||
"""main is the entrypoint for drone
|
||||
|
||||
Args:
|
||||
ctx: drone passes a context with information which the pipeline can be adapted to
|
||||
|
||||
Returns:
|
||||
none
|
||||
"""
|
||||
pipelines = []
|
||||
before = testPipelines(ctx)
|
||||
|
||||
before = \
|
||||
testOcisModules(ctx) + \
|
||||
testPipelines(ctx)
|
||||
|
||||
stages = [
|
||||
docker(ctx, 'amd64'),
|
||||
@@ -146,54 +142,50 @@ def main(ctx):
|
||||
badges(ctx),
|
||||
docs(ctx),
|
||||
updateDeployment(ctx),
|
||||
notify(ctx),
|
||||
]
|
||||
|
||||
if ctx.build.event == "cron":
|
||||
notify_pipelines = notify(ctx)
|
||||
notify_pipelines['depends_on'] = getTestPipelinesNames(ctx)
|
||||
pipelines = before + [ notify_pipelines ]
|
||||
notify_pipeline = notify(ctx)
|
||||
notify_pipeline['depends_on'] = \
|
||||
getPipelineNames(before)
|
||||
|
||||
pipelines = before + [ notify_pipeline ]
|
||||
|
||||
elif '[docs-only]' in (ctx.build.title + ctx.build.message):
|
||||
doc_pipelines = docs(ctx)
|
||||
doc_pipelines['depends_on'] = []
|
||||
docs_pipeline = docs(ctx)
|
||||
docs_pipeline['depends_on'] = []
|
||||
docs_pipelines = [ docs_pipeline ]
|
||||
|
||||
notify_pipelines = notify(ctx)
|
||||
notify_pipelines['depends_on'] = ['docs']
|
||||
notify_pipeline = notify(ctx)
|
||||
notify_pipeline['depends_on'] = \
|
||||
getPipelineNames(docs_pipelines)
|
||||
|
||||
pipelines = docs_pipelines + [ notify_pipeline ]
|
||||
|
||||
pipelines = [ doc_pipelines, notify_pipelines ]
|
||||
else:
|
||||
pipelines = before + stages + after
|
||||
|
||||
notify_pipeline = notify(ctx)
|
||||
notify_pipeline['depends_on'] = \
|
||||
getPipelineNames(pipelines)
|
||||
|
||||
pipelines = pipelines + [ notify_pipeline ]
|
||||
|
||||
return pipelines
|
||||
|
||||
def getTestPipelinesNames(ctx):
|
||||
pipelines = getTestSuiteNames()
|
||||
def testOcisModules(ctx):
|
||||
pipelines = []
|
||||
for module in config['modules']:
|
||||
pipelines.append(testOcisModule(ctx, module))
|
||||
|
||||
pipelines += [
|
||||
'localApiTests-apiOcisSpecific-owncloud',
|
||||
'localApiTests-apiOcisSpecific-ocis',
|
||||
'localApiTests-apiBasic-owncloud',
|
||||
'localApiTests-apiBasic-ocis',
|
||||
]
|
||||
coverage_upload = uploadCoverage(ctx)
|
||||
coverage_upload['depends_on'] = getPipelineNames(pipelines)
|
||||
|
||||
for runPart in range(1, config['apiTests']['numberOfParts'] + 1):
|
||||
pipelines.append('Core-API-Tests-ocis-storage-%s' % (runPart))
|
||||
pipelines.append('Core-API-Tests-owncloud-storage-%s' % (runPart))
|
||||
return pipelines + [coverage_upload]
|
||||
|
||||
pipelines = pipelines + getUITestSuiteNames()
|
||||
|
||||
pipelines.append('accountsUITests')
|
||||
return pipelines
|
||||
|
||||
def testPipelines(ctx):
|
||||
pipelines = []
|
||||
|
||||
for module in config['modules']:
|
||||
pipelines.append(testing(ctx, module))
|
||||
|
||||
pipelines += [
|
||||
uploadCoverage(ctx),
|
||||
pipelines = [
|
||||
localApiTests(ctx, config['apiTests']['coreBranch'], config['apiTests']['coreCommit'], 'owncloud', 'apiOcisSpecific'),
|
||||
localApiTests(ctx, config['apiTests']['coreBranch'], config['apiTests']['coreCommit'], 'ocis', 'apiOcisSpecific'),
|
||||
localApiTests(ctx, config['apiTests']['coreBranch'], config['apiTests']['coreCommit'], 'owncloud', 'apiBasic', 'default'),
|
||||
@@ -208,7 +200,7 @@ def testPipelines(ctx):
|
||||
pipelines.append(accountsUITests(ctx, config['uiTests']['phoenixBranch'], config['uiTests']['phoenixCommit']))
|
||||
return pipelines
|
||||
|
||||
def testing(ctx, module):
|
||||
def testOcisModule(ctx, module):
|
||||
steps = generate(module) + [
|
||||
{
|
||||
'name': 'vet',
|
||||
@@ -308,6 +300,12 @@ def testing(ctx, module):
|
||||
'refs/pull/**',
|
||||
],
|
||||
},
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'temp': {},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
def uploadCoverage(ctx):
|
||||
@@ -376,7 +374,6 @@ def uploadCoverage(ctx):
|
||||
'refs/pull/**',
|
||||
],
|
||||
},
|
||||
'depends_on': getTestSuiteNames(),
|
||||
}
|
||||
|
||||
def localApiTests(ctx, coreBranch = 'master', coreCommit = '', storage = 'owncloud', suite = 'apiOcisSpecific', accounts_hash_difficulty = 4):
|
||||
@@ -491,11 +488,11 @@ def coreApiTests(ctx, coreBranch = 'master', coreCommit = '', part_number = 1, n
|
||||
}
|
||||
|
||||
def uiTests(ctx, phoenixBranch, phoenixCommit):
|
||||
suiteNames = getUITestSuiteNames()
|
||||
return [uiTestPipeline(suiteName, phoenixBranch, phoenixCommit) for suiteName in suiteNames]
|
||||
suiteNames = config['uiTests']['suites'].keys()
|
||||
return [uiTestPipeline(ctx, suiteName, phoenixBranch, phoenixCommit) for suiteName in suiteNames]
|
||||
|
||||
def uiTestPipeline(suiteName, phoenixBranch = 'master', phoenixCommit = '', storage = 'owncloud', accounts_hash_difficulty = 4):
|
||||
suites = getUITestSuites()
|
||||
def uiTestPipeline(ctx, suiteName, phoenixBranch = 'master', phoenixCommit = '', storage = 'owncloud', accounts_hash_difficulty = 4):
|
||||
suites = config['uiTests']['suites']
|
||||
paths = ""
|
||||
suite = suites[suiteName]
|
||||
if type(suite) == "list":
|
||||
@@ -731,7 +728,7 @@ def docker(ctx, arch):
|
||||
'temp': {},
|
||||
},
|
||||
],
|
||||
'depends_on': getDependsOnAllTestPipelines(ctx),
|
||||
'depends_on': getPipelineNames(testOcisModules(ctx) + testPipelines(ctx)),
|
||||
'trigger': {
|
||||
'ref': [
|
||||
'refs/heads/master',
|
||||
@@ -803,7 +800,7 @@ def dockerEos(ctx):
|
||||
'temp': {},
|
||||
},
|
||||
],
|
||||
'depends_on': getDependsOnAllTestPipelines(ctx),
|
||||
'depends_on': getPipelineNames(testOcisModules(ctx) + testPipelines(ctx)),
|
||||
'trigger': {
|
||||
'ref': [
|
||||
'refs/heads/master',
|
||||
@@ -951,7 +948,7 @@ def binary(ctx, name):
|
||||
'temp': {},
|
||||
},
|
||||
],
|
||||
'depends_on': getDependsOnAllTestPipelines(ctx),
|
||||
'depends_on': getPipelineNames(testOcisModules(ctx) + testPipelines(ctx)),
|
||||
'trigger': {
|
||||
'ref': [
|
||||
'refs/heads/master',
|
||||
|
||||
38
CHANGELOG.md
38
CHANGELOG.md
@@ -20,11 +20,13 @@
|
||||
* Bugfix - Fix director selection in proxy: [#521](https://github.com/owncloud/ocis/pull/521)
|
||||
* Bugfix - Build docker images with alpine:latest instead of alpine:edge: [#416](https://github.com/owncloud/ocis/pull/416)
|
||||
* Change - Accounts UI shows message when no permissions: [#656](https://github.com/owncloud/ocis/pull/656)
|
||||
* Change - Cache password validation: [#958](https://github.com/owncloud/ocis/pull/958)
|
||||
* Change - Filesystem based index: [#709](https://github.com/owncloud/ocis/pull/709)
|
||||
* Change - Rebuild index command for accounts: [#748](https://github.com/owncloud/ocis/pull/748)
|
||||
* Change - Add k6: [#941](https://github.com/owncloud/ocis/pull/941)
|
||||
* Change - Add the thumbnails command: [#156](https://github.com/owncloud/ocis/issues/156)
|
||||
* Change - Use bcrypt to hash the user passwords: [#510](https://github.com/owncloud/ocis/issues/510)
|
||||
* Change - Replace the library which scales the images: [#910](https://github.com/owncloud/ocis/pull/910)
|
||||
* Change - Choose disk or cs3 storage for accounts and groups: [#623](https://github.com/owncloud/ocis/pull/623)
|
||||
* Change - Enable OpenID dynamic client registration: [#811](https://github.com/owncloud/ocis/issues/811)
|
||||
* Change - Integrate import command from ocis-migration: [#249](https://github.com/owncloud/ocis/pull/249)
|
||||
@@ -87,8 +89,10 @@
|
||||
* Enhancement - Update glauth to dev 4f029234b2308: [#786](https://github.com/owncloud/ocis/pull/786)
|
||||
* Enhancement - Update konnectd to v0.33.8: [#744](https://github.com/owncloud/ocis/pull/744)
|
||||
* Enhancement - Update reva to v1.4.1-0.20201123062044-b2c4af4e897d: [#823](https://github.com/owncloud/ocis/pull/823)
|
||||
* Enhancement - Update reva to v1.4.1-0.20201130061320-ac85e68e0600: [#980](https://github.com/owncloud/ocis/pull/980)
|
||||
* Enhancement - Update reva to cdb3d6688da5: [#748](https://github.com/owncloud/ocis/pull/748)
|
||||
* Enhancement - Update reva to dd3a8c0f38: [#725](https://github.com/owncloud/ocis/pull/725)
|
||||
* Enhancement - Update reva to v1.4.1-0.20201127111856-e6a6212c1b7b: [#971](https://github.com/owncloud/ocis/pull/971)
|
||||
|
||||
## Details
|
||||
|
||||
@@ -249,6 +253,15 @@
|
||||
|
||||
https://github.com/owncloud/ocis/pull/656
|
||||
|
||||
* Change - Cache password validation: [#958](https://github.com/owncloud/ocis/pull/958)
|
||||
|
||||
Tags: accounts
|
||||
|
||||
The password validity check for requests like `login eq '%s' and password eq '%s'` is now cached
|
||||
for 10 minutes. This improves the performance for basic auth requests.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/958
|
||||
|
||||
* Change - Filesystem based index: [#709](https://github.com/owncloud/ocis/pull/709)
|
||||
|
||||
Tags: accounts, storage
|
||||
@@ -300,6 +313,12 @@
|
||||
|
||||
https://github.com/owncloud/ocis/issues/510
|
||||
|
||||
* Change - Replace the library which scales the images: [#910](https://github.com/owncloud/ocis/pull/910)
|
||||
|
||||
The library went out of support. Also did some refactoring of the thumbnails service code.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/910
|
||||
|
||||
* Change - Choose disk or cs3 storage for accounts and groups: [#623](https://github.com/owncloud/ocis/pull/623)
|
||||
|
||||
Tags: accounts
|
||||
@@ -1763,6 +1782,14 @@
|
||||
https://github.com/cs3org/reva/pull/1324
|
||||
https://github.com/cs3org/reva/pull/1326
|
||||
|
||||
* Enhancement - Update reva to v1.4.1-0.20201130061320-ac85e68e0600: [#980](https://github.com/owncloud/ocis/pull/980)
|
||||
|
||||
* Fix move operation in ocis storage driver [csorg/reva#1343](https://github.com/cs3org/reva/pull/1343)
|
||||
|
||||
https://github.com/owncloud/ocis/issues/975
|
||||
https://github.com/owncloud/ocis/pull/980
|
||||
https://github.com/cs3org/reva/pull/1343
|
||||
|
||||
* Enhancement - Update reva to cdb3d6688da5: [#748](https://github.com/owncloud/ocis/pull/748)
|
||||
|
||||
* let the gateway filter invalid references
|
||||
@@ -1776,3 +1803,14 @@
|
||||
|
||||
https://github.com/owncloud/ocis/pull/725
|
||||
https://github.com/cs3org/reva/pull/1264
|
||||
|
||||
* Enhancement - Update reva to v1.4.1-0.20201127111856-e6a6212c1b7b: [#971](https://github.com/owncloud/ocis/pull/971)
|
||||
|
||||
Tags: reva
|
||||
|
||||
* Fix capabilities response for multiple client versions #1331 [cs3org/reva#1331](https://github.com/cs3org/reva/pull/1331)
|
||||
* Fix home storage redirect for remote.php/dav/files [cs3org/reva#1342](https://github.com/cs3org/reva/pull/1342)
|
||||
|
||||
https://github.com/owncloud/ocis/pull/971
|
||||
https://github.com/cs3org/reva/pull/1331
|
||||
https://github.com/cs3org/reva/pull/1342
|
||||
|
||||
@@ -4,7 +4,7 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600
|
||||
github.com/go-chi/chi v4.1.2+incompatible
|
||||
github.com/go-chi/render v1.0.1
|
||||
github.com/gofrs/uuid v3.3.0+incompatible
|
||||
|
||||
@@ -192,6 +192,12 @@ github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d h1:8lqmft08fZJHoi/XG
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c h1:x7HkQqFGA+7FJUfyDO9tM2gF5i540PQePx+1kGUUYgA=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d h1:Sr6ZWGjTds5cWDei3mJev2+RPJ0iejKnVrYklr5mO+M=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b h1:Bypxdf3vXwyEeL86MMoPPuLbv4P979nkGsuTX6OQ0i8=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600 h1:4CKU+R4UNvILzsPrcAFwEbk/8Hc6vJqwO7SxK0gAm4I=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/owncloud/ocis/ocis-pkg/cache"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"path"
|
||||
"regexp"
|
||||
@@ -32,6 +36,12 @@ import (
|
||||
// accLock mutually exclude readers from writers on account files
|
||||
var accLock sync.Mutex
|
||||
|
||||
// passwordValidCache caches basic auth password validations
|
||||
var passwordValidCache = cache.NewCache(cache.Size(1024))
|
||||
|
||||
// passwordValidCacheExpiration defines the entry lifetime
|
||||
const passwordValidCacheExpiration = 10 * time.Minute
|
||||
|
||||
// an auth request is currently hardcoded and has to match this regex
|
||||
// login eq \"teddy\" and password eq \"F&1!b90t111!\"
|
||||
var authQuery = regexp.MustCompile(`^login eq '(.*)' and password eq '(.*)'$`) // TODO how is ' escaped in the password?
|
||||
@@ -128,7 +138,6 @@ func (s Service) ListAccounts(ctx context.Context, in *proto.ListAccountsRequest
|
||||
|
||||
teardownServiceUser := s.serviceUserToIndex()
|
||||
defer teardownServiceUser()
|
||||
|
||||
match, authRequest := getAuthQueryMatch(in.Query)
|
||||
if authRequest {
|
||||
password := match[2]
|
||||
@@ -152,11 +161,54 @@ func (s Service) ListAccounts(ctx context.Context, in *proto.ListAccountsRequest
|
||||
if err != nil || a.PasswordProfile == nil || len(a.PasswordProfile.Password) == 0 {
|
||||
return merrors.Unauthorized(s.id, "account not found or invalid credentials")
|
||||
}
|
||||
if !isPasswordValid(s.log, a.PasswordProfile.Password, password) {
|
||||
return merrors.Unauthorized(s.id, "account not found or invalid credentials")
|
||||
|
||||
// isPasswordValid uses bcrypt.CompareHashAndPassword which is slow by design.
|
||||
// if every request that matches authQuery regex needs to do this step over and over again,
|
||||
// this is secure but also slow. In this implementation we keep it same secure but increase the speed.
|
||||
//
|
||||
// flow:
|
||||
// - request comes in
|
||||
// - it creates a sha256 based on found account PasswordProfile.LastPasswordChangeDateTime and requested password (v)
|
||||
// - it checks if the cache already contains an entry that matches found account Id // account PasswordProfile.LastPasswordChangeDateTime (k)
|
||||
// - if no entry exists it runs the bcrypt.CompareHashAndPassword as before and if everything is ok it stores the
|
||||
// result by the (k) as key and (v) as value. If not it errors
|
||||
// - if a entry is found it checks if the given value matches (v). If it doesnt match the cache entry gets removed
|
||||
// and it errors.
|
||||
//
|
||||
// if many concurrent requests from the same user come in within a short period of time, it's possible that e is still nil.
|
||||
// This is why all this needs to be wrapped within a sync.Mutex locking to prevent calling bcrypt.CompareHashAndPassword unnecessarily too often.
|
||||
{
|
||||
var suspicious bool
|
||||
|
||||
kh := sha256.New()
|
||||
kh.Write([]byte(a.Id))
|
||||
k := hex.EncodeToString(kh.Sum([]byte(a.PasswordProfile.LastPasswordChangeDateTime.String())))
|
||||
|
||||
vh := sha256.New()
|
||||
vh.Write([]byte(a.PasswordProfile.Password))
|
||||
v := vh.Sum([]byte(password))
|
||||
|
||||
e := passwordValidCache.Get(k)
|
||||
|
||||
if e == nil {
|
||||
suspicious = !isPasswordValid(s.log, a.PasswordProfile.Password, password)
|
||||
} else if !bytes.Equal(e.V.([]byte), v) {
|
||||
suspicious = true
|
||||
}
|
||||
|
||||
if suspicious {
|
||||
passwordValidCache.Unset(k)
|
||||
return merrors.Unauthorized(s.id, "account not found or invalid credentials")
|
||||
}
|
||||
|
||||
if e == nil {
|
||||
passwordValidCache.Set(k, v, time.Now().Add(passwordValidCacheExpiration))
|
||||
}
|
||||
}
|
||||
|
||||
a.PasswordProfile.Password = ""
|
||||
out.Accounts = []*proto.Account{a}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
6
changelog/reva-update-2020-11-26.md
Normal file
6
changelog/reva-update-2020-11-26.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Enhancement: Update reva to v1.4.1-0.20201125172625-a5ab834a565d
|
||||
|
||||
Mostly to bring fixes to pressing changes.
|
||||
|
||||
https://github.com/cs3org/reva/pull/1320
|
||||
https://github.com/cs3org/reva/pull/1338
|
||||
@@ -0,0 +1,8 @@
|
||||
Change: Cache password validation
|
||||
|
||||
Tags: accounts
|
||||
|
||||
The password validity check for requests like `login eq '%s' and password eq '%s'` is now cached for 10 minutes.
|
||||
This improves the performance for basic auth requests.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/958
|
||||
6
changelog/unreleased/change-thumbnails-library.md
Normal file
6
changelog/unreleased/change-thumbnails-library.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Change: replace the library which scales the images
|
||||
|
||||
The library went out of support.
|
||||
Also did some refactoring of the thumbnails service code.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/910
|
||||
7
changelog/unreleased/update-reva-to-ac85e68.md
Normal file
7
changelog/unreleased/update-reva-to-ac85e68.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Enhancement: Update reva to v1.4.1-0.20201130061320-ac85e68e0600
|
||||
|
||||
* Fix move operation in ocis storage driver [csorg/reva#1343](https://github.com/cs3org/reva/pull/1343)
|
||||
|
||||
https://github.com/owncloud/ocis/pull/980
|
||||
https://github.com/owncloud/ocis/issues/975
|
||||
https://github.com/cs3org/reva/pull/1343
|
||||
10
changelog/unreleased/update-reva-to-e6a621.md
Normal file
10
changelog/unreleased/update-reva-to-e6a621.md
Normal file
@@ -0,0 +1,10 @@
|
||||
Enhancement: Update reva to v1.4.1-0.20201127111856-e6a6212c1b7b
|
||||
|
||||
Tags: reva
|
||||
|
||||
* Fix capabilities response for multiple client versions #1331 [cs3org/reva#1331](https://github.com/cs3org/reva/pull/1331)
|
||||
* Fix home storage redirect for remote.php/dav/files [cs3org/reva#1342](https://github.com/cs3org/reva/pull/1342)
|
||||
|
||||
https://github.com/owncloud/ocis/pull/971
|
||||
https://github.com/cs3org/reva/pull/1331
|
||||
https://github.com/cs3org/reva/pull/1342
|
||||
@@ -217,6 +217,7 @@ github.com/cs3org/go-cs3apis v0.0.0-20200810113633-b00aca449666 h1:E7VsSSN/2YZLS
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20200810113633-b00aca449666/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.1.0 h1:Gih6ECHvMMGSx523SFluFlDmNMuhYelXYShdWvjvW38=
|
||||
github.com/cs3org/reva v1.1.0/go.mod h1:fBzTrNuAKdQ62ybjpdu8nyhBin90/3/3s6DGQDCdBp4=
|
||||
github.com/cs3org/reva v1.2.2-0.20200924071957-e6676516e61e h1:khITGSnfDXtByQsLezoXgocUgGHJBBn0BPsUihGvk7w=
|
||||
@@ -224,6 +225,7 @@ github.com/cs3org/reva v1.2.2-0.20200924071957-e6676516e61e/go.mod h1:DOV5SjpOBK
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5 h1:nkmk9ywGKpJthWeMYGBiXh4DD6mTCOZLRfGDjp9rsKg=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT524bvxACFkrkZqBzK4BoXLSprxcPshBlSOY=
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -208,12 +208,14 @@ github.com/cs3org/go-cs3apis v0.0.0-20200730121022-c4f3d4f7ddfd/go.mod h1:UXha4T
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20200810113633-b00aca449666/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.1.0 h1:Gih6ECHvMMGSx523SFluFlDmNMuhYelXYShdWvjvW38=
|
||||
github.com/cs3org/reva v1.1.0/go.mod h1:fBzTrNuAKdQ62ybjpdu8nyhBin90/3/3s6DGQDCdBp4=
|
||||
github.com/cs3org/reva v1.2.2-0.20200924071957-e6676516e61e/go.mod h1:DOV5SjpOBKN+aWfOHLdA4KiLQkpyC786PQaXEdRAZ0M=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5 h1:nkmk9ywGKpJthWeMYGBiXh4DD6mTCOZLRfGDjp9rsKg=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT524bvxACFkrkZqBzK4BoXLSprxcPshBlSOY=
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -261,6 +261,7 @@ github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT52
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d h1:8lqmft08fZJHoi/XGBidmfZyemFXwDKBLUd8UDI/2LY=
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
||||
@@ -28,7 +28,7 @@ func NewCache(o ...Option) Cache {
|
||||
}
|
||||
}
|
||||
|
||||
// Get gets a role-bundle by a given `roleID`.
|
||||
// Get gets an entry by given key
|
||||
func (c *Cache) Get(k string) *Entry {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
@@ -43,7 +43,7 @@ func (c *Cache) Get(k string) *Entry {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set sets a roleID / role-bundle.
|
||||
// Set adds an entry for given key and value
|
||||
func (c *Cache) Set(k string, val interface{}, expiration time.Time) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
@@ -58,6 +58,16 @@ func (c *Cache) Set(k string, val interface{}, expiration time.Time) {
|
||||
}
|
||||
}
|
||||
|
||||
// Unset removes an entry by given key
|
||||
func (c *Cache) Unset(k string) bool {
|
||||
if _, ok := c.entries[k]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
delete(c.entries, k)
|
||||
return true
|
||||
}
|
||||
|
||||
// evict frees memory from the cache by removing entries that exceeded the cache TTL.
|
||||
func (c *Cache) evict() {
|
||||
for i := range c.entries {
|
||||
@@ -7,7 +7,7 @@ require (
|
||||
github.com/ascarter/requestid v0.0.0-20170313220838-5b76ab3d4aee
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600
|
||||
github.com/go-chi/chi v4.1.2+incompatible
|
||||
github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5
|
||||
github.com/iancoleman/strcase v0.1.2
|
||||
|
||||
@@ -220,6 +220,12 @@ github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d h1:8lqmft08fZJHoi/XG
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c h1:x7HkQqFGA+7FJUfyDO9tM2gF5i540PQePx+1kGUUYgA=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d h1:Sr6ZWGjTds5cWDei3mJev2+RPJ0iejKnVrYklr5mO+M=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b h1:Bypxdf3vXwyEeL86MMoPPuLbv4P979nkGsuTX6OQ0i8=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600 h1:4CKU+R4UNvILzsPrcAFwEbk/8Hc6vJqwO7SxK0gAm4I=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
23
ocis/go.sum
23
ocis/go.sum
@@ -160,8 +160,6 @@ github.com/aws/aws-sdk-go v1.23.19/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi
|
||||
github.com/aws/aws-sdk-go v1.25.31/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.28.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.33.19/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.35.9 h1:b1HiUpdkFLJyoOQ7zas36YHzjNHH0ivHx/G5lWBeg+U=
|
||||
github.com/aws/aws-sdk-go v1.35.9/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go v1.35.23 h1:SCP0d0XvyJTDmfnHEQPvBaYi3kea1VNUo7uQmkVgFts=
|
||||
github.com/aws/aws-sdk-go v1.35.23/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-xray-sdk-go v0.9.4/go.mod h1:XtMKdBQfpVut+tJEwI7+dJFRxxRdxHDyVNp2tHXRq04=
|
||||
@@ -217,7 +215,6 @@ github.com/bwmarrin/discordgo v0.20.2/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVO
|
||||
github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
|
||||
github.com/caddyserver/certmagic v0.10.6 h1:sCya6FmfaN74oZE46kqfaFOVoROD/mF36rTQfjN7TZc=
|
||||
github.com/caddyserver/certmagic v0.10.6/go.mod h1:Y8jcUBctgk/IhpAzlHKfimZNyXCkfGgRTC0orl8gROQ=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
@@ -233,7 +230,6 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
||||
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
|
||||
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/cheggaaa/pb v1.0.28/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30=
|
||||
@@ -295,7 +291,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/crewjam/httperr v0.0.0-20190612203328-a946449404da h1:WXnT88cFG2davqSFqvaFfzkSMC0lqh/8/rKZ+z7tYvI=
|
||||
github.com/crewjam/httperr v0.0.0-20190612203328-a946449404da/go.mod h1:+rmNIXRvYMqLQeR4DHyTvs6y0MEMymTz4vyFpFkKTPs=
|
||||
github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo=
|
||||
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
|
||||
@@ -305,20 +300,17 @@ github.com/cs3org/cato v0.0.0-20200626150132-28a40e643719/go.mod h1:XJEZ3/EQuI3B
|
||||
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20191128165347-19746c015c83/go.mod h1:IsVGyZrOLUQD48JIhlM/xb3Vz6He5o2+W0ZTfUGY+IU=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20200730121022-c4f3d4f7ddfd/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21 h1:mZpylrgnCgSeaZ5EznvHIPIKuaQHMHZDi2wkJtk4M8Y=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v0.0.2-0.20200115110931-4c7513415ec5/go.mod h1:Hk3eCcdhtv4eIhKvRK736fQuOyS1HuHnUcz0Dq6NK1A=
|
||||
github.com/cs3org/reva v1.1.0/go.mod h1:fBzTrNuAKdQ62ybjpdu8nyhBin90/3/3s6DGQDCdBp4=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5 h1:nkmk9ywGKpJthWeMYGBiXh4DD6mTCOZLRfGDjp9rsKg=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT524bvxACFkrkZqBzK4BoXLSprxcPshBlSOY=
|
||||
github.com/cs3org/reva v1.3.1-0.20201112131316-1c425035c8a2 h1:vBgCFcQMxcu7wDPo44Onw3ZXXZc3DrARz6V8rECZjVs=
|
||||
github.com/cs3org/reva v1.3.1-0.20201112131316-1c425035c8a2/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c h1:x7HkQqFGA+7FJUfyDO9tM2gF5i540PQePx+1kGUUYgA=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d h1:Sr6ZWGjTds5cWDei3mJev2+RPJ0iejKnVrYklr5mO+M=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b h1:Bypxdf3vXwyEeL86MMoPPuLbv4P979nkGsuTX6OQ0i8=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600 h1:4CKU+R4UNvILzsPrcAFwEbk/8Hc6vJqwO7SxK0gAm4I=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d h1:SwD98825d6bdB+pEuTxWOXiSjBrHdOl/UVp75eI7JT8=
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=
|
||||
@@ -1118,7 +1110,6 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
|
||||
github.com/nats-io/stan.go v0.5.0/go.mod h1:dYqB+vMN3C2F9pT1FRQpg9eHbjPj6mP0yYuyBNuXHZE=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/netdata/go-orchestrator v0.0.0-20190905093727-c793edba0e8f/go.mod h1:ECF8anFVCt/TfTIWVPgPrNaYJXtAtpAOF62ugDbw41A=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
@@ -1602,6 +1593,7 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -1783,7 +1775,6 @@ golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201022201747-fb209a7c41cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@@ -8,7 +8,7 @@ require (
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.1
|
||||
github.com/UnnoTed/fileb0x v1.1.4
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600
|
||||
github.com/go-chi/chi v4.1.2+incompatible
|
||||
github.com/go-chi/render v1.0.1
|
||||
github.com/golang/protobuf v1.4.3
|
||||
|
||||
@@ -204,6 +204,12 @@ github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d h1:8lqmft08fZJHoi/XG
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c h1:x7HkQqFGA+7FJUfyDO9tM2gF5i540PQePx+1kGUUYgA=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d h1:Sr6ZWGjTds5cWDei3mJev2+RPJ0iejKnVrYklr5mO+M=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b h1:Bypxdf3vXwyEeL86MMoPPuLbv4P979nkGsuTX6OQ0i8=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600 h1:4CKU+R4UNvILzsPrcAFwEbk/8Hc6vJqwO7SxK0gAm4I=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
||||
|
||||
@@ -8,7 +8,7 @@ require (
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.1
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/justinas/alice v1.2.0
|
||||
|
||||
@@ -199,6 +199,12 @@ github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d h1:8lqmft08fZJHoi/XG
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c h1:x7HkQqFGA+7FJUfyDO9tM2gF5i540PQePx+1kGUUYgA=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d h1:Sr6ZWGjTds5cWDei3mJev2+RPJ0iejKnVrYklr5mO+M=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b h1:Bypxdf3vXwyEeL86MMoPPuLbv4P979nkGsuTX6OQ0i8=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600 h1:4CKU+R4UNvILzsPrcAFwEbk/8Hc6vJqwO7SxK0gAm4I=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
||||
|
||||
@@ -2,12 +2,11 @@ package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/ocis-pkg/oidc"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const publicFilesEndpoint = "/remote.php/dav/public-files/"
|
||||
@@ -15,50 +14,49 @@ const publicFilesEndpoint = "/remote.php/dav/public-files/"
|
||||
// BasicAuth provides a middleware to check if BasicAuth is provided
|
||||
func BasicAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
|
||||
options := newOptions(optionSetters...)
|
||||
logger := options.Logger
|
||||
oidcIss := options.OIDCIss
|
||||
|
||||
if options.EnableBasicAuth {
|
||||
options.Logger.Warn().Msg("basic auth enabled, use only for testing or development")
|
||||
}
|
||||
|
||||
h := basicAuth{
|
||||
logger: logger,
|
||||
enabled: options.EnableBasicAuth,
|
||||
accountsClient: options.AccountsClient,
|
||||
}
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return &basicAuth{
|
||||
next: next,
|
||||
logger: options.Logger,
|
||||
enabled: options.EnableBasicAuth,
|
||||
accountsClient: options.AccountsClient,
|
||||
oidcIss: options.OIDCIss,
|
||||
}
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, req *http.Request) {
|
||||
if h.isPublicLink(req) || !h.isBasicAuth(req) {
|
||||
next.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
account, ok := h.getAccount(req)
|
||||
|
||||
if !ok {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
claims := &oidc.StandardClaims{
|
||||
OcisID: account.Id,
|
||||
Iss: oidcIss,
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, req.WithContext(oidc.NewContext(req.Context(), claims)))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
type basicAuth struct {
|
||||
next http.Handler
|
||||
logger log.Logger
|
||||
enabled bool
|
||||
accountsClient accounts.AccountsService
|
||||
oidcIss string
|
||||
}
|
||||
|
||||
func (m basicAuth) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if m.isPublicLink(req) || !m.isBasicAuth(req) {
|
||||
m.next.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
login, password, _ := req.BasicAuth()
|
||||
|
||||
account, status := getAccount(m.logger, m.accountsClient, fmt.Sprintf("login eq '%s' and password eq '%s'", strings.ReplaceAll(login, "'", "''"), strings.ReplaceAll(password, "'", "''")))
|
||||
|
||||
if status != 0 {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
claims := &oidc.StandardClaims{
|
||||
OcisID: account.Id,
|
||||
Iss: m.oidcIss,
|
||||
}
|
||||
|
||||
m.next.ServeHTTP(w, req.WithContext(oidc.NewContext(req.Context(), claims)))
|
||||
}
|
||||
|
||||
func (m basicAuth) isPublicLink(req *http.Request) bool {
|
||||
@@ -72,3 +70,19 @@ func (m basicAuth) isBasicAuth(req *http.Request) bool {
|
||||
|
||||
return m.enabled && ok && login != "" && password != ""
|
||||
}
|
||||
|
||||
func (m basicAuth) getAccount(req *http.Request) (*accounts.Account, bool) {
|
||||
login, password, _ := req.BasicAuth()
|
||||
|
||||
account, status := getAccount(
|
||||
m.logger,
|
||||
m.accountsClient,
|
||||
fmt.Sprintf(
|
||||
"login eq '%s' and password eq '%s'",
|
||||
strings.ReplaceAll(login, "'", "''"),
|
||||
strings.ReplaceAll(password, "'", "''"),
|
||||
),
|
||||
)
|
||||
|
||||
return account, status == 0
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
|
||||
gOidc "github.com/coreos/go-oidc"
|
||||
"github.com/owncloud/ocis/ocis-pkg/cache"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/ocis-pkg/oidc"
|
||||
"github.com/owncloud/ocis/proxy/pkg/cache"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
|
||||
@@ -194,12 +194,14 @@ github.com/cs3org/go-cs3apis v0.0.0-20200730121022-c4f3d4f7ddfd/go.mod h1:UXha4T
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20200810113633-b00aca449666/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.1.0 h1:Gih6ECHvMMGSx523SFluFlDmNMuhYelXYShdWvjvW38=
|
||||
github.com/cs3org/reva v1.1.0/go.mod h1:fBzTrNuAKdQ62ybjpdu8nyhBin90/3/3s6DGQDCdBp4=
|
||||
github.com/cs3org/reva v1.2.2-0.20200924071957-e6676516e61e/go.mod h1:DOV5SjpOBKN+aWfOHLdA4KiLQkpyC786PQaXEdRAZ0M=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5 h1:nkmk9ywGKpJthWeMYGBiXh4DD6mTCOZLRfGDjp9rsKg=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT524bvxACFkrkZqBzK4BoXLSprxcPshBlSOY=
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -3,7 +3,7 @@ module github.com/owncloud/ocis/storage
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600
|
||||
github.com/gofrs/uuid v3.3.0+incompatible
|
||||
github.com/micro/cli/v2 v2.1.2
|
||||
github.com/micro/go-micro/v2 v2.9.1
|
||||
|
||||
@@ -212,6 +212,12 @@ github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d h1:8lqmft08fZJHoi/XG
|
||||
github.com/cs3org/reva v1.4.1-0.20201123062044-b2c4af4e897d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c h1:x7HkQqFGA+7FJUfyDO9tM2gF5i540PQePx+1kGUUYgA=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125144025-57da0c27434c/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d h1:Sr6ZWGjTds5cWDei3mJev2+RPJ0iejKnVrYklr5mO+M=
|
||||
github.com/cs3org/reva v1.4.1-0.20201125172625-a5ab834a565d/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b h1:Bypxdf3vXwyEeL86MMoPPuLbv4P979nkGsuTX6OQ0i8=
|
||||
github.com/cs3org/reva v1.4.1-0.20201127111856-e6a6212c1b7b/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600 h1:4CKU+R4UNvILzsPrcAFwEbk/8Hc6vJqwO7SxK0gAm4I=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -225,12 +225,14 @@ github.com/cs3org/go-cs3apis v0.0.0-20200730121022-c4f3d4f7ddfd/go.mod h1:UXha4T
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20200810113633-b00aca449666/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.1.0 h1:Gih6ECHvMMGSx523SFluFlDmNMuhYelXYShdWvjvW38=
|
||||
github.com/cs3org/reva v1.1.0/go.mod h1:fBzTrNuAKdQ62ybjpdu8nyhBin90/3/3s6DGQDCdBp4=
|
||||
github.com/cs3org/reva v1.2.2-0.20200924071957-e6676516e61e/go.mod h1:DOV5SjpOBKN+aWfOHLdA4KiLQkpyC786PQaXEdRAZ0M=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5 h1:nkmk9ywGKpJthWeMYGBiXh4DD6mTCOZLRfGDjp9rsKg=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT524bvxACFkrkZqBzK4BoXLSprxcPshBlSOY=
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d h1:SwD98825d6bdB+pEuTxWOXiSjBrHdOl/UVp75eI7JT8=
|
||||
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=
|
||||
|
||||
@@ -1171,10 +1171,6 @@ apiWebdavOperations/downloadFile.feature:85
|
||||
apiWebdavOperations/refuseAccess.feature:21
|
||||
apiWebdavOperations/refuseAccess.feature:22
|
||||
#
|
||||
# https://github.com/owncloud/ocis/issues/751 PROPFIND to https://localhost:9200/remote.php/dav/files gets an error 500 response
|
||||
#
|
||||
apiWebdavOperations/propfind.feature:5
|
||||
#
|
||||
# https://github.com/owncloud/ocis-reva/issues/39 REPORT request not implemented
|
||||
#
|
||||
apiWebdavOperations/search.feature:42
|
||||
@@ -1640,8 +1636,6 @@ apiVersions/fileVersionsSharingToShares.feature:179
|
||||
#
|
||||
apiVersions/fileVersionsSharingToShares.feature:222
|
||||
apiVersions/fileVersionsSharingToShares.feature:223
|
||||
apiVersions/fileVersionsSharingToShares.feature:224
|
||||
apiVersions/fileVersionsSharingToShares.feature:225
|
||||
#
|
||||
# getting the metadata without permission results in a 403 error https://github.com/owncloud/ocis/issues/773
|
||||
#
|
||||
@@ -2474,3 +2468,25 @@ apiVersions/fileVersionsSharingToShares.feature:279
|
||||
# https://github.com/owncloud/ocis/issues/719 when a share exists its impossible to share a renamed folder
|
||||
apiShareManagementBasicToShares/createShareToSharesFolder.feature:611
|
||||
apiShareManagementBasicToShares/createShareToSharesFolder.feature:612
|
||||
|
||||
# https://github.com/owncloud/ocis/issues/965 ocis-storage does not use the mtime send in the `Upload-Metadata` header when uploading via TUS
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:17
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:18
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:27
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:28
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:38
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:39
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:49
|
||||
apiWebdavUploadTUS/uploadFileMtime.feature:50
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:40
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:41
|
||||
|
||||
# https://github.com/owncloud/ocis/issues/968 [ocis-storage] PROPFIND on a file uploaded by share receiver is not possible
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:26
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:27
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:55
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:56
|
||||
|
||||
# https://github.com/owncloud/ocis/issues/763 [OCIS-storage] reading a file that a collaborator uploaded is impossible
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:70
|
||||
apiWebdavUploadTUS/uploadFileMtimeShares.feature:71
|
||||
|
||||
@@ -1136,10 +1136,6 @@ apiWebdavOperations/downloadFile.feature:85
|
||||
apiWebdavOperations/refuseAccess.feature:21
|
||||
apiWebdavOperations/refuseAccess.feature:22
|
||||
#
|
||||
# https://github.com/owncloud/ocis/issues/751 PROPFIND to https://localhost:9200/remote.php/dav/files gets an error 500 response
|
||||
#
|
||||
apiWebdavOperations/propfind.feature:5
|
||||
#
|
||||
# https://github.com/owncloud/ocis-reva/issues/39 REPORT request not implemented
|
||||
#
|
||||
apiWebdavOperations/search.feature:42
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {sleep, check} from 'k6';
|
||||
import {Options} from "k6/options";
|
||||
import {defaults, api, utils} from "./lib";
|
||||
import {defaults, api} from "./lib";
|
||||
|
||||
const files = {
|
||||
'kb_50.jpg': open('./_files/kb_50.jpg', 'b'),
|
||||
@@ -13,10 +13,14 @@ export let options: Options = {
|
||||
};
|
||||
|
||||
export default () => {
|
||||
const res = api.uploadFile(defaults.accounts.einstein, files['kb_50.jpg'], `kb_50-${utils.randomString()}.jpg`)
|
||||
const res = api.uploadFile(
|
||||
defaults.accounts.einstein,
|
||||
files['kb_50.jpg'],
|
||||
`kb_50-${__VU}-${__ITER}.jpg`,
|
||||
);
|
||||
|
||||
check(res, {
|
||||
'status is 201': () => res.status === 201,
|
||||
'status is 204': () => res.status === 204,
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
|
||||
@@ -8,6 +8,7 @@ require (
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.1
|
||||
github.com/UnnoTed/fileb0x v1.1.4
|
||||
github.com/cespare/reflex v0.2.0
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21
|
||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31 // indirect
|
||||
github.com/gogo/protobuf v1.3.1 // indirect
|
||||
github.com/golang/protobuf v1.4.3
|
||||
@@ -31,7 +32,9 @@ require (
|
||||
github.com/stretchr/testify v1.6.1
|
||||
go.opencensus.io v0.22.5
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b
|
||||
google.golang.org/genproto v0.0.0-20200918140846-d0d605568037 // indirect
|
||||
google.golang.org/grpc v1.33.2
|
||||
gopkg.in/square/go-jose.v2 v2.5.1
|
||||
)
|
||||
|
||||
|
||||
@@ -202,12 +202,14 @@ github.com/cs3org/go-cs3apis v0.0.0-20200730121022-c4f3d4f7ddfd/go.mod h1:UXha4T
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20200810113633-b00aca449666/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.1.0 h1:Gih6ECHvMMGSx523SFluFlDmNMuhYelXYShdWvjvW38=
|
||||
github.com/cs3org/reva v1.1.0/go.mod h1:fBzTrNuAKdQ62ybjpdu8nyhBin90/3/3s6DGQDCdBp4=
|
||||
github.com/cs3org/reva v1.2.2-0.20200924071957-e6676516e61e/go.mod h1:DOV5SjpOBKN+aWfOHLdA4KiLQkpyC786PQaXEdRAZ0M=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5 h1:nkmk9ywGKpJthWeMYGBiXh4DD6mTCOZLRfGDjp9rsKg=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT524bvxACFkrkZqBzK4BoXLSprxcPshBlSOY=
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -1212,6 +1214,7 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
||||
@@ -2,6 +2,7 @@ package svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"image"
|
||||
|
||||
"gopkg.in/square/go-jose.v2/jwt"
|
||||
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
v0proto "github.com/owncloud/ocis/thumbnails/pkg/proto/v0"
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail"
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/imgsource"
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/resolution"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -18,19 +18,19 @@ import (
|
||||
func NewService(opts ...Option) v0proto.ThumbnailServiceHandler {
|
||||
options := newOptions(opts...)
|
||||
logger := options.Logger
|
||||
resolutions, err := resolution.New(options.Config.Thumbnail.Resolutions)
|
||||
resolutions, err := thumbnail.ParseResolutions(options.Config.Thumbnail.Resolutions)
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err).Msg("resolutions not configured correctly")
|
||||
}
|
||||
svc := Thumbnail{
|
||||
serviceID: options.Config.Server.Namespace + "." + options.Config.Server.Name,
|
||||
manager: thumbnail.NewSimpleManager(
|
||||
resolutions,
|
||||
options.ThumbnailStorage,
|
||||
logger,
|
||||
),
|
||||
resolutions: resolutions,
|
||||
source: options.ImageSource,
|
||||
logger: logger,
|
||||
source: options.ImageSource,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
return svc
|
||||
@@ -38,11 +38,10 @@ func NewService(opts ...Option) v0proto.ThumbnailServiceHandler {
|
||||
|
||||
// Thumbnail implements the GRPC handler.
|
||||
type Thumbnail struct {
|
||||
serviceID string
|
||||
manager thumbnail.Manager
|
||||
resolutions resolution.Resolutions
|
||||
source imgsource.Source
|
||||
logger log.Logger
|
||||
serviceID string
|
||||
manager thumbnail.Manager
|
||||
source imgsource.Source
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// GetThumbnail retrieves a thumbnail for an image
|
||||
@@ -52,7 +51,6 @@ func (g Thumbnail) GetThumbnail(ctx context.Context, req *v0proto.GetRequest, rs
|
||||
g.logger.Debug().Str("filetype", req.Filetype.String()).Msg("unsupported filetype")
|
||||
return nil
|
||||
}
|
||||
r := g.resolutions.ClosestMatch(int(req.Width), int(req.Height))
|
||||
|
||||
auth := req.Authorization
|
||||
if auth == "" {
|
||||
@@ -64,8 +62,7 @@ func (g Thumbnail) GetThumbnail(ctx context.Context, req *v0proto.GetRequest, rs
|
||||
}
|
||||
|
||||
tr := thumbnail.Request{
|
||||
Resolution: r,
|
||||
ImagePath: req.Filepath,
|
||||
Resolution: image.Rect(0, 0, int(req.Width), int(req.Height)),
|
||||
Encoder: encoder,
|
||||
ETag: req.Etag,
|
||||
Username: username,
|
||||
@@ -78,8 +75,8 @@ func (g Thumbnail) GetThumbnail(ctx context.Context, req *v0proto.GetRequest, rs
|
||||
return nil
|
||||
}
|
||||
|
||||
sCtx := imgsource.WithAuthorization(ctx, auth)
|
||||
img, err := g.source.Get(sCtx, tr.ImagePath)
|
||||
sCtx := imgsource.ContextSetAuthorization(ctx, auth)
|
||||
img, err := g.source.Get(sCtx, req.Filepath)
|
||||
if err != nil {
|
||||
return merrors.InternalServerError(g.serviceID, "could not get image from source: %v", err.Error())
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@ package imgsource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"image"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/config"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// NewFileSystemSource return a new FileSystem instance
|
||||
@@ -27,12 +27,12 @@ func (s FileSystem) Get(ctx context.Context, file string) (image.Image, error) {
|
||||
imgPath := filepath.Join(s.basePath, file)
|
||||
f, err := os.Open(filepath.Clean(imgPath))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load the file %s from %s error %s", file, imgPath, err.Error())
|
||||
return nil, errors.Wrapf(err, "failed to load the file %s from %s", file, imgPath)
|
||||
}
|
||||
|
||||
img, _, err := image.Decode(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "Get: Decode:")
|
||||
}
|
||||
|
||||
return img, nil
|
||||
|
||||
@@ -16,15 +16,16 @@ type Source interface {
|
||||
Get(ctx context.Context, path string) (image.Image, error)
|
||||
}
|
||||
|
||||
// WithAuthorization puts the authorization in the context.
|
||||
func WithAuthorization(parent context.Context, authorization string) context.Context {
|
||||
// ContextSetAuthorization puts the authorization in the context.
|
||||
func ContextSetAuthorization(parent context.Context, authorization string) context.Context {
|
||||
return context.WithValue(parent, auth, authorization)
|
||||
}
|
||||
|
||||
func authorization(ctx context.Context) string {
|
||||
// ContextGetAuthorization gets the authorization from the context.
|
||||
func ContextGetAuthorization(ctx context.Context) (string, bool) {
|
||||
val := ctx.Value(auth)
|
||||
if val == nil {
|
||||
return ""
|
||||
return "", false
|
||||
}
|
||||
return val.(string)
|
||||
return val.(string), true
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"path"
|
||||
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/config"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// NewWebDavSource creates a new webdav instance.
|
||||
@@ -32,13 +33,13 @@ func (s WebDav) Get(ctx context.Context, file string) (image.Image, error) {
|
||||
u.Path = path.Join(u.Path, file)
|
||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get the image \"%s\" error: %s", file, err.Error())
|
||||
return nil, errors.Wrapf(err, `could not get the image "%s"`, file)
|
||||
}
|
||||
|
||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: s.insecure}
|
||||
|
||||
auth := authorization(ctx)
|
||||
if auth == "" {
|
||||
auth, ok := ContextGetAuthorization(ctx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("could not get image \"%s\" error: authorization is missing", file)
|
||||
}
|
||||
req.Header.Add("Authorization", auth)
|
||||
@@ -46,7 +47,7 @@ func (s WebDav) Get(ctx context.Context, file string) (image.Image, error) {
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get the image \"%s\" error: %s", file, err.Error())
|
||||
return nil, errors.Wrapf(err, `could not get the image "%s"`, file)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
@@ -55,7 +56,7 @@ func (s WebDav) Get(ctx context.Context, file string) (image.Image, error) {
|
||||
|
||||
img, _, err := image.Decode(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not decode the image \"%s\". error: %s", file, err.Error())
|
||||
return nil, errors.Wrapf(err, `could not decode the image "%s"`, file)
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package resolution
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Parse parses a resolution string in the form <width>x<height> and returns a resolution instance.
|
||||
func Parse(s string) (Resolution, error) {
|
||||
parts := strings.Split(s, "x")
|
||||
if len(parts) != 2 {
|
||||
return Resolution{}, fmt.Errorf("failed to parse resolution: %s. Expected format <width>x<height>", s)
|
||||
}
|
||||
width, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return Resolution{}, fmt.Errorf("width: %s has an invalid value. Expected an integer", parts[0])
|
||||
}
|
||||
height, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return Resolution{}, fmt.Errorf("height: %s has an invalid value. Expected an integer", parts[1])
|
||||
}
|
||||
return Resolution{Width: width, Height: height}, nil
|
||||
}
|
||||
|
||||
// Resolution defines represents the width and height of a thumbnail.
|
||||
type Resolution struct {
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
||||
// String returns the resolution in the format:
|
||||
//
|
||||
// <width>x<height>
|
||||
func (r Resolution) String() string {
|
||||
return strconv.Itoa(r.Width) + "x" + strconv.Itoa(r.Height)
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package resolution
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseWithEmptyString(t *testing.T) {
|
||||
_, err := Parse("")
|
||||
if err == nil {
|
||||
t.Error("Parse with empty string should return an error.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseWithInvalidWidth(t *testing.T) {
|
||||
_, err := Parse("invalidx42")
|
||||
if err == nil {
|
||||
t.Error("Parse with invalid width should return an error.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseWithInvalidHeight(t *testing.T) {
|
||||
_, err := Parse("42xinvalid")
|
||||
if err == nil {
|
||||
t.Error("Parse with invalid height should return an error.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
rStr := "42x23"
|
||||
r, _ := Parse(rStr)
|
||||
if r.Width != 42 || r.Height != 23 {
|
||||
t.Errorf("Expected resolution %s got %s", rStr, r.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
r := Resolution{Width: 42, Height: 23}
|
||||
expected := "42x23"
|
||||
if r.String() != expected {
|
||||
t.Errorf("Expected string %s got %s", expected, r.String())
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package resolution
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// New creates an instance of Resolutions from resolution strings.
|
||||
func New(rStrs []string) (Resolutions, error) {
|
||||
var rs Resolutions
|
||||
for _, rStr := range rStrs {
|
||||
r, err := Parse(rStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize resolutions: %s", err.Error())
|
||||
}
|
||||
rs = append(rs, r)
|
||||
}
|
||||
sort.Slice(rs, func(i, j int) bool {
|
||||
left := rs[i]
|
||||
right := rs[j]
|
||||
|
||||
leftSize := left.Width * left.Height
|
||||
rightSize := right.Width * right.Height
|
||||
|
||||
return leftSize < rightSize
|
||||
})
|
||||
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
// Resolutions represents the available thumbnail resolutions.
|
||||
type Resolutions []Resolution
|
||||
|
||||
// ClosestMatch returns the resolution which is closest to the provided resolution.
|
||||
// If there is no exact match the resolution will be the next higher one.
|
||||
// If the given resolution is bigger than all available resolutions the biggest available one is used.
|
||||
func (r Resolutions) ClosestMatch(width, height int) Resolution {
|
||||
if len(r) == 0 {
|
||||
return Resolution{Width: width, Height: height}
|
||||
}
|
||||
|
||||
isLandscape := width > height
|
||||
givenLen := int(math.Max(float64(width), float64(height)))
|
||||
|
||||
// Initialize with the first resolution
|
||||
var match Resolution
|
||||
minDiff := math.MaxInt32
|
||||
|
||||
for _, current := range r {
|
||||
len := dimensionLength(current, isLandscape)
|
||||
diff := givenLen - len
|
||||
if diff > 0 {
|
||||
continue
|
||||
}
|
||||
absDiff := int(math.Abs(float64(diff)))
|
||||
if absDiff < minDiff {
|
||||
minDiff = absDiff
|
||||
match = current
|
||||
}
|
||||
}
|
||||
|
||||
if match == (Resolution{}) {
|
||||
match = r[len(r)-1]
|
||||
}
|
||||
return match
|
||||
}
|
||||
|
||||
func dimensionLength(r Resolution, landscape bool) int {
|
||||
if landscape {
|
||||
return r.Width
|
||||
}
|
||||
return r.Height
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package resolution
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInitWithEmptyArray(t *testing.T) {
|
||||
rs, err := New([]string{})
|
||||
if err != nil {
|
||||
t.Errorf("Init with an empty array should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != 0 {
|
||||
t.Error("Init with an empty array should return an empty Resolutions instance.\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitWithNil(t *testing.T) {
|
||||
rs, err := New(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Init with nil parameter should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != 0 {
|
||||
t.Error("Init with nil parameter should return an empty Resolutions instance.\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitWithInvalidValuesInArray(t *testing.T) {
|
||||
_, err := New([]string{"invalid"})
|
||||
if err == nil {
|
||||
t.Error("Init with invalid parameter should fail.\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
rs, err := New([]string{"16x16"})
|
||||
if err != nil {
|
||||
t.Errorf("Init with valid parameter should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != 1 {
|
||||
t.Errorf("resolutions has size %d, expected size %d.\n", len(rs), 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitWithMultipleResolutions(t *testing.T) {
|
||||
rStrs := []string{"16x16", "32x32", "64x64", "128x128"}
|
||||
rs, err := New(rStrs)
|
||||
if err != nil {
|
||||
t.Errorf("Init with valid parameter should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != len(rStrs) {
|
||||
t.Errorf("resolutions has size %d, expected size %d.\n", len(rs), len(rStrs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitWithMultipleResolutionsShouldBeSorted(t *testing.T) {
|
||||
rStrs := []string{"32x32", "64x64", "16x16", "128x128"}
|
||||
rs, err := New(rStrs)
|
||||
if err != nil {
|
||||
t.Errorf("Init with valid parameter should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
|
||||
for i := 0; i < len(rs)-1; i++ {
|
||||
current := rs[i]
|
||||
currentSize := current.Width * current.Height
|
||||
next := rs[i]
|
||||
nextSize := next.Width * next.Height
|
||||
|
||||
if currentSize > nextSize {
|
||||
t.Error("Resolutions are not sorted.")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
func TestClosestMatchWithEmptyResolutions(t *testing.T) {
|
||||
rs, _ := New(nil)
|
||||
width := 24
|
||||
height := 24
|
||||
|
||||
r := rs.ClosestMatch(width, height)
|
||||
if r.Width != width || r.Height != height {
|
||||
t.Errorf("ClosestMatch from empty resolutions should return the given resolution")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClosestMatch(t *testing.T) {
|
||||
rs, _ := New([]string{"16x16", "24x24", "32x32", "64x64", "128x128"})
|
||||
table := [][]int{
|
||||
// width, height, expectedWidth, expectedHeight
|
||||
[]int{17, 17, 24, 24},
|
||||
[]int{12, 17, 24, 24},
|
||||
[]int{24, 24, 24, 24},
|
||||
[]int{20, 20, 24, 24},
|
||||
[]int{20, 80, 128, 128},
|
||||
[]int{80, 20, 128, 128},
|
||||
[]int{48, 48, 64, 64},
|
||||
[]int{1024, 1024, 128, 128},
|
||||
}
|
||||
|
||||
for _, row := range table {
|
||||
width := row[0]
|
||||
height := row[1]
|
||||
expectedWidth := row[2]
|
||||
expectedHeight := row[3]
|
||||
|
||||
match := rs.ClosestMatch(width, height)
|
||||
|
||||
if match.Width != expectedWidth || match.Height != expectedHeight {
|
||||
t.Errorf("Expected resolution %dx%d got %s", expectedWidth, expectedHeight, match.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
110
thumbnails/pkg/thumbnail/resolutions.go
Normal file
110
thumbnails/pkg/thumbnail/resolutions.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_resolutionSeperator = "x"
|
||||
)
|
||||
|
||||
// ParseResolution returns an image.Rectangle representing the resolution given as a string
|
||||
func ParseResolution(s string) (image.Rectangle, error) {
|
||||
parts := strings.Split(s, _resolutionSeperator)
|
||||
if len(parts) != 2 {
|
||||
return image.Rectangle{}, fmt.Errorf("failed to parse resolution: %s. Expected format <width>x<height>", s)
|
||||
}
|
||||
width, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return image.Rectangle{}, fmt.Errorf("width: %s has an invalid value. Expected an integer", parts[0])
|
||||
}
|
||||
height, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return image.Rectangle{}, fmt.Errorf("height: %s has an invalid value. Expected an integer", parts[1])
|
||||
}
|
||||
return image.Rect(0, 0, width, height), nil
|
||||
}
|
||||
|
||||
// Resolutions is a list of image.Rectangle representing resolutions.
|
||||
type Resolutions []image.Rectangle
|
||||
|
||||
// ParseResolutions creates an instance of Resolutions from resolution strings.
|
||||
func ParseResolutions(strs []string) (Resolutions, error) {
|
||||
var rs Resolutions
|
||||
for _, s := range strs {
|
||||
r, err := ParseResolution(s)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not parse resolutions")
|
||||
}
|
||||
rs = append(rs, r)
|
||||
}
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
// ClosestMatch returns the resolution which is closest to the provided resolution.
|
||||
// If there is no exact match the resolution will be the next higher one.
|
||||
// If the given resolution is bigger than all available resolutions the biggest available one is used.
|
||||
func (rs Resolutions) ClosestMatch(requested image.Rectangle, sourceSize image.Rectangle) image.Rectangle {
|
||||
isLandscape := sourceSize.Dx() > sourceSize.Dy()
|
||||
sourceLen := dimensionLength(sourceSize, isLandscape)
|
||||
requestedLen := dimensionLength(requested, isLandscape)
|
||||
isSourceSmaller := sourceLen < requestedLen
|
||||
|
||||
// We don't want to scale images up.
|
||||
if isSourceSmaller {
|
||||
return sourceSize
|
||||
}
|
||||
|
||||
if len(rs) == 0 {
|
||||
return requested
|
||||
}
|
||||
|
||||
var match image.Rectangle
|
||||
// Since we want to search for the smallest difference we start with the highest possible number
|
||||
minDiff := math.MaxInt32
|
||||
|
||||
for _, current := range rs {
|
||||
cLen := dimensionLength(current, isLandscape)
|
||||
diff := requestedLen - cLen
|
||||
if diff > 0 {
|
||||
// current is smaller
|
||||
continue
|
||||
}
|
||||
|
||||
// Convert diff to positive value
|
||||
// Multiplying by -1 is safe since we aren't getting postive numbers here
|
||||
// because of the check above
|
||||
absDiff := diff * -1
|
||||
if absDiff < minDiff {
|
||||
minDiff = absDiff
|
||||
match = current
|
||||
}
|
||||
}
|
||||
|
||||
if (match == image.Rectangle{}) {
|
||||
match = rs[len(rs)-1]
|
||||
}
|
||||
return match
|
||||
}
|
||||
|
||||
func mapRatio(given image.Rectangle, other image.Rectangle) image.Rectangle {
|
||||
isLandscape := given.Dx() > given.Dy()
|
||||
ratio := float64(given.Dx()) / float64(given.Dy())
|
||||
if isLandscape {
|
||||
return image.Rect(0, 0, other.Dx(), int(float64(other.Dx())/ratio))
|
||||
}
|
||||
return image.Rect(0, 0, int(float64(other.Dy())*ratio), other.Dy())
|
||||
}
|
||||
|
||||
func dimensionLength(rect image.Rectangle, isLandscape bool) int {
|
||||
if isLandscape {
|
||||
return rect.Dx()
|
||||
}
|
||||
return rect.Dy()
|
||||
}
|
||||
139
thumbnails/pkg/thumbnail/resolutions_test.go
Normal file
139
thumbnails/pkg/thumbnail/resolutions_test.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
"image"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInitWithEmptyArray(t *testing.T) {
|
||||
rs, err := ParseResolutions([]string{})
|
||||
if err != nil {
|
||||
t.Errorf("Init with an empty array should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != 0 {
|
||||
t.Error("Init with an empty array should return an empty Resolutions instance.\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitWithNil(t *testing.T) {
|
||||
rs, err := ParseResolutions(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Init with nil parameter should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != 0 {
|
||||
t.Error("Init with nil parameter should return an empty Resolutions instance.\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitWithInvalidValuesInArray(t *testing.T) {
|
||||
_, err := ParseResolutions([]string{"invalid"})
|
||||
if err == nil {
|
||||
t.Error("Init with invalid parameter should fail.\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
rs, err := ParseResolutions([]string{"16x16"})
|
||||
if err != nil {
|
||||
t.Errorf("Init with valid parameter should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != 1 {
|
||||
t.Errorf("resolutions has size %d, expected size %d.\n", len(rs), 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitWithMultipleResolutions(t *testing.T) {
|
||||
rStrs := []string{"16x16", "32x32", "64x64", "128x128"}
|
||||
rs, err := ParseResolutions(rStrs)
|
||||
if err != nil {
|
||||
t.Errorf("Init with valid parameter should not fail. Error: %s.\n", err.Error())
|
||||
}
|
||||
if len(rs) != len(rStrs) {
|
||||
t.Errorf("resolutions has size %d, expected size %d.\n", len(rs), len(rStrs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestClosestMatchWithEmptyResolutions(t *testing.T) {
|
||||
rs, _ := ParseResolutions(nil)
|
||||
want := image.Rect(0, 0, 24, 24)
|
||||
imgSize := image.Rect(0, 0, 24, 24)
|
||||
|
||||
r := rs.ClosestMatch(want, imgSize)
|
||||
if r.Dx() != want.Dx() || r.Dy() != want.Dy() {
|
||||
t.Errorf("ClosestMatch from empty resolutions should return the given resolution")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClosestMatch(t *testing.T) {
|
||||
rs, _ := ParseResolutions([]string{"16x16", "24x24", "32x32", "64x64", "128x128"})
|
||||
|
||||
testData := [][]image.Rectangle{
|
||||
{image.Rect(0, 0, 17, 17), image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 24, 24)},
|
||||
{image.Rect(0, 0, 12, 17), image.Rect(0, 0, 1080, 1920), image.Rect(0, 0, 24, 24)},
|
||||
{image.Rect(0, 0, 24, 24), image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 24, 24)},
|
||||
{image.Rect(0, 0, 20, 20), image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 24, 24)},
|
||||
{image.Rect(0, 0, 20, 80), image.Rect(0, 0, 1080, 1920), image.Rect(0, 0, 128, 128)},
|
||||
{image.Rect(0, 0, 80, 20), image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 128, 128)},
|
||||
{image.Rect(0, 0, 48, 48), image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 64, 64)},
|
||||
{image.Rect(0, 0, 1024, 1024), image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 128, 128)},
|
||||
{image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 256, 36), image.Rect(0, 0, 256, 36)},
|
||||
}
|
||||
|
||||
for _, row := range testData {
|
||||
given := row[0]
|
||||
imgSize := row[1]
|
||||
expected := row[2]
|
||||
|
||||
match := rs.ClosestMatch(given, imgSize)
|
||||
|
||||
if match != expected {
|
||||
t.Errorf("Expected resolution %dx%d got %dx%d", expected.Dx(), expected.Dy(), match.Dx(), match.Dy())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseWithEmptyString(t *testing.T) {
|
||||
_, err := ParseResolution("")
|
||||
if err == nil {
|
||||
t.Error("Parse with empty string should return an error.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseWithInvalidWidth(t *testing.T) {
|
||||
_, err := ParseResolution("invalidx42")
|
||||
if err == nil {
|
||||
t.Error("Parse with invalid width should return an error.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseWithInvalidHeight(t *testing.T) {
|
||||
_, err := ParseResolution("42xinvalid")
|
||||
if err == nil {
|
||||
t.Error("Parse with invalid height should return an error.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseResolution(t *testing.T) {
|
||||
rStr := "42x23"
|
||||
r, _ := ParseResolution(rStr)
|
||||
if r.Dx() != 42 || r.Dy() != 23 {
|
||||
t.Errorf("Expected resolution %s got %s", rStr, r.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapRatio(t *testing.T) {
|
||||
testData := [][]image.Rectangle{
|
||||
{image.Rect(0, 0, 1920, 1080), image.Rect(0, 0, 32, 32), image.Rect(0, 0, 32, 18)},
|
||||
{image.Rect(0, 0, 1080, 1920), image.Rect(0, 0, 32, 32), image.Rect(0, 0, 18, 32)},
|
||||
{image.Rect(0, 0, 1024, 735), image.Rect(0, 0, 32, 32), image.Rect(0, 0, 32, 22)},
|
||||
}
|
||||
for _, row := range testData {
|
||||
given := row[0]
|
||||
other := row[1]
|
||||
expected := row[2]
|
||||
mapped := mapRatio(given, other)
|
||||
if mapped.Dx() != expected.Dx() || mapped.Dy() != expected.Dy() {
|
||||
t.Errorf("Expected %dx%d got %dx%d", expected.Dx(), expected.Dy(), mapped.Dx(), mapped.Dy())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -70,7 +71,7 @@ func (s *FileSystem) Set(username string, key string, img []byte) error {
|
||||
func (s *FileSystem) BuildKey(r Request) string {
|
||||
etag := r.ETag
|
||||
filetype := r.Types[0]
|
||||
filename := r.Resolution.String() + "." + filetype
|
||||
filename := strconv.Itoa(r.Resolution.Dx()) + "x" + strconv.Itoa(r.Resolution.Dy()) + "." + filetype
|
||||
|
||||
return filepath.Join(etag[:2], etag[2:4], etag[4:], filename)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package storage
|
||||
|
||||
import "github.com/owncloud/ocis/thumbnails/pkg/thumbnail/resolution"
|
||||
import (
|
||||
"image"
|
||||
)
|
||||
|
||||
// Request combines different attributes needed for storage operations.
|
||||
type Request struct {
|
||||
ETag string
|
||||
Types []string
|
||||
Resolution resolution.Resolution
|
||||
Resolution image.Rectangle
|
||||
}
|
||||
|
||||
// Storage defines the interface for a thumbnail store.
|
||||
|
||||
@@ -4,16 +4,14 @@ import (
|
||||
"bytes"
|
||||
"image"
|
||||
|
||||
"github.com/nfnt/resize"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/resolution"
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/storage"
|
||||
"golang.org/x/image/draw"
|
||||
)
|
||||
|
||||
// Request bundles information needed to generate a thumbnail for afile
|
||||
type Request struct {
|
||||
Resolution resolution.Resolution
|
||||
ImagePath string
|
||||
Resolution image.Rectangle
|
||||
Encoder Encoder
|
||||
ETag string
|
||||
Username string
|
||||
@@ -29,22 +27,25 @@ type Manager interface {
|
||||
}
|
||||
|
||||
// NewSimpleManager creates a new instance of SimpleManager
|
||||
func NewSimpleManager(storage storage.Storage, logger log.Logger) SimpleManager {
|
||||
func NewSimpleManager(resolutions Resolutions, storage storage.Storage, logger log.Logger) SimpleManager {
|
||||
return SimpleManager{
|
||||
storage: storage,
|
||||
logger: logger,
|
||||
storage: storage,
|
||||
logger: logger,
|
||||
resolutions: resolutions,
|
||||
}
|
||||
}
|
||||
|
||||
// SimpleManager is a simple implementation of Manager
|
||||
type SimpleManager struct {
|
||||
storage storage.Storage
|
||||
logger log.Logger
|
||||
storage storage.Storage
|
||||
logger log.Logger
|
||||
resolutions Resolutions
|
||||
}
|
||||
|
||||
// Get implements the Get Method of Manager
|
||||
func (s SimpleManager) Get(r Request, img image.Image) ([]byte, error) {
|
||||
thumbnail := s.generate(r, img)
|
||||
match := s.resolutions.ClosestMatch(r.Resolution, img.Bounds())
|
||||
thumbnail := s.generate(match, img)
|
||||
|
||||
key := s.storage.BuildKey(mapToStorageRequest(r))
|
||||
|
||||
@@ -69,8 +70,10 @@ func (s SimpleManager) GetStored(r Request) []byte {
|
||||
return stored
|
||||
}
|
||||
|
||||
func (s SimpleManager) generate(r Request, img image.Image) image.Image {
|
||||
thumbnail := resize.Thumbnail(uint(r.Resolution.Width), uint(r.Resolution.Height), img, resize.Lanczos2)
|
||||
func (s SimpleManager) generate(r image.Rectangle, img image.Image) image.Image {
|
||||
targetResolution := mapRatio(img.Bounds(), r)
|
||||
thumbnail := image.NewRGBA(targetResolution)
|
||||
draw.ApproxBiLinear.Scale(thumbnail, targetResolution, img, img.Bounds(), draw.Over, nil)
|
||||
return thumbnail
|
||||
}
|
||||
|
||||
47
thumbnails/pkg/thumbnail/thumbnail_test.go
Normal file
47
thumbnails/pkg/thumbnail/thumbnail_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
"image"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/thumbnails/pkg/thumbnail/storage"
|
||||
)
|
||||
|
||||
type NoOpManager struct {
|
||||
storage.Storage
|
||||
}
|
||||
|
||||
func (m NoOpManager) BuildKey(r storage.Request) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m NoOpManager) Set(username, key string, thumbnail []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func BenchmarkGet(b *testing.B) {
|
||||
|
||||
sut := NewSimpleManager(
|
||||
Resolutions{},
|
||||
NoOpManager{},
|
||||
log.NewLogger(),
|
||||
)
|
||||
|
||||
res, _ := ParseResolution("32x32")
|
||||
req := Request{
|
||||
Resolution: res,
|
||||
ETag: "1872ade88f3013edeb33decd74a4f947",
|
||||
}
|
||||
cwd, _ := os.Getwd()
|
||||
p := filepath.Join(cwd, "../../testdata/oc.png")
|
||||
f, _ := os.Open(p)
|
||||
defer f.Close()
|
||||
img, ext, _ := image.Decode(f)
|
||||
req.Encoder = EncoderForType(ext)
|
||||
for i := 0; i < b.N; i++ {
|
||||
sut.Get(req, img)
|
||||
}
|
||||
}
|
||||
@@ -202,12 +202,14 @@ github.com/cs3org/go-cs3apis v0.0.0-20200730121022-c4f3d4f7ddfd/go.mod h1:UXha4T
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20200810113633-b00aca449666/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00 h1:LVl25JaflluOchVvaHWtoCynm5OaM+VNai0IYkcCSe0=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201007120910-416ed6cf8b00/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20201118090759-87929f5bae21/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.1.0 h1:Gih6ECHvMMGSx523SFluFlDmNMuhYelXYShdWvjvW38=
|
||||
github.com/cs3org/reva v1.1.0/go.mod h1:fBzTrNuAKdQ62ybjpdu8nyhBin90/3/3s6DGQDCdBp4=
|
||||
github.com/cs3org/reva v1.2.2-0.20200924071957-e6676516e61e/go.mod h1:DOV5SjpOBKN+aWfOHLdA4KiLQkpyC786PQaXEdRAZ0M=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5 h1:nkmk9ywGKpJthWeMYGBiXh4DD6mTCOZLRfGDjp9rsKg=
|
||||
github.com/cs3org/reva v1.3.1-0.20201023144216-cdb3d6688da5/go.mod h1:V50GXMiT524bvxACFkrkZqBzK4BoXLSprxcPshBlSOY=
|
||||
github.com/cs3org/reva v1.4.1-0.20201120104232-f5afafc04c3b/go.mod h1:oqkkfe0g/dvrFFrmwd/VVfmrxhfswHp7+IB2PNeADSE=
|
||||
github.com/cs3org/reva v1.4.1-0.20201130061320-ac85e68e0600/go.mod h1:MTBlfobTE8W2hgXQ9+r+75jpJa1TxD04IZm5TpS9H48=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
Reference in New Issue
Block a user