mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-05 19:59:37 -06:00
Add 'ocis-pkg/' from commit '72d605ba3857d0b972ddd72e226d8a5360fb480d'
git-subtree-dir: ocis-pkg git-subtree-mainline:4c12bed11bgit-subtree-split:72d605ba38
This commit is contained in:
6
ocis-pkg/.codacy.yml
Normal file
6
ocis-pkg/.codacy.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
exclude_paths:
|
||||
- CHANGELOG.md
|
||||
- changelog/**
|
||||
|
||||
...
|
||||
282
ocis-pkg/.drone.star
Normal file
282
ocis-pkg/.drone.star
Normal file
@@ -0,0 +1,282 @@
|
||||
def main(ctx):
|
||||
stages = [
|
||||
testing(ctx),
|
||||
]
|
||||
|
||||
after = [
|
||||
changelog(ctx),
|
||||
publish(ctx),
|
||||
]
|
||||
|
||||
return stages + after
|
||||
|
||||
def testing(ctx):
|
||||
return {
|
||||
'kind': 'pipeline',
|
||||
'type': 'docker',
|
||||
'name': 'testing',
|
||||
'platform': {
|
||||
'os': 'linux',
|
||||
'arch': 'amd64',
|
||||
},
|
||||
'steps': [
|
||||
{
|
||||
'name': 'generate',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make generate',
|
||||
],
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'path': '/srv/app',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'vet',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make vet',
|
||||
],
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'path': '/srv/app',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'staticcheck',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make staticcheck',
|
||||
],
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'path': '/srv/app',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'lint',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make lint',
|
||||
],
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'path': '/srv/app',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'build',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make build',
|
||||
],
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'path': '/srv/app',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'test',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make test',
|
||||
],
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'path': '/srv/app',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'codacy',
|
||||
'image': 'plugins/codacy:1',
|
||||
'pull': 'always',
|
||||
'settings': {
|
||||
'token': {
|
||||
'from_secret': 'codacy_token',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
'volumes': [
|
||||
{
|
||||
'name': 'gopath',
|
||||
'temp': {},
|
||||
},
|
||||
],
|
||||
'trigger': {
|
||||
'ref': [
|
||||
'refs/heads/master',
|
||||
'refs/tags/**',
|
||||
'refs/pull/**',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
def changelog(ctx):
|
||||
repo_slug = ctx.build.source_repo if ctx.build.source_repo else ctx.repo.slug
|
||||
return {
|
||||
'kind': 'pipeline',
|
||||
'type': 'docker',
|
||||
'name': 'changelog',
|
||||
'platform': {
|
||||
'os': 'linux',
|
||||
'arch': 'amd64',
|
||||
},
|
||||
'clone': {
|
||||
'disable': True,
|
||||
},
|
||||
'steps': [
|
||||
{
|
||||
'name': 'clone',
|
||||
'image': 'plugins/git-action:1',
|
||||
'pull': 'always',
|
||||
'settings': {
|
||||
'actions': [
|
||||
'clone',
|
||||
],
|
||||
'remote': 'https://github.com/%s' % (repo_slug),
|
||||
'branch': ctx.build.source if ctx.build.event == 'pull_request' else 'master',
|
||||
'path': '/drone/src',
|
||||
'netrc_machine': 'github.com',
|
||||
'netrc_username': {
|
||||
'from_secret': 'github_username',
|
||||
},
|
||||
'netrc_password': {
|
||||
'from_secret': 'github_token',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
'name': 'generate',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'make changelog',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'diff',
|
||||
'image': 'owncloud/alpine:latest',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'git diff',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'output',
|
||||
'image': 'webhippie/golang:1.13',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'cat CHANGELOG.md',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'publish',
|
||||
'image': 'plugins/git-action:1',
|
||||
'pull': 'always',
|
||||
'settings': {
|
||||
'actions': [
|
||||
'commit',
|
||||
'push',
|
||||
],
|
||||
'message': 'Automated changelog update [skip ci]',
|
||||
'branch': 'master',
|
||||
'author_email': 'devops@owncloud.com',
|
||||
'author_name': 'ownClouders',
|
||||
'netrc_machine': 'github.com',
|
||||
'netrc_username': {
|
||||
'from_secret': 'github_username',
|
||||
},
|
||||
'netrc_password': {
|
||||
'from_secret': 'github_token',
|
||||
},
|
||||
},
|
||||
'when': {
|
||||
'ref': {
|
||||
'exclude': [
|
||||
'refs/pull/**',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
'depends_on': [
|
||||
'testing',
|
||||
],
|
||||
'trigger': {
|
||||
'ref': [
|
||||
'refs/heads/master',
|
||||
'refs/pull/**',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
def publish(ctx):
|
||||
return {
|
||||
'kind': 'pipeline',
|
||||
'type': 'docker',
|
||||
'name': 'publish',
|
||||
'platform': {
|
||||
'os': 'linux',
|
||||
'arch': 'amd64',
|
||||
},
|
||||
'steps': [
|
||||
{
|
||||
'name': 'prepare',
|
||||
'image': 'owncloud/alpine:latest',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'mkdir -p dist',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'changelog',
|
||||
'image': 'toolhippie/calens:latest',
|
||||
'pull': 'always',
|
||||
'commands': [
|
||||
'calens --version %s -o dist/CHANGELOG.md' % ctx.build.ref.replace("refs/tags/v", "").split("-")[0],
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'release',
|
||||
'image': 'plugins/github-release:1',
|
||||
'pull': 'always',
|
||||
'settings': {
|
||||
'api_key': {
|
||||
'from_secret': 'github_token',
|
||||
},
|
||||
'files': [],
|
||||
'title': ctx.build.ref.replace("refs/tags/v", ""),
|
||||
'note': 'dist/CHANGELOG.md',
|
||||
'overwrite': True,
|
||||
'prerelease': len(ctx.build.ref.split("-")) > 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
'depends_on': [
|
||||
'testing',
|
||||
],
|
||||
'trigger': {
|
||||
'ref': [
|
||||
'refs/tags/**',
|
||||
],
|
||||
},
|
||||
}
|
||||
35
ocis-pkg/.editorconfig
Normal file
35
ocis-pkg/.editorconfig
Normal file
@@ -0,0 +1,35 @@
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.starlark]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{yml,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{js,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{css,less}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = true
|
||||
12
ocis-pkg/.github/config.yml
vendored
Normal file
12
ocis-pkg/.github/config.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Configuration for update-docs - https://github.com/behaviorbot/update-docs
|
||||
|
||||
# Comment to be posted to on PRs that don't update documentation
|
||||
updateDocsComment: >
|
||||
Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a [changelog](https://github.com/owncloud/ocis-pkg/blob/master/changelog/README.md) item based on your changes.
|
||||
updateDocsWhiteList:
|
||||
- Tests-only
|
||||
- tests-only
|
||||
- Tests-Only
|
||||
|
||||
updateDocsTargetFiles:
|
||||
- changelog/unreleased/
|
||||
0
ocis-pkg/.github/issue_template.md
vendored
Normal file
0
ocis-pkg/.github/issue_template.md
vendored
Normal file
0
ocis-pkg/.github/pull_request_template.md
vendored
Normal file
0
ocis-pkg/.github/pull_request_template.md
vendored
Normal file
98
ocis-pkg/.github/settings.yml
vendored
Normal file
98
ocis-pkg/.github/settings.yml
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
---
|
||||
repository:
|
||||
name: ocis-pkg
|
||||
description: ':atom_symbol: Shared library for oCIS'
|
||||
homepage: http://godoc.org/github.com/owncloud/ocis-pkg/
|
||||
topics: reva, ocis
|
||||
|
||||
private: false
|
||||
has_issues: true
|
||||
has_projects: false
|
||||
has_wiki: false
|
||||
has_downloads: false
|
||||
|
||||
default_branch: master
|
||||
|
||||
allow_squash_merge: true
|
||||
allow_merge_commit: true
|
||||
allow_rebase_merge: true
|
||||
|
||||
labels:
|
||||
- name: bug
|
||||
color: d73a4a
|
||||
description: Something isn't working
|
||||
- name: documentation
|
||||
color: 0075ca
|
||||
description: Improvements or additions to documentation
|
||||
- name: duplicate
|
||||
color: cfd3d7
|
||||
description: This issue or pull request already exists
|
||||
- name: enhancement
|
||||
color: a2eeef
|
||||
description: New feature or request
|
||||
- name: good first issue
|
||||
color: 7057ff
|
||||
description: Good for newcomers
|
||||
- name: help wanted
|
||||
color: 008672
|
||||
description: Extra attention is needed
|
||||
- name: invalid
|
||||
color: e4e669
|
||||
description: This doesn't seem right
|
||||
- name: question
|
||||
color: d876e3
|
||||
description: Further information is requested
|
||||
- name: wontfix
|
||||
color: ffffff
|
||||
description: This will not be worked on
|
||||
- name: effort/trivial
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
- name: effort/0.25d
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
- name: effort/0.5d
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
- name: effort/1d
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
- name: effort/2d
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
- name: effort/4d
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
- name: effort/5d
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
- name: effort/10d
|
||||
color: c2e0c6
|
||||
description: Required effort to finish task
|
||||
|
||||
teams:
|
||||
- name: ci
|
||||
permission: admin
|
||||
- name: employees
|
||||
permission: push
|
||||
|
||||
branches:
|
||||
- name: master
|
||||
protection:
|
||||
required_pull_request_reviews:
|
||||
required_approving_review_count: 1
|
||||
dismiss_stale_reviews: false
|
||||
require_code_owner_reviews: false
|
||||
dismissal_restrictions: {}
|
||||
required_status_checks:
|
||||
strict: true
|
||||
contexts:
|
||||
- continuous-integration/drone/pr
|
||||
enforce_admins: false
|
||||
restrictions:
|
||||
users: []
|
||||
teams:
|
||||
- ci
|
||||
- employees
|
||||
|
||||
...
|
||||
1
ocis-pkg/.gitignore
vendored
Normal file
1
ocis-pkg/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
coverage.out
|
||||
318
ocis-pkg/CHANGELOG.md
Normal file
318
ocis-pkg/CHANGELOG.md
Normal file
@@ -0,0 +1,318 @@
|
||||
# Changelog for [unreleased] (UNRELEASED)
|
||||
|
||||
The following sections list the changes in ocis-pkg unreleased.
|
||||
|
||||
[unreleased]: https://github.com/owncloud/ocis-pkg/compare/v2.4.0...master
|
||||
|
||||
## Summary
|
||||
|
||||
* Change - Unwrap roleIDs from access-token into metadata context: [#59](https://github.com/owncloud/ocis-pkg/pull/59)
|
||||
* Change - Provide cache for roles: [#59](https://github.com/owncloud/ocis-pkg/pull/59)
|
||||
* Change - Roles manager: [#60](https://github.com/owncloud/ocis-pkg/pull/60)
|
||||
|
||||
## Details
|
||||
|
||||
* Change - Unwrap roleIDs from access-token into metadata context: [#59](https://github.com/owncloud/ocis-pkg/pull/59)
|
||||
|
||||
We pass the RoleIDs from the access-token into the metadata context.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/59
|
||||
|
||||
|
||||
* Change - Provide cache for roles: [#59](https://github.com/owncloud/ocis-pkg/pull/59)
|
||||
|
||||
In order to work efficiently with permissions we provide a cache for roles and a middleware to
|
||||
update the cache based on roleIDs from the metadata context. It can be used to check permissions
|
||||
in service handlers.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/59
|
||||
|
||||
|
||||
* Change - Roles manager: [#60](https://github.com/owncloud/ocis-pkg/pull/60)
|
||||
|
||||
We combined the roles middleware and cache into a roles manager. The manager doesn't expose the
|
||||
cache anymore and manages the state of the cache by fetching roles from the role service which
|
||||
don't exist in the cache, yet.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/60
|
||||
|
||||
# Changelog for [2.4.0] (2020-08-25)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.4.0.
|
||||
|
||||
[2.4.0]: https://github.com/owncloud/ocis-pkg/compare/v2.3.0...v2.4.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Change - Use go-micro's metadata context for account id: [#56](https://github.com/owncloud/ocis-pkg/pull/56)
|
||||
|
||||
## Details
|
||||
|
||||
* Change - Use go-micro's metadata context for account id: [#56](https://github.com/owncloud/ocis-pkg/pull/56)
|
||||
|
||||
We switched to using go-micro's metadata context for reliably passing the AccountID in the
|
||||
context across service boundaries.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/56
|
||||
|
||||
# Changelog for [2.3.0] (2020-08-17)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.3.0.
|
||||
|
||||
[2.3.0]: https://github.com/owncloud/ocis-pkg/compare/v2.2.1...v2.3.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Bugfix - Remove redigo 2.0.0+incompatible dependency: [#33](https://github.com/owncloud/ocis-graph/pull/33)
|
||||
* Change - Add middleware for x-access-token distmantling: [#46](https://github.com/owncloud/ocis-pkg/pull/46)
|
||||
* Enhancement - Add `ocis.id` and numeric id claims: [#50](https://github.com/owncloud/ocis-pkg/pull/50)
|
||||
|
||||
## Details
|
||||
|
||||
* Bugfix - Remove redigo 2.0.0+incompatible dependency: [#33](https://github.com/owncloud/ocis-graph/pull/33)
|
||||
|
||||
Get rid of redigo v2.0.0
|
||||
|
||||
https://github.com/owncloud/ocis-graph/pull/33
|
||||
|
||||
|
||||
* Change - Add middleware for x-access-token distmantling: [#46](https://github.com/owncloud/ocis-pkg/pull/46)
|
||||
|
||||
We added a middleware that dismantles the `x-access-token` from the request header and makes
|
||||
it available in the context.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/46
|
||||
|
||||
|
||||
* Enhancement - Add `ocis.id` and numeric id claims: [#50](https://github.com/owncloud/ocis-pkg/pull/50)
|
||||
|
||||
We added an `ocis.id` claim to the OIDC standard claims. It allows the idp to send a stable
|
||||
identifier that can be exposed to the outside world (in contrast to sub, which might change
|
||||
whens the IdP changes).
|
||||
|
||||
In addition we added `uidnumber` and `gidnumber` claims, which can be used by the IdP as well.
|
||||
They will be used by storage providers that integrate with an existing LDAP server.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/50
|
||||
|
||||
# Changelog for [2.2.1] (2020-04-21)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.2.1.
|
||||
|
||||
[2.2.1]: https://github.com/owncloud/ocis-pkg/compare/v2.2.0...v2.2.1
|
||||
|
||||
## Summary
|
||||
|
||||
* Bugfix - Pass flags to micro service: [#44](https://github.com/owncloud/ocis-pkg/pull/44)
|
||||
|
||||
## Details
|
||||
|
||||
* Bugfix - Pass flags to micro service: [#44](https://github.com/owncloud/ocis-pkg/pull/44)
|
||||
|
||||
Passed flags to the micro service to be able to pass cli arguments while starting a grpc service.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/44
|
||||
|
||||
# Changelog for [2.2.0] (2020-03-30)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.2.0.
|
||||
|
||||
[2.2.0]: https://github.com/owncloud/ocis-pkg/compare/v2.1.0...v2.2.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Change - Add header to cors handler: [#41](https://github.com/owncloud/ocis-pkg/issues/41)
|
||||
|
||||
## Details
|
||||
|
||||
* Change - Add header to cors handler: [#41](https://github.com/owncloud/ocis-pkg/issues/41)
|
||||
|
||||
The `x-requested-with` header was added to allow ajax requests.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/41
|
||||
|
||||
# Changelog for [2.1.0] (2020-03-16)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.1.0.
|
||||
|
||||
[2.1.0]: https://github.com/owncloud/ocis-pkg/compare/v2.0.2...v2.1.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Enhancement - Tracing middleware: [#35](https://github.com/owncloud/ocis-pkg/pull/35/)
|
||||
|
||||
## Details
|
||||
|
||||
* Enhancement - Tracing middleware: [#35](https://github.com/owncloud/ocis-pkg/pull/35/)
|
||||
|
||||
A new tracing middleware has been added to unpack context propagation
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/35/
|
||||
|
||||
# Changelog for [2.0.2] (2020-03-04)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.0.2.
|
||||
|
||||
[2.0.2]: https://github.com/owncloud/ocis-pkg/compare/v2.0.1...v2.0.2
|
||||
|
||||
## Summary
|
||||
|
||||
* Enhancement - Allow http services to register handlers: [#33](https://github.com/owncloud/ocis-pkg/pull/33)
|
||||
|
||||
## Details
|
||||
|
||||
* Enhancement - Allow http services to register handlers: [#33](https://github.com/owncloud/ocis-pkg/pull/33)
|
||||
|
||||
Added a handler option on http services
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/33
|
||||
|
||||
# Changelog for [2.0.1] (2020-02-05)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.0.1.
|
||||
|
||||
[2.0.1]: https://github.com/owncloud/ocis-pkg/compare/v2.0.0...v2.0.1
|
||||
|
||||
## Summary
|
||||
|
||||
* Bugfix - Fix Module Path: [#25](https://github.com/owncloud/ocis-pkg/pull/25)
|
||||
* Bugfix - Change import paths to ocis-pkg/v2: [#27](https://github.com/owncloud/ocis-pkg/pull/27)
|
||||
|
||||
## Details
|
||||
|
||||
* Bugfix - Fix Module Path: [#25](https://github.com/owncloud/ocis-pkg/pull/25)
|
||||
|
||||
The module version must be in the path. See
|
||||
https://github.com/golang/go/wiki/Modules#semantic-import-versioning for more
|
||||
information. > If the module is version v2 or higher, the major version of the module must be
|
||||
included as a /vN at the end of the module paths used in go.mod files (e.g., module
|
||||
github.com/my/mod/v2, require github.com/my/mod/v2 v2.0.1) and in the package import path
|
||||
(e.g., import "github.com/my/mod/v2/mypkg"). This includes the paths used in go get
|
||||
commands (e.g., go get github.com/my/mod/v2@v2.0.1. Note there is both a /v2 and a @v2.0.1 in
|
||||
that example. One way to think about it is that the module name now includes the /v2, so include
|
||||
/v2 whenever you are using the module name).
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/25
|
||||
|
||||
|
||||
* Bugfix - Change import paths to ocis-pkg/v2: [#27](https://github.com/owncloud/ocis-pkg/pull/27)
|
||||
|
||||
Changed the import paths to the current version
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/27
|
||||
|
||||
# Changelog for [2.0.0] (2020-02-04)
|
||||
|
||||
The following sections list the changes in ocis-pkg 2.0.0.
|
||||
|
||||
[2.0.0]: https://github.com/owncloud/ocis-pkg/compare/v1.3.0...v2.0.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Change - Upgrade the micro libraries: [#22](https://github.com/owncloud/ocis-pkg/pull/22)
|
||||
|
||||
## Details
|
||||
|
||||
* Change - Upgrade the micro libraries: [#22](https://github.com/owncloud/ocis-pkg/pull/22)
|
||||
|
||||
Upgraded the go-micro libraries to v2.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/22
|
||||
|
||||
# Changelog for [1.3.0] (2020-01-20)
|
||||
|
||||
The following sections list the changes in ocis-pkg 1.3.0.
|
||||
|
||||
[1.3.0]: https://github.com/owncloud/ocis-pkg/compare/v1.2.0...v1.3.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Bugfix - Fix serving static assets: [#14](https://github.com/owncloud/ocis-pkg/pull/14)
|
||||
* Change - Add TLS support for http services: [#19](https://github.com/owncloud/ocis-pkg/issues/19)
|
||||
* Enhancement - Introduce OpenID Connect middleware: [#8](https://github.com/owncloud/ocis-pkg/issues/8)
|
||||
|
||||
## Details
|
||||
|
||||
* Bugfix - Fix serving static assets: [#14](https://github.com/owncloud/ocis-pkg/pull/14)
|
||||
|
||||
Ocis-hello used "/" as root. adding another / caused the static middleware to always fail
|
||||
stripping that prefix. All requests will return 404. Setting root to `""` in the `ocis-hello`
|
||||
flag does not work because Chi reports that routes need to start with `/`.
|
||||
`path.Clean(root+"/")` would yield `""` for `root="/"`.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/14
|
||||
|
||||
|
||||
* Change - Add TLS support for http services: [#19](https://github.com/owncloud/ocis-pkg/issues/19)
|
||||
|
||||
`ocis-pkg` http services support TLS. The idea behind is setting the issuer on phoenix's
|
||||
`config.json` to `https`. Or in other words, use https to access the Kopano extension, and
|
||||
authenticate using an SSL certificate.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/19
|
||||
|
||||
|
||||
* Enhancement - Introduce OpenID Connect middleware: [#8](https://github.com/owncloud/ocis-pkg/issues/8)
|
||||
|
||||
Added an openid connect middleware that will try to authenticate users using OpenID Connect.
|
||||
The claims will be added to the context of the request.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/8
|
||||
|
||||
# Changelog for [1.2.0] (2019-12-09)
|
||||
|
||||
The following sections list the changes in ocis-pkg 1.2.0.
|
||||
|
||||
[1.2.0]: https://github.com/owncloud/ocis-pkg/compare/v1.1.0...v1.2.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Change - Add root path to static middleware: [#9](https://github.com/owncloud/ocis-pkg/issues/9)
|
||||
|
||||
## Details
|
||||
|
||||
* Change - Add root path to static middleware: [#9](https://github.com/owncloud/ocis-pkg/issues/9)
|
||||
|
||||
Currently the `Static` middleware always serves from the root path, but all our HTTP handlers
|
||||
accept a custom root path which also got to be applied to the static file handling.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/9
|
||||
|
||||
# Changelog for [1.1.0] (2019-12-06)
|
||||
|
||||
The following sections list the changes in ocis-pkg 1.1.0.
|
||||
|
||||
[1.1.0]: https://github.com/owncloud/ocis-pkg/compare/v1.0.0...v1.1.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Change - Better log level handling within micro: [#2](https://github.com/owncloud/ocis-pkg/issues/2)
|
||||
|
||||
## Details
|
||||
|
||||
* Change - Better log level handling within micro: [#2](https://github.com/owncloud/ocis-pkg/issues/2)
|
||||
|
||||
Currently every log message from the micro internals are logged with the info level, we really
|
||||
need to respect the proper defined log level within our log wrapper package.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/2
|
||||
|
||||
# Changelog for [1.0.0] (2019-12-05)
|
||||
|
||||
The following sections list the changes in ocis-pkg 1.0.0.
|
||||
|
||||
[1.0.0]: https://github.com/owncloud/ocis-pkg/compare/63fa90a673cbc3238a503ea5e6304f1db7fdf47b...v1.0.0
|
||||
|
||||
## Summary
|
||||
|
||||
* Change - Initial release of basic version: [#1](https://github.com/owncloud/ocis-pkg/issues/1)
|
||||
|
||||
## Details
|
||||
|
||||
* Change - Initial release of basic version: [#1](https://github.com/owncloud/ocis-pkg/issues/1)
|
||||
|
||||
Just prepared an initial basic version to have some shared functionality published which can
|
||||
be used by all other ownCloud Infinite Scale extensions.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/1
|
||||
|
||||
202
ocis-pkg/LICENSE
Normal file
202
ocis-pkg/LICENSE
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
70
ocis-pkg/Makefile
Normal file
70
ocis-pkg/Makefile
Normal file
@@ -0,0 +1,70 @@
|
||||
SHELL := bash
|
||||
NAME := ocis-pkg
|
||||
IMPORT := github.com/owncloud/$(NAME)
|
||||
BIN := bin
|
||||
DIST := dist
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
UNAME := Windows
|
||||
else
|
||||
UNAME := $(shell uname -s)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
GOBUILD ?= go build -i
|
||||
else
|
||||
GOBUILD ?= go build
|
||||
endif
|
||||
|
||||
PACKAGES ?= $(shell go list ./...)
|
||||
SOURCES ?= $(shell find . -name "*.go" -type f)
|
||||
GENERATE ?= $(PACKAGES)
|
||||
|
||||
TAGS ?=
|
||||
|
||||
LDFLAGS += -s -w
|
||||
GCFLAGS += all=-N -l
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
.PHONY: sync
|
||||
sync:
|
||||
go mod download
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
go clean -i ./...
|
||||
rm -rf $(BIN) $(DIST)
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
gofmt -s -w $(SOURCES)
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
go vet $(PACKAGES)
|
||||
|
||||
.PHONY: staticcheck
|
||||
staticcheck:
|
||||
go run honnef.co/go/tools/cmd/staticcheck -tags '$(TAGS)' $(PACKAGES)
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
for PKG in $(PACKAGES); do go run golang.org/x/lint/golint -set_exit_status $$PKG || exit 1; done;
|
||||
|
||||
.PHONY: generate
|
||||
generate:
|
||||
go generate $(GENERATE)
|
||||
|
||||
.PHONY: changelog
|
||||
changelog:
|
||||
go run github.com/restic/calens >| CHANGELOG.md
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go run github.com/haya14busa/goverage -v -coverprofile coverage.out $(PACKAGES)
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./...
|
||||
45
ocis-pkg/README.md
Normal file
45
ocis-pkg/README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# ownCloud Infinite Scale: Pkg
|
||||
|
||||
[](https://cloud.drone.io/owncloud/ocis-pkg)
|
||||
[](https://gitter.im/cs3org/reva)
|
||||
[](https://www.codacy.com/manual/owncloud/ocis-pkg?utm_source=github.com&utm_medium=referral&utm_content=owncloud/ocis-pkg&utm_campaign=Badge_Grade)
|
||||
[](http://godoc.org/github.com/owncloud/ocis-pkg)
|
||||
[](http://goreportcard.com/report/github.com/owncloud/ocis-pkg)
|
||||
|
||||
This package defines some boilerplate code that reduces the code duplication within the ownCloud Infinite Scale microservice architecture. It can't be used standalone as the is a pure library. For further information about the available packages please read the source code or take a loog at [GoDoc](http://godoc.org/github.com/owncloud/ocis-pkg).
|
||||
|
||||
## Install
|
||||
|
||||
Import the required packages within your ownCloud Infinite Scale extensions and you are good to go.
|
||||
|
||||
## Development
|
||||
|
||||
Make sure you have a working Go environment, for further reference or a guide take a look at the [install instructions](http://golang.org/doc/install.html). This project requires Go >= v1.13.
|
||||
|
||||
```console
|
||||
git clone https://github.com/owncloud/ocis-pkg.git
|
||||
cd ocis-pkg
|
||||
|
||||
make vet
|
||||
make staticcheck
|
||||
make lint
|
||||
make test
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
If you find a security issue please contact security@owncloud.com first.
|
||||
|
||||
## Contributing
|
||||
|
||||
Fork -> Patch -> Push -> Pull Request
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
|
||||
## Copyright
|
||||
|
||||
```console
|
||||
Copyright (c) 2019 ownCloud GmbH <https://owncloud.com>
|
||||
```
|
||||
30
ocis-pkg/account/option.go
Normal file
30
ocis-pkg/account/option.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
// Logger to use for logging, must be set
|
||||
Logger log.Logger
|
||||
// JWTSecret is the jwt secret for the reva token manager
|
||||
JWTSecret string
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(l log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = l
|
||||
}
|
||||
}
|
||||
|
||||
// JWTSecret provides a function to set the jwt secret option.
|
||||
func JWTSecret(s string) Option {
|
||||
return func(o *Options) {
|
||||
o.JWTSecret = s
|
||||
}
|
||||
}
|
||||
6
ocis-pkg/changelog/1.0.0_2019-12-05/initial-release.md
Normal file
6
ocis-pkg/changelog/1.0.0_2019-12-05/initial-release.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Change: Initial release of basic version
|
||||
|
||||
Just prepared an initial basic version to have some shared functionality
|
||||
published which can be used by all other ownCloud Infinite Scale extensions.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/1
|
||||
@@ -0,0 +1,7 @@
|
||||
Change: Better log level handling within micro
|
||||
|
||||
Currently every log message from the micro internals are logged with the info
|
||||
level, we really need to respect the proper defined log level within our log
|
||||
wrapper package.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/2
|
||||
7
ocis-pkg/changelog/1.2.0_2019-12-09/static-root-path.md
Normal file
7
ocis-pkg/changelog/1.2.0_2019-12-09/static-root-path.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Change: Add root path to static middleware
|
||||
|
||||
Currently the `Static` middleware always serves from the root path, but all our
|
||||
HTTP handlers accept a custom root path which also got to be applied to the
|
||||
static file handling.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/9
|
||||
@@ -0,0 +1,8 @@
|
||||
Bugfix: Fix serving static assets
|
||||
|
||||
ocis-hello used "/" as root. adding another / caused the static middleware to
|
||||
always fail stripping that prefix. All requests will return 404. Setting root
|
||||
to `""` in the `ocis-hello` flag does not work because Chi reports that routes
|
||||
need to start with `/`. `path.Clean(root+"/")` would yield `""` for `root="/"`.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/14
|
||||
6
ocis-pkg/changelog/1.3.0_2020-01-20/issue-8.md
Normal file
6
ocis-pkg/changelog/1.3.0_2020-01-20/issue-8.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Enhancement: Introduce OpenID Connect middleware
|
||||
|
||||
Added an openid connect middleware that will try to authenticate users using
|
||||
OpenID Connect. The claims will be added to the context of the request.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/8
|
||||
@@ -0,0 +1,7 @@
|
||||
Change: Add TLS support for http services
|
||||
|
||||
`ocis-pkg` http services support TLS. The idea behind is setting the issuer on
|
||||
phoenix's `config.json` to `https`. Or in other words, use https to access the
|
||||
Kopano extension, and authenticate using an SSL certificate.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/19
|
||||
5
ocis-pkg/changelog/2.0.0_2020-02-04/micro-cli-v2.md
Normal file
5
ocis-pkg/changelog/2.0.0_2020-02-04/micro-cli-v2.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Change: upgrade the micro libraries
|
||||
|
||||
Upgraded the go-micro libraries to v2.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/22
|
||||
@@ -0,0 +1,6 @@
|
||||
Bugfix: Fix Module Path
|
||||
|
||||
The module version must be in the path. See https://github.com/golang/go/wiki/Modules#semantic-import-versioning for more information.
|
||||
> If the module is version v2 or higher, the major version of the module must be included as a /vN at the end of the module paths used in go.mod files (e.g., module github.com/my/mod/v2, require github.com/my/mod/v2 v2.0.1) and in the package import path (e.g., import "github.com/my/mod/v2/mypkg"). This includes the paths used in go get commands (e.g., go get github.com/my/mod/v2@v2.0.1. Note there is both a /v2 and a @v2.0.1 in that example. One way to think about it is that the module name now includes the /v2, so include /v2 whenever you are using the module name).
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/25
|
||||
5
ocis-pkg/changelog/2.0.1_2020-02-05/correct-imports.md
Normal file
5
ocis-pkg/changelog/2.0.1_2020-02-05/correct-imports.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Bugfix: change import paths to ocis-pkg/v2
|
||||
|
||||
Changed the import paths to the current version
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/27
|
||||
@@ -0,0 +1,5 @@
|
||||
Enhancement: Allow http services to register handlers
|
||||
|
||||
Added a handler option on http services
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/33
|
||||
@@ -0,0 +1,5 @@
|
||||
Enhancement: Tracing middleware
|
||||
|
||||
A new tracing middleware has been added to unpack context propagation
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/35/
|
||||
@@ -0,0 +1,5 @@
|
||||
Change: Add header to cors handler
|
||||
|
||||
The `x-requested-with` header was added to allow ajax requests.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/41
|
||||
5
ocis-pkg/changelog/2.2.1_2020-04-21/fix-micro-options.md
Normal file
5
ocis-pkg/changelog/2.2.1_2020-04-21/fix-micro-options.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Bugfix: pass flags to micro service
|
||||
|
||||
Passed flags to the micro service to be able to pass cli arguments while starting a grpc service.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/44
|
||||
@@ -0,0 +1,6 @@
|
||||
Change: add middleware for x-access-token distmantling
|
||||
|
||||
We added a middleware that dismantles the `x-access-token` from the request header and makes
|
||||
it available in the context.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/46
|
||||
7
ocis-pkg/changelog/2.3.0_2020-08-17/add-ocisid-claim.md
Normal file
7
ocis-pkg/changelog/2.3.0_2020-08-17/add-ocisid-claim.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Enhancement: add `ocis.id` and numeric id claims
|
||||
|
||||
We added an `ocis.id` claim to the OIDC standard claims. It allows the idp to send a stable identifier that can be exposed to the outside world (in contrast to sub, which might change whens the IdP changes).
|
||||
|
||||
In addition we added `uidnumber` and `gidnumber` claims, which can be used by the IdP as well. They will be used by storage providers that integrate with an existing LDAP server.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/50
|
||||
5
ocis-pkg/changelog/2.3.0_2020-08-17/remove-redigo.md
Normal file
5
ocis-pkg/changelog/2.3.0_2020-08-17/remove-redigo.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Bugfix: remove redigo 2.0.0+incompatible dependency
|
||||
|
||||
get rid of redigo v2.0.0
|
||||
|
||||
https://github.com/owncloud/ocis-graph/pull/33
|
||||
6
ocis-pkg/changelog/2.4.0_2020-08-25/metadata-context.md
Normal file
6
ocis-pkg/changelog/2.4.0_2020-08-25/metadata-context.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Change: use go-micro's metadata context for account id
|
||||
|
||||
We switched to using go-micro's metadata context for reliably passing the AccountID in the context
|
||||
across service boundaries.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/56
|
||||
53
ocis-pkg/changelog/CHANGELOG.tmpl
Normal file
53
ocis-pkg/changelog/CHANGELOG.tmpl
Normal file
@@ -0,0 +1,53 @@
|
||||
{{ $allVersions := . }}
|
||||
{{- range $index, $changes := . }}{{ with $changes -}}
|
||||
{{ if gt (len $allVersions) 1 -}}
|
||||
# Changelog for [{{ .Version }}] ({{ .Date }})
|
||||
|
||||
The following sections list the changes in ocis-pkg {{ .Version }}.
|
||||
|
||||
{{/* creating version compare links */ -}}
|
||||
{{ $next := add1 $index -}}
|
||||
{{ if ne (len $allVersions) $next -}}
|
||||
{{ $previousVersion := (index $allVersions $next).Version -}}
|
||||
{{ if eq .Version "unreleased" -}}
|
||||
[{{ .Version }}]: https://github.com/owncloud/ocis-pkg/compare/v{{ $previousVersion }}...master
|
||||
|
||||
{{ else -}}
|
||||
[{{ .Version }}]: https://github.com/owncloud/ocis-pkg/compare/v{{ $previousVersion }}...v{{ .Version }}
|
||||
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- /* last version managed by calens, end of the loop */ -}}
|
||||
{{ if eq .Version "1.0.0" -}}
|
||||
[{{ .Version }}]: https://github.com/owncloud/ocis-pkg/compare/63fa90a673cbc3238a503ea5e6304f1db7fdf47b...v{{ .Version }}
|
||||
|
||||
{{ end -}}
|
||||
{{ else -}}
|
||||
# Changes in {{ .Version }}
|
||||
|
||||
{{ end -}}
|
||||
|
||||
## Summary
|
||||
{{ range $entry := .Entries }}{{ with $entry }}
|
||||
* {{ .Type }} - {{ .Title }}: [#{{ .PrimaryID }}]({{ .PrimaryURL }})
|
||||
{{- end }}{{ end }}
|
||||
|
||||
## Details
|
||||
{{ range $entry := .Entries }}{{ with $entry }}
|
||||
* {{ .Type }} - {{ .Title }}: [#{{ .PrimaryID }}]({{ .PrimaryURL }})
|
||||
{{ range $par := .Paragraphs }}
|
||||
{{ wrapIndent $par 80 3 }}
|
||||
{{ end -}}
|
||||
{{ range $url := .IssueURLs }}
|
||||
{{ $url -}}
|
||||
{{ end -}}
|
||||
{{ range $url := .PRURLs }}
|
||||
{{ $url -}}
|
||||
{{ end -}}
|
||||
{{ range $url := .OtherURLs }}
|
||||
{{ $url -}}
|
||||
{{ end }}
|
||||
|
||||
{{ end }}{{ end -}}
|
||||
{{ end }}{{ end -}}
|
||||
10
ocis-pkg/changelog/README.md
Normal file
10
ocis-pkg/changelog/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
We are using [calens](https://github.com/restic/calens) to properly generate a
|
||||
changelog before we are tagging a new release. To get an idea how this could
|
||||
look like <https://github.com/restic/restic/tree/master/changelog> would be the
|
||||
best reference.
|
||||
|
||||
We're using kebab case for naming the changelog files:
|
||||
|
||||
`kebab-case-looks-like-this`
|
||||
11
ocis-pkg/changelog/TEMPLATE
Normal file
11
ocis-pkg/changelog/TEMPLATE
Normal file
@@ -0,0 +1,11 @@
|
||||
Bugfix: Fix behavior for foobar (in present tense)
|
||||
|
||||
We've fixed the behavior for foobar, a long-standing annoyance for users. The
|
||||
text should be wrapped at 80 characters length.
|
||||
|
||||
The text in the paragraphs is written in past tense. The last section is a list
|
||||
of issue URLs, PR URLs and other URLs. The first issue ID (or the first PR ID,
|
||||
in case there aren't any issue links) is used as the primary ID.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/issues/1234
|
||||
https://github.com/owncloud/ocis-pkg/pull/55555
|
||||
0
ocis-pkg/changelog/unreleased/.keep
Normal file
0
ocis-pkg/changelog/unreleased/.keep
Normal file
5
ocis-pkg/changelog/unreleased/role-ids-from-context.md
Normal file
5
ocis-pkg/changelog/unreleased/role-ids-from-context.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Change: Unwrap roleIDs from access-token into metadata context
|
||||
|
||||
We pass the RoleIDs from the access-token into the metadata context.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/59
|
||||
7
ocis-pkg/changelog/unreleased/roles-cache.md
Normal file
7
ocis-pkg/changelog/unreleased/roles-cache.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Change: Provide cache for roles
|
||||
|
||||
In order to work efficiently with permissions we provide a cache for roles and a
|
||||
middleware to update the cache based on roleIDs from the metadata context. It can be
|
||||
used to check permissions in service handlers.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/59
|
||||
6
ocis-pkg/changelog/unreleased/roles-manager.md
Normal file
6
ocis-pkg/changelog/unreleased/roles-manager.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Change: Roles manager
|
||||
|
||||
We combined the roles middleware and cache into a roles manager. The manager doesn't expose the cache anymore and manages
|
||||
the state of the cache by fetching roles from the role service which don't exist in the cache, yet.
|
||||
|
||||
https://github.com/owncloud/ocis-pkg/pull/60
|
||||
14
ocis-pkg/conversions/strings.go
Normal file
14
ocis-pkg/conversions/strings.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package conversions
|
||||
|
||||
import "strings"
|
||||
|
||||
// StringToSliceString splits a string into a slice string according to separator
|
||||
func StringToSliceString(src string, sep string) []string {
|
||||
var parts []string
|
||||
parsed := strings.Split(src, sep)
|
||||
for _, v := range parsed {
|
||||
parts = append(parts, strings.TrimSpace(v))
|
||||
}
|
||||
|
||||
return parts
|
||||
}
|
||||
35
ocis-pkg/conversions/strings_test.go
Normal file
35
ocis-pkg/conversions/strings_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package conversions
|
||||
|
||||
import "testing"
|
||||
|
||||
var scenarios = []struct {
|
||||
name string
|
||||
input string
|
||||
separator string
|
||||
out []string
|
||||
}{
|
||||
{
|
||||
"comma separated input",
|
||||
"a, b, c, d",
|
||||
",",
|
||||
[]string{"a", "b", "c", "d"},
|
||||
}, {
|
||||
"space separated input",
|
||||
"a b c d",
|
||||
" ",
|
||||
[]string{"a", "b", "c", "d"},
|
||||
},
|
||||
}
|
||||
|
||||
func TestStringToSliceString(t *testing.T) {
|
||||
for _, tt := range scenarios {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := StringToSliceString(tt.input, tt.separator)
|
||||
for i, v := range tt.out {
|
||||
if tt.out[i] != v {
|
||||
t.Errorf("got %q, want %q", s, tt.out)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
26
ocis-pkg/go.mod
Normal file
26
ocis-pkg/go.mod
Normal file
@@ -0,0 +1,26 @@
|
||||
module github.com/owncloud/ocis-pkg/v2
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/ascarter/requestid v0.0.0-20170313220838-5b76ab3d4aee
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/cs3org/reva v1.1.0
|
||||
github.com/go-chi/chi v4.1.2+incompatible
|
||||
github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5
|
||||
github.com/justinas/alice v1.2.0
|
||||
github.com/micro/cli/v2 v2.1.2
|
||||
github.com/micro/go-micro/v2 v2.9.1
|
||||
github.com/micro/go-plugins/wrapper/trace/opencensus/v2 v2.9.1
|
||||
github.com/owncloud/ocis-settings v0.3.2-0.20200828091056-47af10a0e872
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/restic/calens v0.2.0
|
||||
github.com/rs/zerolog v1.19.0
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
||||
go.opencensus.io v0.22.4
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
honnef.co/go/tools v0.0.1-2020.1.5
|
||||
)
|
||||
|
||||
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
|
||||
1405
ocis-pkg/go.sum
Normal file
1405
ocis-pkg/go.sum
Normal file
File diff suppressed because it is too large
Load Diff
172
ocis-pkg/log/log.go
Normal file
172
ocis-pkg/log/log.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mdlog "github.com/micro/go-micro/v2/debug/log"
|
||||
mlog "github.com/micro/go-micro/v2/util/log"
|
||||
"github.com/micro/go-micro/v2/util/ring"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Logger simply wraps the zerolog logger.
|
||||
type Logger struct {
|
||||
zerolog.Logger
|
||||
}
|
||||
|
||||
// NewLogger initializes a new logger instance.
|
||||
func NewLogger(opts ...Option) Logger {
|
||||
options := newOptions(opts...)
|
||||
|
||||
switch strings.ToLower(options.Level) {
|
||||
case "panic":
|
||||
zerolog.SetGlobalLevel(zerolog.PanicLevel)
|
||||
mlog.SetLevel(mlog.LevelFatal)
|
||||
case "fatal":
|
||||
zerolog.SetGlobalLevel(zerolog.FatalLevel)
|
||||
mlog.SetLevel(mlog.LevelFatal)
|
||||
case "error":
|
||||
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
|
||||
mlog.SetLevel(mlog.LevelError)
|
||||
case "warn":
|
||||
zerolog.SetGlobalLevel(zerolog.WarnLevel)
|
||||
mlog.SetLevel(mlog.LevelWarn)
|
||||
case "info":
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
mlog.SetLevel(mlog.LevelInfo)
|
||||
case "debug":
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
mlog.SetLevel(mlog.LevelDebug)
|
||||
case "trace":
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
mlog.SetLevel(mlog.LevelTrace)
|
||||
default:
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
mlog.SetLevel(mlog.LevelInfo)
|
||||
}
|
||||
|
||||
var logger zerolog.Logger
|
||||
|
||||
if options.Pretty {
|
||||
logger = log.Output(
|
||||
zerolog.NewConsoleWriter(
|
||||
func(w *zerolog.ConsoleWriter) {
|
||||
w.TimeFormat = time.RFC3339
|
||||
w.Out = os.Stderr
|
||||
w.NoColor = !options.Color
|
||||
},
|
||||
),
|
||||
)
|
||||
} else {
|
||||
logger = zerolog.New(os.Stderr)
|
||||
}
|
||||
|
||||
logger = logger.With().
|
||||
Str("service", options.Name).
|
||||
Timestamp().
|
||||
Logger()
|
||||
|
||||
mlog.SetLogger(
|
||||
microZerolog{
|
||||
logger: logger,
|
||||
buffer: ring.New(mdlog.DefaultSize),
|
||||
},
|
||||
)
|
||||
|
||||
return Logger{
|
||||
logger,
|
||||
}
|
||||
}
|
||||
|
||||
// microZerolog implements the required interface for the go-micro logger.
|
||||
type microZerolog struct {
|
||||
logger zerolog.Logger
|
||||
buffer *ring.Buffer
|
||||
}
|
||||
|
||||
func (mz microZerolog) Read(opts ...mdlog.ReadOption) ([]mdlog.Record, error) {
|
||||
options := mdlog.ReadOptions{}
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
var entries []*ring.Entry
|
||||
|
||||
if !options.Since.IsZero() {
|
||||
entries = mz.buffer.Since(options.Since)
|
||||
}
|
||||
|
||||
if options.Count > 0 {
|
||||
switch len(entries) > 0 {
|
||||
case true:
|
||||
if options.Count > len(entries) {
|
||||
entries = entries[0:options.Count]
|
||||
}
|
||||
default:
|
||||
entries = mz.buffer.Get(options.Count)
|
||||
}
|
||||
}
|
||||
|
||||
records := make([]mdlog.Record, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
record := mdlog.Record{
|
||||
Timestamp: entry.Timestamp,
|
||||
Message: entry.Value,
|
||||
}
|
||||
records = append(records, record)
|
||||
}
|
||||
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func (mz microZerolog) Write(record mdlog.Record) error {
|
||||
level := record.Metadata["level"]
|
||||
mz.log(level, fmt.Sprint(record.Message))
|
||||
mz.buffer.Put(record.Message)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mz microZerolog) Stream() (mdlog.Stream, error) {
|
||||
stream, stop := mz.buffer.Stream()
|
||||
records := make(chan mdlog.Record, 128)
|
||||
last10 := mz.buffer.Get(10)
|
||||
|
||||
go func() {
|
||||
for _, entry := range last10 {
|
||||
records <- mdlog.Record{
|
||||
Timestamp: entry.Timestamp,
|
||||
Message: entry.Value,
|
||||
Metadata: make(map[string]string),
|
||||
}
|
||||
}
|
||||
for entry := range stream {
|
||||
records <- mdlog.Record{
|
||||
Timestamp: entry.Timestamp,
|
||||
Message: entry.Value,
|
||||
Metadata: make(map[string]string),
|
||||
}
|
||||
}
|
||||
}()
|
||||
return &logStream{
|
||||
stream: records,
|
||||
stop: stop,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (mz microZerolog) log(level string, msg string) {
|
||||
l, err := zerolog.ParseLevel(level)
|
||||
if err != nil {
|
||||
l = zerolog.InfoLevel
|
||||
}
|
||||
|
||||
mz.logger.WithLevel(l).Msg(msg)
|
||||
|
||||
// Invoke os.Exit because unlike zerolog.Logger.Fatal zerolog.Logger.WithLevel won't stop the execution.
|
||||
if l == zerolog.FatalLevel {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
56
ocis-pkg/log/option.go
Normal file
56
ocis-pkg/log/option.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package log
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Name string
|
||||
Level string
|
||||
Pretty bool
|
||||
Color bool
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{
|
||||
Name: "ocis",
|
||||
Level: "info",
|
||||
Pretty: true,
|
||||
Color: true,
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Name provides a function to set the name option.
|
||||
func Name(val string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = val
|
||||
}
|
||||
}
|
||||
|
||||
// Level provides a function to set the level option.
|
||||
func Level(val string) Option {
|
||||
return func(o *Options) {
|
||||
o.Level = val
|
||||
}
|
||||
}
|
||||
|
||||
// Pretty provides a function to set the pretty option.
|
||||
func Pretty(val bool) Option {
|
||||
return func(o *Options) {
|
||||
o.Pretty = val
|
||||
}
|
||||
}
|
||||
|
||||
// Color provides a function to set the color option.
|
||||
func Color(val bool) Option {
|
||||
return func(o *Options) {
|
||||
o.Color = val
|
||||
}
|
||||
}
|
||||
24
ocis-pkg/log/stream.go
Normal file
24
ocis-pkg/log/stream.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
mdlog "github.com/micro/go-micro/v2/debug/log"
|
||||
)
|
||||
|
||||
type logStream struct {
|
||||
stream <-chan mdlog.Record
|
||||
stop chan bool
|
||||
}
|
||||
|
||||
func (l *logStream) Chan() <-chan mdlog.Record {
|
||||
return l.stream
|
||||
}
|
||||
|
||||
func (l *logStream) Stop() error {
|
||||
select {
|
||||
case <-l.stop:
|
||||
return nil
|
||||
default:
|
||||
close(l.stop)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
65
ocis-pkg/middleware/account.go
Normal file
65
ocis-pkg/middleware/account.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/cs3org/reva/pkg/token/manager/jwt"
|
||||
"github.com/micro/go-micro/v2/metadata"
|
||||
"github.com/owncloud/ocis-pkg/v2/account"
|
||||
)
|
||||
|
||||
// newAccountOptions initializes the available default options.
|
||||
func newAccountOptions(opts ...account.Option) account.Options {
|
||||
opt := account.Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// AccountID serves as key for the account uuid in the context
|
||||
const AccountID string = "Account-Id"
|
||||
// RoleIDs serves as key for the roles in the context
|
||||
const RoleIDs string = "Role-Ids"
|
||||
// UUIDKey serves as key for the account uuid in the context
|
||||
// Deprecated: UUIDKey exists for compatibility reasons. Use AccountID instead.
|
||||
var UUIDKey struct{}
|
||||
|
||||
// ExtractAccountUUID provides a middleware to extract the account uuid from the x-access-token header value
|
||||
// and write it to the context. If there is no x-access-token the middleware is omitted.
|
||||
func ExtractAccountUUID(opts ...account.Option) func(http.Handler) http.Handler {
|
||||
opt := newAccountOptions(opts...)
|
||||
tokenManager, err := jwt.New(map[string]interface{}{
|
||||
"secret": opt.JWTSecret,
|
||||
"expires": int64(60),
|
||||
})
|
||||
if err != nil {
|
||||
opt.Logger.Fatal().Err(err).Msgf("Could not initialize token-manager")
|
||||
}
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("x-access-token")
|
||||
if len(token) == 0 {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := tokenManager.DismantleToken(r.Context(), token)
|
||||
if err != nil {
|
||||
opt.Logger.Error().Err(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Important: user.Id.OpaqueId is the AccountUUID. Set this way in the account uuid middleware in ocis-proxy.
|
||||
// https://github.com/owncloud/ocis-proxy/blob/ea254d6036592cf9469d757d1295e0c4309d1e63/pkg/middleware/account_uuid.go#L109
|
||||
ctx := context.WithValue(r.Context(), UUIDKey, user.Id.OpaqueId)
|
||||
// TODO: implement token manager in cs3org/reva that uses generic metadata instead of access token from header.
|
||||
ctx = metadata.Set(ctx, AccountID, user.Id.OpaqueId)
|
||||
ctx = metadata.Set(ctx, RoleIDs, string(user.Opaque.Map["roles"].Value))
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
49
ocis-pkg/middleware/header.go
Normal file
49
ocis-pkg/middleware/header.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Cache writes required cache headers to all requests.
|
||||
func Cache(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
|
||||
w.Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// Cors writes required cors headers to all requests.
|
||||
func Cors(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "OPTIONS" {
|
||||
next.ServeHTTP(w, r)
|
||||
} else {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "authorization, origin, content-type, accept, x-requested-with")
|
||||
w.Header().Set("Allow", "HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Secure writes required access headers to all requests.
|
||||
func Secure(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("X-Frame-Options", "DENY")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("X-XSS-Protection", "1; mode=block")
|
||||
|
||||
if r.TLS != nil {
|
||||
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
30
ocis-pkg/middleware/logger.go
Normal file
30
ocis-pkg/middleware/logger.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
)
|
||||
|
||||
// Logger is a middleware to log http requests.
|
||||
func Logger(logger log.Logger) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
start := time.Now()
|
||||
wrap := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
|
||||
next.ServeHTTP(wrap, r)
|
||||
|
||||
logger.Debug().
|
||||
Str("request", r.Header.Get("X-Request-ID")).
|
||||
Str("proto", r.Proto).
|
||||
Str("method", r.Method).
|
||||
Int("status", wrap.Status()).
|
||||
Str("path", r.URL.Path).
|
||||
Dur("duration", time.Since(start)).
|
||||
Int("bytes", wrap.BytesWritten()).
|
||||
Msg("")
|
||||
})
|
||||
}
|
||||
}
|
||||
107
ocis-pkg/middleware/openidconnect.go
Normal file
107
ocis-pkg/middleware/openidconnect.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
oidc "github.com/coreos/go-oidc"
|
||||
ocisoidc "github.com/owncloud/ocis-pkg/v2/oidc"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// newOIDCOptions initializes the available default options.
|
||||
func newOIDCOptions(opts ...ocisoidc.Option) ocisoidc.Options {
|
||||
opt := ocisoidc.Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// OpenIDConnect provides a middleware to check access secured by a static token.
|
||||
func OpenIDConnect(opts ...ocisoidc.Option) func(http.Handler) http.Handler {
|
||||
opt := newOIDCOptions(opts...)
|
||||
|
||||
// set defaults
|
||||
if opt.Realm == "" {
|
||||
opt.Realm = opt.Endpoint
|
||||
}
|
||||
if len(opt.SigningAlgs) < 1 {
|
||||
opt.SigningAlgs = []string{"RS256", "PS256"}
|
||||
}
|
||||
|
||||
var oidcProvider *oidc.Provider
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
header := r.Header.Get("Authorization")
|
||||
|
||||
if header == "" || !strings.HasPrefix(header, "Bearer ") {
|
||||
w.Header().Add("WWW-Authenticate", fmt.Sprintf(`Bearer realm="%s"`, opt.Realm))
|
||||
http.Error(w, ErrInvalidToken.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
token := header[7:]
|
||||
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: opt.Insecure,
|
||||
},
|
||||
}
|
||||
customHTTPClient := &http.Client{
|
||||
Transport: tr,
|
||||
Timeout: time.Second * 10,
|
||||
}
|
||||
customCtx := context.WithValue(r.Context(), oauth2.HTTPClient, customHTTPClient)
|
||||
|
||||
// use cached provider
|
||||
if oidcProvider == nil {
|
||||
// Initialize a provider by specifying the issuer URL.
|
||||
// provider needs to be cached as when it is created
|
||||
// it will fetch the keys from the issuer using the .well-known
|
||||
// endpoint
|
||||
provider, err := oidc.NewProvider(customCtx, opt.Endpoint)
|
||||
if err != nil {
|
||||
opt.Logger.Error().Err(err).Msg("could not initialize oidc provider")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
oidcProvider = provider
|
||||
}
|
||||
|
||||
// The claims we want to have
|
||||
var claims ocisoidc.StandardClaims
|
||||
|
||||
// TODO cache userinfo for access token if we can determine the expiry (which works in case it is a jwt based access token)
|
||||
oauth2Token := &oauth2.Token{
|
||||
AccessToken: token,
|
||||
}
|
||||
userInfo, err := oidcProvider.UserInfo(customCtx, oauth2.StaticTokenSource(oauth2Token))
|
||||
if err != nil {
|
||||
opt.Logger.Error().Err(err).Str("token", string(token)).Msg("Failed to get userinfo")
|
||||
http.Error(w, ErrInvalidToken.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// parse claims
|
||||
if err := userInfo.Claims(&claims); err != nil {
|
||||
opt.Logger.Error().Err(err).Interface("userinfo", userInfo).Msg("failed to unmarshal userinfo claims")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
opt.Logger.Debug().Interface("claims", claims).Interface("userInfo", userInfo).Msg("unmarshalled userinfo")
|
||||
// store claims in context
|
||||
// uses the original context, not the one with probably reduced security
|
||||
nr := r.WithContext(ocisoidc.NewContext(r.Context(), &claims))
|
||||
|
||||
next.ServeHTTP(w, nr)
|
||||
})
|
||||
}
|
||||
}
|
||||
18
ocis-pkg/middleware/realip.go
Normal file
18
ocis-pkg/middleware/realip.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/tomasen/realip"
|
||||
)
|
||||
|
||||
// RealIP is a middleware that sets a http.Request RemoteAddr.
|
||||
func RealIP(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if ip := realip.RealIP(r); ip != "" {
|
||||
r.RemoteAddr = ip
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
12
ocis-pkg/middleware/requestid.go
Normal file
12
ocis-pkg/middleware/requestid.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/ascarter/requestid"
|
||||
)
|
||||
|
||||
// RequestID is a convenient middleware to inject a request id.
|
||||
func RequestID(next http.Handler) http.Handler {
|
||||
return requestid.RequestIDHandler(next)
|
||||
}
|
||||
35
ocis-pkg/middleware/static.go
Normal file
35
ocis-pkg/middleware/static.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Static is a middleware that serves static assets.
|
||||
func Static(root string, fs http.FileSystem) func(http.Handler) http.Handler {
|
||||
if !strings.HasSuffix(root, "/") {
|
||||
root = root + "/"
|
||||
}
|
||||
|
||||
static := http.StripPrefix(
|
||||
root,
|
||||
http.FileServer(
|
||||
fs,
|
||||
),
|
||||
)
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, path.Join(root, "api")) {
|
||||
next.ServeHTTP(w, r)
|
||||
} else {
|
||||
if strings.HasSuffix(r.URL.Path, "/") {
|
||||
http.NotFound(w, r)
|
||||
} else {
|
||||
static.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
37
ocis-pkg/middleware/token.go
Normal file
37
ocis-pkg/middleware/token.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidToken is returned when the request token is invalid.
|
||||
ErrInvalidToken = errors.New("invalid or missing token")
|
||||
)
|
||||
|
||||
// Token provides a middleware to check access secured by a static token.
|
||||
func Token(token string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if token == "" {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
header := r.Header.Get("Authorization")
|
||||
|
||||
if header == "" {
|
||||
http.Error(w, ErrInvalidToken.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if header != "Bearer "+token {
|
||||
http.Error(w, ErrInvalidToken.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
31
ocis-pkg/middleware/tracing.go
Normal file
31
ocis-pkg/middleware/tracing.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"go.opencensus.io/plugin/ochttp/propagation/tracecontext"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// Trace unpacks the request context looking for an existing trace id.
|
||||
func Trace(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var ctx context.Context
|
||||
var span *trace.Span
|
||||
|
||||
tc := tracecontext.HTTPFormat{}
|
||||
// reconstruct span context from request
|
||||
if sc, ok := tc.SpanContextFromRequest(r); ok {
|
||||
// if there is one, add it to the new span
|
||||
ctx, span = trace.StartSpanWithRemoteParent(r.Context(), r.URL.String(), sc)
|
||||
defer span.End()
|
||||
} else {
|
||||
// create a new span if there is no context
|
||||
ctx, span = trace.StartSpan(r.Context(), r.URL.String())
|
||||
defer span.End()
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
21
ocis-pkg/middleware/version.go
Normal file
21
ocis-pkg/middleware/version.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Version writes the current version to the headers.
|
||||
func Version(name, version string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set(
|
||||
fmt.Sprintf("X-%s-VERSION", strings.ToUpper(name)),
|
||||
version,
|
||||
)
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
183
ocis-pkg/oidc/claims.go
Normal file
183
ocis-pkg/oidc/claims.go
Normal file
@@ -0,0 +1,183 @@
|
||||
package oidc
|
||||
|
||||
// The ProviderMetadata describes an idp.
|
||||
// see https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
type ProviderMetadata struct {
|
||||
AuthorizationEndpoint string `json:"authorization_endpoint,omitempty"`
|
||||
//claims_parameter_supported
|
||||
ClaimsSupported []string `json:"claims_supported,omitempty"`
|
||||
//grant_types_supported
|
||||
IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported,omitempty"`
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
JwksURI string `json:"jwks_uri,omitempty"`
|
||||
//registration_endpoint
|
||||
//request_object_signing_alg_values_supported
|
||||
//request_parameter_supported
|
||||
//request_uri_parameter_supported
|
||||
//require_request_uri_registration
|
||||
//response_modes_supported
|
||||
ResponseTypesSupported []string `json:"response_types_supported,omitempty"`
|
||||
ScopesSupported []string `json:"scopes_supported,omitempty"`
|
||||
SubjectTypesSupported []string `json:"subject_types_supported,omitempty"`
|
||||
TokenEndpoint string `json:"token_endpoint,omitempty"`
|
||||
//token_endpoint_auth_methods_supported
|
||||
//token_endpoint_auth_signing_alg_values_supported
|
||||
UserinfoEndpoint string `json:"userinfo_endpoint,omitempty"`
|
||||
//userinfo_signing_alg_values_supported
|
||||
//code_challenge_methods_supported
|
||||
IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"`
|
||||
//introspection_endpoint_auth_methods_supported
|
||||
//introspection_endpoint_auth_signing_alg_values_supported
|
||||
RevocationEndpoint string `json:"revocation_endpoint,omitempty"`
|
||||
//revocation_endpoint_auth_methods_supported
|
||||
//revocation_endpoint_auth_signing_alg_values_supported
|
||||
//id_token_encryption_alg_values_supported
|
||||
//id_token_encryption_enc_values_supported
|
||||
//userinfo_encryption_alg_values_supported
|
||||
//userinfo_encryption_enc_values_supported
|
||||
//request_object_encryption_alg_values_supported
|
||||
//request_object_encryption_enc_values_supported
|
||||
CheckSessionIframe string `json:"check_session_iframe,omitempty"`
|
||||
EndSessionEndpoint string `json:"end_session_endpoint,omitempty"`
|
||||
//claim_types_supported
|
||||
}
|
||||
|
||||
// StandardClaims will be stored in the context to be consumed by the oidc user manager
|
||||
// They can be requested to be returned either in the UserInfo Response, per
|
||||
// Section 5.3.2, or in the ID Token, per Section 2.
|
||||
// see https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
|
||||
type StandardClaims struct {
|
||||
// Time the End-User's information was last updated. Its value is a
|
||||
// JSON number representing the number of seconds from 1970-01-01T0:0:0Z
|
||||
// as measured in UTC until the date/time.
|
||||
UpdatedAt int64 `json:"updated_at,omitempty"`
|
||||
|
||||
// True if the End-User's e-mail address has been verified; otherwise false.
|
||||
// When this Claim Value is true, this means that the OP took affirmative
|
||||
// steps to ensure that this e-mail address was controlled by the End-User
|
||||
// at the time the verification was performed. The means by which an e-mail
|
||||
// address is verified is context-specific, and dependent upon the trust
|
||||
// framework or contractual agreements within which the parties are operating.
|
||||
EmailVerified bool `json:"email_verified,omitempty"`
|
||||
|
||||
// True if the End-User's phone number has been verified; otherwise false.
|
||||
// When this Claim Value is true, this means that the OP took affirmative
|
||||
// steps to ensure that this phone number was controlled by the End-User
|
||||
// at the time the verification was performed. The means by which a phone
|
||||
// number is verified is context-specific, and dependent upon the trust
|
||||
// framework or contractual agreements within which the parties are
|
||||
// operating. When true, the phone_number Claim MUST be in E.164 format
|
||||
// and any extensions MUST be represented in RFC 3966 format.
|
||||
PhoneNumberVerified bool `json:"phone_number_verified,omitempty"`
|
||||
|
||||
Iss string `json:"iss"`
|
||||
|
||||
// Subject - Identifier for the End-User at the Issuer.
|
||||
Sub string `json:"sub,omitempty"`
|
||||
|
||||
// End-User's full name in displayable form including all name parts, possibly
|
||||
// including titles and suffixes, ordered according to the End-User's locale
|
||||
// and preferences.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Given name(s) or first name(s) of the End-User. Note that in some cultures,
|
||||
// people can have multiple given names; all can be present, with the names
|
||||
// being separated by space characters.
|
||||
GivenName string `json:"given_name,omitempty"`
|
||||
|
||||
// Surname(s) or last name(s) of the End-User. Note that in some cultures,
|
||||
// people can have multiple family names or no family name; all can be present,
|
||||
// with the names being separated by space characters.
|
||||
FamilyName string `json:"family_name,omitempty"`
|
||||
|
||||
// Middle name(s) of the End-User. Note that in some cultures, people can have
|
||||
// multiple middle names; all can be present, with the names being separated by
|
||||
// space characters. Also note that in some cultures, middle names are not used.
|
||||
MiddleName string `json:"middle_name,omitempty"`
|
||||
|
||||
// Casual name of the End-User that may or may not be the same as the given_name.
|
||||
// For instance, a nickname value of Mike might be returned alongside a given_name
|
||||
// value of Michael.
|
||||
Nickname string `json:"nickname,omitempty"`
|
||||
|
||||
// Shorthand name by which the End-User wishes to be referred to at the RP, such
|
||||
// as janedoe or j.doe. This value MAY be any valid JSON string including special
|
||||
// characters such as @, /, or whitespace. The RP MUST NOT rely upon this value
|
||||
// being unique, as discussed in Section 5.7.
|
||||
PreferredUsername string `json:"preferred_username,omitempty"`
|
||||
|
||||
// URL of the End-User's profile page. The contents of this Web page SHOULD be
|
||||
// about the End-User.
|
||||
Profile string `json:"profile,omitempty"`
|
||||
|
||||
// URL of the End-User's profile picture. This URL MUST refer to an image file
|
||||
// (for example, a PNG, JPEG, or GIF image file), rather than to a Web page
|
||||
// containing an image. Note that this URL SHOULD specifically reference a
|
||||
// profile photo of the End-User suitable for displaying when describing the
|
||||
// End-User, rather than an arbitrary photo taken by the End-User.
|
||||
Picture string `json:"picture,omitempty"`
|
||||
|
||||
// URL of the End-User's Web page or blog. This Web page SHOULD contain
|
||||
// information published by the End-User or an organization that the End-User
|
||||
// is affiliated with.
|
||||
Website string `json:"website,omitempty"`
|
||||
|
||||
// End-User's preferred e-mail address. Its value MUST conform to the RFC 5322
|
||||
// addr-spec syntax. The RP MUST NOT rely upon this value being unique, as
|
||||
// discussed in Section 5.7.
|
||||
Email string `json:"email,omitempty"`
|
||||
|
||||
// End-User's gender. Values defined by this specification are female and male.
|
||||
// Other values MAY be used when neither of the defined values are applicable.
|
||||
Gender string `json:"gender,omitempty"`
|
||||
|
||||
// End-User's birthday, represented as an ISO 8601:2004 YYYY-MM-DD format.
|
||||
// The year MAY be 0000, indicating that it is omitted. To represent only the
|
||||
// year, YYYY format is allowed. Note that depending on the underlying
|
||||
// platform's date related function, providing just year can result in
|
||||
// varying month and day, so the implementers need to take this factor into
|
||||
// account to correctly process the dates.
|
||||
Birthdate string `json:"birthdate,omitempty"`
|
||||
|
||||
// String from zoneinfo time zone database representing the End-User's time
|
||||
// zone. For example, Europe/Paris or America/Los_Angeles.
|
||||
Zoneinfo string `json:"zoneinfo,omitempty"`
|
||||
|
||||
// End-User's locale, represented as a BCP47 [RFC5646] language tag.
|
||||
// This is typically an ISO 639-1 Alpha-2 [ISO639‑1] language code in
|
||||
// lowercase and an ISO 3166-1 Alpha-2 [ISO3166‑1] country code in
|
||||
// uppercase, separated by a dash. For example, en-US or fr-CA. As a
|
||||
// compatibility note, some implementations have used an underscore as
|
||||
// the separator rather than a dash, for example, en_US; Relying Parties
|
||||
// MAY choose to accept this locale syntax as well.
|
||||
Locale string `json:"locale,omitempty"`
|
||||
|
||||
// End-User's preferred telephone number. E.164 [E.164] is RECOMMENDED
|
||||
// as the format of this Claim, for example, +1 (425) 555-1212 or
|
||||
// +56 (2) 687 2400. If the phone number contains an extension, it is
|
||||
// RECOMMENDED that the extension be represented using the RFC 3966
|
||||
// extension syntax, for example, +1 (604) 555-1234;ext=5678.
|
||||
PhoneNumber string `json:"phone_number,omitempty"`
|
||||
|
||||
// TODO Name is the correct one, does kopano use display name? -> double check and report bug
|
||||
DisplayName string `json:"display_name,omitempty"`
|
||||
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
|
||||
// End-User's preferred postal address. The value of the address member
|
||||
// is a JSON [RFC4627] structure containing some or all of the members
|
||||
// defined in Section 5.1.1.
|
||||
// TODO add address claim https://openid.net/specs/openid-connect-core-1_0.html#AddressClaim
|
||||
Address map[string]interface{} `json:"address,omitempty"`
|
||||
KCIdentity map[string]string `json:"kc.identity,omitempty"`
|
||||
|
||||
// To integrate with an existing LDAP server the IdP can send the numeric user and group id:
|
||||
|
||||
// UIDNumber is a unique numerical id that will be used when setting acls on a storage that integrates with the OS/LDAP
|
||||
UIDNumber string `json:"uidnumber,omitempty"`
|
||||
// GIDNumber is a unique numerical id that will be used when setting acls on a storage that integrates with the OS/LDAP
|
||||
GIDNumber string `json:"gidnumber,omitempty"`
|
||||
|
||||
// OcisID is a unique, persistent, non reassignable user id
|
||||
OcisID string `json:"ocis.id,omitempty"`
|
||||
}
|
||||
17
ocis-pkg/oidc/context.go
Normal file
17
ocis-pkg/oidc/context.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package oidc
|
||||
|
||||
import "context"
|
||||
|
||||
// contextKey is the key for oidc claims in a context
|
||||
type contextKey struct{}
|
||||
|
||||
// NewContext makes a new context that contains the OpenID Connect claims.
|
||||
func NewContext(parent context.Context, c *StandardClaims) context.Context {
|
||||
return context.WithValue(parent, contextKey{}, c)
|
||||
}
|
||||
|
||||
// FromContext returns the StandardClaims stored in a context, or nil if there isn't one.
|
||||
func FromContext(ctx context.Context) *StandardClaims {
|
||||
s, _ := ctx.Value(contextKey{}).(*StandardClaims)
|
||||
return s
|
||||
}
|
||||
57
ocis-pkg/oidc/option.go
Normal file
57
ocis-pkg/oidc/option.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
// Logger to use for logging, must be set
|
||||
Logger log.Logger
|
||||
// Endpoint is the OpenID Connect provider URL
|
||||
Endpoint string
|
||||
// Realm to use in the WWW-Authenticate header, defaults to Endpoint
|
||||
Realm string
|
||||
// SigningAlgs to use when verifying jwt signatures, defaults to "RS256" & "PS256"
|
||||
SigningAlgs []string
|
||||
// Insecure can be used to disable http certificate checks
|
||||
Insecure bool
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(l log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = l
|
||||
}
|
||||
}
|
||||
|
||||
// Endpoint provides a function to set the endpoint option.
|
||||
func Endpoint(e string) Option {
|
||||
return func(o *Options) {
|
||||
o.Endpoint = e
|
||||
}
|
||||
}
|
||||
|
||||
// Realm provides a function to set the realm option.
|
||||
func Realm(r string) Option {
|
||||
return func(o *Options) {
|
||||
o.Realm = r
|
||||
}
|
||||
}
|
||||
|
||||
// SigningAlgs provides a function to set the signing algorithms option.
|
||||
func SigningAlgs(sa []string) Option {
|
||||
return func(o *Options) {
|
||||
o.SigningAlgs = sa
|
||||
}
|
||||
}
|
||||
|
||||
// Insecure provides a function to set the insecure option.
|
||||
func Insecure(i bool) Option {
|
||||
return func(o *Options) {
|
||||
o.Insecure = i
|
||||
}
|
||||
}
|
||||
71
ocis-pkg/roles/cache.go
Normal file
71
ocis-pkg/roles/cache.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
settings "github.com/owncloud/ocis-settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
// entry extends a bundle and adds a TTL
|
||||
type entry struct {
|
||||
*settings.Bundle
|
||||
inserted time.Time
|
||||
}
|
||||
|
||||
// cache is a cache implementation for roles, keyed by roleIDs.
|
||||
type cache struct {
|
||||
entries map[string]entry
|
||||
size int
|
||||
ttl time.Duration
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
// newCache returns a new instance of Cache.
|
||||
func newCache(size int, ttl time.Duration) cache {
|
||||
return cache{
|
||||
size: size,
|
||||
ttl: ttl,
|
||||
entries: map[string]entry{},
|
||||
}
|
||||
}
|
||||
|
||||
// get gets a role-bundle by a given `roleID`.
|
||||
func (c *cache) get(roleID string) *settings.Bundle {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if _, ok := c.entries[roleID]; ok {
|
||||
return c.entries[roleID].Bundle
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// set sets a roleID / role-bundle.
|
||||
func (c *cache) set(roleID string, value *settings.Bundle) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if !c.fits() {
|
||||
c.evict()
|
||||
}
|
||||
|
||||
c.entries[roleID] = entry{
|
||||
value,
|
||||
time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
// evict frees memory from the cache by removing entries that exceeded the cache TTL.
|
||||
func (c *cache) evict() {
|
||||
for i := range c.entries {
|
||||
if c.entries[i].inserted.Add(c.ttl).Before(time.Now()) {
|
||||
delete(c.entries, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fits returns whether the cache fits more entries.
|
||||
func (c *cache) fits() bool {
|
||||
return c.size > len(c.entries)
|
||||
}
|
||||
69
ocis-pkg/roles/manager.go
Normal file
69
ocis-pkg/roles/manager.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
settings "github.com/owncloud/ocis-settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
// Manager manages a cache of roles by fetching unknown roles from the settings.RoleService.
|
||||
type Manager struct {
|
||||
logger log.Logger
|
||||
cache cache
|
||||
roleService settings.RoleService
|
||||
}
|
||||
|
||||
// NewManager returns a new instance of Manager.
|
||||
func NewManager(o ...Option) Manager {
|
||||
opts := newOptions(o...)
|
||||
|
||||
return Manager{
|
||||
cache: newCache(opts.size, opts.ttl),
|
||||
roleService: opts.roleService,
|
||||
}
|
||||
}
|
||||
|
||||
// List returns all roles that match the given roleIDs.
|
||||
func (m *Manager) List(ctx context.Context, roleIDs []string) []*settings.Bundle {
|
||||
// get from cache
|
||||
result := make([]*settings.Bundle, 0)
|
||||
lookup := make([]string, 0)
|
||||
for _, roleID := range roleIDs {
|
||||
if hit := m.cache.get(roleID); hit == nil {
|
||||
lookup = append(lookup, roleID)
|
||||
} else {
|
||||
result = append(result, hit)
|
||||
}
|
||||
}
|
||||
|
||||
// if there are roles missing, fetch them from the RoleService
|
||||
if len(lookup) > 0 {
|
||||
request := &settings.ListBundlesRequest{
|
||||
BundleIds: lookup,
|
||||
}
|
||||
res, err := m.roleService.ListRoles(ctx, request)
|
||||
if err != nil {
|
||||
m.logger.Debug().Err(err).Msg("failed to fetch roles by roleIDs")
|
||||
}
|
||||
for _, role := range res.Bundles {
|
||||
m.cache.set(role.Id, role)
|
||||
result = append(result, role)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindPermissionByID searches for a permission-setting by the permissionID, but limited to the given roleIDs
|
||||
func (m *Manager) FindPermissionByID(ctx context.Context, roleIDs []string, permissionID string) *settings.Setting {
|
||||
for _, role := range m.List(ctx, roleIDs) {
|
||||
for _, setting := range role.Settings {
|
||||
if setting.Id == permissionID {
|
||||
return setting
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
57
ocis-pkg/roles/option.go
Normal file
57
ocis-pkg/roles/option.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
settings "github.com/owncloud/ocis-settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
// Options are all the possible options.
|
||||
type Options struct {
|
||||
size int
|
||||
ttl time.Duration
|
||||
logger log.Logger
|
||||
roleService settings.RoleService
|
||||
}
|
||||
|
||||
// Option mutates option
|
||||
type Option func(*Options)
|
||||
|
||||
// CacheSize configures the size of the cache in items.
|
||||
func CacheSize(s int) Option {
|
||||
return func(o *Options) {
|
||||
o.size = s
|
||||
}
|
||||
}
|
||||
|
||||
// CacheTTL rebuilds the cache after the configured duration.
|
||||
func CacheTTL(ttl time.Duration) Option {
|
||||
return func(o *Options) {
|
||||
o.ttl = ttl
|
||||
}
|
||||
}
|
||||
|
||||
// Logger sets a preconfigured logger
|
||||
func Logger(logger log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.logger = logger
|
||||
}
|
||||
}
|
||||
|
||||
// RoleService provides endpoints for fetching roles.
|
||||
func RoleService(rs settings.RoleService) Option {
|
||||
return func(o *Options) {
|
||||
o.roleService = rs
|
||||
}
|
||||
}
|
||||
|
||||
func newOptions(opts ...Option) Options {
|
||||
o := Options{}
|
||||
|
||||
for _, v := range opts {
|
||||
v(&o)
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
22
ocis-pkg/roles/util.go
Normal file
22
ocis-pkg/roles/util.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/micro/go-micro/v2/metadata"
|
||||
"github.com/owncloud/ocis-pkg/v2/middleware"
|
||||
)
|
||||
|
||||
// ReadRoleIDsFromContext extracts roleIDs from the metadata context and returns them as []string
|
||||
func ReadRoleIDsFromContext(ctx context.Context) (roleIDs []string, ok bool) {
|
||||
roleIDsJSON, ok := metadata.Get(ctx, middleware.RoleIDs)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
err := json.Unmarshal([]byte(roleIDsJSON), &roleIDs)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return roleIDs, true
|
||||
}
|
||||
97
ocis-pkg/service/debug/option.go
Normal file
97
ocis-pkg/service/debug/option.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Name string
|
||||
Version string
|
||||
Address string
|
||||
Token string
|
||||
Pprof bool
|
||||
Zpages bool
|
||||
Health func(http.ResponseWriter, *http.Request)
|
||||
Ready func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(l log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = l
|
||||
}
|
||||
}
|
||||
|
||||
// Name provides a function to set the name option.
|
||||
func Name(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = n
|
||||
}
|
||||
}
|
||||
|
||||
// Version provides a function to set the version option.
|
||||
func Version(v string) Option {
|
||||
return func(o *Options) {
|
||||
o.Version = v
|
||||
}
|
||||
}
|
||||
|
||||
// Address provides a function to set the address option.
|
||||
func Address(a string) Option {
|
||||
return func(o *Options) {
|
||||
o.Address = a
|
||||
}
|
||||
}
|
||||
|
||||
// Token provides a function to set the token option.
|
||||
func Token(t string) Option {
|
||||
return func(o *Options) {
|
||||
o.Token = t
|
||||
}
|
||||
}
|
||||
|
||||
// Pprof provides a function to set the pprof option.
|
||||
func Pprof(p bool) Option {
|
||||
return func(o *Options) {
|
||||
o.Pprof = p
|
||||
}
|
||||
}
|
||||
|
||||
// Zpages provides a function to set the zpages option.
|
||||
func Zpages(z bool) Option {
|
||||
return func(o *Options) {
|
||||
o.Zpages = z
|
||||
}
|
||||
}
|
||||
|
||||
// Health provides a function to set the health option.
|
||||
func Health(h func(http.ResponseWriter, *http.Request)) Option {
|
||||
return func(o *Options) {
|
||||
o.Health = h
|
||||
}
|
||||
}
|
||||
|
||||
// Ready provides a function to set the ready option.
|
||||
func Ready(r func(http.ResponseWriter, *http.Request)) Option {
|
||||
return func(o *Options) {
|
||||
o.Ready = r
|
||||
}
|
||||
}
|
||||
63
ocis-pkg/service/debug/service.go
Normal file
63
ocis-pkg/service/debug/service.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
|
||||
"github.com/justinas/alice"
|
||||
"github.com/owncloud/ocis-pkg/v2/middleware"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.opencensus.io/zpages"
|
||||
)
|
||||
|
||||
// NewService initializes a new debug service.
|
||||
func NewService(opts ...Option) *http.Server {
|
||||
dopts := newOptions(opts...)
|
||||
|
||||
dopts.Logger.Info().
|
||||
Str("transport", "debug").
|
||||
Str("addr", dopts.Address).
|
||||
Msg("Starting server")
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("/metrics", alice.New(
|
||||
middleware.Token(
|
||||
dopts.Token,
|
||||
),
|
||||
).Then(
|
||||
promhttp.Handler(),
|
||||
))
|
||||
|
||||
mux.HandleFunc("/healthz", dopts.Health)
|
||||
mux.HandleFunc("/readyz", dopts.Ready)
|
||||
|
||||
if dopts.Pprof {
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
}
|
||||
|
||||
if dopts.Zpages {
|
||||
zpages.Handle(mux, "/debug")
|
||||
}
|
||||
|
||||
return &http.Server{
|
||||
Addr: dopts.Address,
|
||||
Handler: alice.New(
|
||||
middleware.RealIP,
|
||||
middleware.RequestID,
|
||||
middleware.Cache,
|
||||
middleware.Cors,
|
||||
middleware.Secure,
|
||||
middleware.Version(
|
||||
dopts.Name,
|
||||
dopts.Version,
|
||||
),
|
||||
).Then(
|
||||
mux,
|
||||
),
|
||||
}
|
||||
}
|
||||
84
ocis-pkg/service/grpc/option.go
Normal file
84
ocis-pkg/service/grpc/option.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/micro/cli/v2"
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Namespace string
|
||||
Name string
|
||||
Version string
|
||||
Address string
|
||||
Context context.Context
|
||||
Flags []cli.Flag
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{
|
||||
Namespace: "go.micro.api",
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(l log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = l
|
||||
}
|
||||
}
|
||||
|
||||
// Namespace provides a function to set the namespace option.
|
||||
func Namespace(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Namespace = n
|
||||
}
|
||||
}
|
||||
|
||||
// Name provides a function to set the name option.
|
||||
func Name(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = n
|
||||
}
|
||||
}
|
||||
|
||||
// Version provides a function to set the version option.
|
||||
func Version(v string) Option {
|
||||
return func(o *Options) {
|
||||
o.Version = v
|
||||
}
|
||||
}
|
||||
|
||||
// Address provides a function to set the address option.
|
||||
func Address(a string) Option {
|
||||
return func(o *Options) {
|
||||
o.Address = a
|
||||
}
|
||||
}
|
||||
|
||||
// Context provides a function to set the context option.
|
||||
func Context(ctx context.Context) Option {
|
||||
return func(o *Options) {
|
||||
o.Context = ctx
|
||||
}
|
||||
}
|
||||
|
||||
// Flags provides a function to set the flags option.
|
||||
func Flags(flags ...cli.Flag) Option {
|
||||
return func(o *Options) {
|
||||
o.Flags = append(o.Flags, flags...)
|
||||
}
|
||||
}
|
||||
53
ocis-pkg/service/grpc/service.go
Normal file
53
ocis-pkg/service/grpc/service.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/v2"
|
||||
"github.com/micro/go-plugins/wrapper/trace/opencensus/v2"
|
||||
"github.com/owncloud/ocis-pkg/v2/wrapper/prometheus"
|
||||
)
|
||||
|
||||
// Service simply wraps the go-micro grpc service.
|
||||
type Service struct {
|
||||
micro.Service
|
||||
}
|
||||
|
||||
// NewService initializes a new grpc service.
|
||||
func NewService(opts ...Option) Service {
|
||||
sopts := newOptions(opts...)
|
||||
|
||||
sopts.Logger.Info().
|
||||
Str("transport", "grpc").
|
||||
Str("addr", sopts.Address).
|
||||
Msg("Starting server")
|
||||
|
||||
mopts := []micro.Option{
|
||||
micro.Name(
|
||||
strings.Join(
|
||||
[]string{
|
||||
sopts.Namespace,
|
||||
sopts.Name,
|
||||
},
|
||||
".",
|
||||
),
|
||||
),
|
||||
micro.Version(sopts.Version),
|
||||
micro.Address(sopts.Address),
|
||||
micro.WrapHandler(prometheus.NewHandlerWrapper()),
|
||||
micro.WrapClient(opencensus.NewClientWrapper()),
|
||||
micro.WrapHandler(opencensus.NewHandlerWrapper()),
|
||||
micro.WrapSubscriber(opencensus.NewSubscriberWrapper()),
|
||||
micro.RegisterTTL(time.Second * 30),
|
||||
micro.RegisterInterval(time.Second * 10),
|
||||
micro.Context(sopts.Context),
|
||||
micro.Flags(sopts.Flags...),
|
||||
}
|
||||
|
||||
return Service{
|
||||
micro.NewService(
|
||||
mopts...,
|
||||
),
|
||||
}
|
||||
}
|
||||
102
ocis-pkg/service/http/option.go
Normal file
102
ocis-pkg/service/http/option.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
|
||||
"github.com/micro/cli/v2"
|
||||
"github.com/owncloud/ocis-pkg/v2/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
TLSConfig *tls.Config
|
||||
Namespace string
|
||||
Name string
|
||||
Version string
|
||||
Address string
|
||||
Handler http.Handler
|
||||
Context context.Context
|
||||
Flags []cli.Flag
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{
|
||||
Namespace: "go.micro.web",
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(l log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = l
|
||||
}
|
||||
}
|
||||
|
||||
// Namespace provides a function to set the namespace option.
|
||||
func Namespace(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Namespace = n
|
||||
}
|
||||
}
|
||||
|
||||
// Name provides a function to set the name option.
|
||||
func Name(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = n
|
||||
}
|
||||
}
|
||||
|
||||
// Version provides a function to set the version option.
|
||||
func Version(v string) Option {
|
||||
return func(o *Options) {
|
||||
o.Version = v
|
||||
}
|
||||
}
|
||||
|
||||
// Address provides a function to set the address option.
|
||||
func Address(a string) Option {
|
||||
return func(o *Options) {
|
||||
o.Address = a
|
||||
}
|
||||
}
|
||||
|
||||
// Context provides a function to set the context option.
|
||||
func Context(ctx context.Context) Option {
|
||||
return func(o *Options) {
|
||||
o.Context = ctx
|
||||
}
|
||||
}
|
||||
|
||||
// Flags provides a function to set the flags option.
|
||||
func Flags(flags ...cli.Flag) Option {
|
||||
return func(o *Options) {
|
||||
o.Flags = append(o.Flags, flags...)
|
||||
}
|
||||
}
|
||||
|
||||
// TLSConfig provides a function to set the TLSConfig option.
|
||||
func TLSConfig(config *tls.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.TLSConfig = config
|
||||
}
|
||||
}
|
||||
|
||||
// Handler sets the http handler for the service
|
||||
func Handler(h http.Handler) Option {
|
||||
return func(o *Options) {
|
||||
o.Handler = h
|
||||
}
|
||||
}
|
||||
57
ocis-pkg/service/http/service.go
Normal file
57
ocis-pkg/service/http/service.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/v2/web"
|
||||
)
|
||||
|
||||
// Service simply wraps the go-micro web service.
|
||||
type Service struct {
|
||||
web.Service
|
||||
}
|
||||
|
||||
// NewService initializes a new http service.
|
||||
func NewService(opts ...Option) Service {
|
||||
sopts := newOptions(opts...)
|
||||
sopts.Logger.Info().
|
||||
Str("transport", transport(sopts.TLSConfig)).
|
||||
Str("addr", sopts.Address).
|
||||
Msg("Starting server")
|
||||
|
||||
wopts := []web.Option{
|
||||
web.Name(
|
||||
strings.Join(
|
||||
[]string{
|
||||
sopts.Namespace,
|
||||
sopts.Name,
|
||||
},
|
||||
".",
|
||||
),
|
||||
),
|
||||
web.Version(sopts.Version),
|
||||
web.Address(sopts.Address),
|
||||
web.RegisterTTL(time.Second * 30),
|
||||
web.RegisterInterval(time.Second * 10),
|
||||
web.Context(sopts.Context),
|
||||
web.TLSConfig(sopts.TLSConfig),
|
||||
web.Handler(sopts.Handler),
|
||||
web.Flags(sopts.Flags...),
|
||||
}
|
||||
|
||||
return Service{
|
||||
web.NewService(
|
||||
wopts...,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func transport(secure *tls.Config) string {
|
||||
if secure != nil {
|
||||
return "https"
|
||||
}
|
||||
|
||||
return "http"
|
||||
}
|
||||
10
ocis-pkg/tools.go
Normal file
10
ocis-pkg/tools.go
Normal file
@@ -0,0 +1,10 @@
|
||||
// +build tools
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "github.com/haya14busa/goverage"
|
||||
_ "github.com/restic/calens"
|
||||
_ "golang.org/x/lint/golint"
|
||||
_ "honnef.co/go/tools/cmd/staticcheck"
|
||||
)
|
||||
88
ocis-pkg/wrapper/prometheus/prometheus.go
Normal file
88
ocis-pkg/wrapper/prometheus/prometheus.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/micro/go-micro/v2/server"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var (
|
||||
// Namespace defines the namespace of the defined metrics.
|
||||
Namespace = "ocis"
|
||||
)
|
||||
|
||||
// NewHandlerWrapper initializes the prometheus handler wrapper.
|
||||
func NewHandlerWrapper(opts ...server.Option) server.HandlerWrapper {
|
||||
counter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: Namespace,
|
||||
Name: "request_total",
|
||||
Help: "How many service requests processed",
|
||||
},
|
||||
[]string{"method", "status"},
|
||||
)
|
||||
|
||||
latency := prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Namespace: Namespace,
|
||||
Name: "upstream_latency_microseconds",
|
||||
Help: "Service method latencies in microseconds",
|
||||
},
|
||||
[]string{"method"},
|
||||
)
|
||||
|
||||
duration := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: Namespace,
|
||||
Name: "request_duration_seconds",
|
||||
Help: "Service method request time in seconds",
|
||||
},
|
||||
[]string{"method"},
|
||||
)
|
||||
|
||||
prometheus.Register(
|
||||
prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}),
|
||||
)
|
||||
|
||||
prometheus.Register(
|
||||
prometheus.NewGoCollector(),
|
||||
)
|
||||
|
||||
prometheus.Register(
|
||||
counter,
|
||||
)
|
||||
|
||||
prometheus.Register(
|
||||
latency,
|
||||
)
|
||||
|
||||
prometheus.Register(
|
||||
duration,
|
||||
)
|
||||
|
||||
return func(fn server.HandlerFunc) server.HandlerFunc {
|
||||
return func(ctx context.Context, req server.Request, rsp interface{}) error {
|
||||
name := req.Endpoint()
|
||||
|
||||
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
|
||||
us := v * 1000000
|
||||
|
||||
latency.WithLabelValues(name).Observe(us)
|
||||
duration.WithLabelValues(name).Observe(v)
|
||||
}))
|
||||
|
||||
defer timer.ObserveDuration()
|
||||
|
||||
err := fn(ctx, req, rsp)
|
||||
|
||||
if err == nil {
|
||||
counter.WithLabelValues(name, "success").Inc()
|
||||
} else {
|
||||
counter.WithLabelValues(name, "fail").Inc()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user