Skip to content

Commit

Permalink
minimal webfinger (#5373)
Browse files Browse the repository at this point in the history
* initial webfinger stub

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* add webfinger to proxy, return current host

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* some cleanup

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* allow passing multiple rel params

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* introduce interfaces

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* parse oidc auth token

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* add templating, drop chain, use map of relation providers

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* fix ocis url yaml

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* fix typos

Co-authored-by: Dominik Schmidt <[email protected]>

* switch to userinfo claims

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* readme cleanup

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* add TODO.md with ideas

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* replace subject on authenticated request responses

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* Apply suggestions from code review

Co-authored-by: Martin <[email protected]>

* markdown lint

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* return a 401 when bearer token expired, some more docs

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* Apply suggestions from code review

Co-authored-by: Martin <[email protected]>

* fix docs

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* clarify env var

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* extract handler func

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* use correct service in reflex.conf

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* test relations

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>

* Update services/webfinger/pkg/config/config.go

---------

Signed-off-by: Jörn Friedrich Dreyer <[email protected]>
Co-authored-by: Dominik Schmidt <[email protected]>
Co-authored-by: Martin <[email protected]>
  • Loading branch information
3 people authored Feb 13, 2023
1 parent 139cf79 commit 2c98d32
Show file tree
Hide file tree
Showing 46 changed files with 2,072 additions and 1 deletion.
18 changes: 18 additions & 0 deletions docs/services/webfinger/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Webfinger
date: 2023-02-03T00:00:00+00:00
weight: 20
geekdocRepo: https://github.com/owncloud/ocis
geekdocEditPath: edit/master/docs/services/webfinger
geekdocFilePath: _index.md
geekdocCollapseSection: true
---

## Abstract

This service provides endpoints a the /.well-known/webfinger implementation.

## Table of Contents

{{< toc-tree >}}

24 changes: 24 additions & 0 deletions docs/services/wellknown/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
title: Well-Known
date: 2023-02-03T00:00:00+00:00
weight: 20
geekdocRepo: https://github.com/owncloud/ocis
geekdocEditPath: edit/master/docs/services/well-known
geekdocFilePath: _index.md
geekdocCollapseSection: true
---

## Abstract

This service provides endpoints on the /.well-known API

## Table of Contents

{{< toc-tree >}}


## Webfinger

## oCIS-configuration

## Libregraph?
2 changes: 2 additions & 0 deletions ocis-pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
users "github.com/owncloud/ocis/v2/services/users/pkg/config"
web "github.com/owncloud/ocis/v2/services/web/pkg/config"
webdav "github.com/owncloud/ocis/v2/services/webdav/pkg/config"
webfinger "github.com/owncloud/ocis/v2/services/webfinger/pkg/config"
)

const (
Expand Down Expand Up @@ -106,5 +107,6 @@ type Config struct {
Users *users.Config `yaml:"users"`
Web *web.Config `yaml:"web"`
WebDAV *webdav.Config `yaml:"webdav"`
Webfinger *webfinger.Config `yaml:"webfinger"`
Search *search.Config `yaml:"search"`
}
2 changes: 2 additions & 0 deletions ocis-pkg/config/defaultconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
users "github.com/owncloud/ocis/v2/services/users/pkg/config/defaults"
web "github.com/owncloud/ocis/v2/services/web/pkg/config/defaults"
webdav "github.com/owncloud/ocis/v2/services/webdav/pkg/config/defaults"
webfinger "github.com/owncloud/ocis/v2/services/webfinger/pkg/config/defaults"
)

func DefaultConfig() *Config {
Expand Down Expand Up @@ -71,5 +72,6 @@ func DefaultConfig() *Config {
Users: users.DefaultConfig(),
Web: web.DefaultConfig(),
WebDAV: webdav.DefaultConfig(),
Webfinger: webfinger.DefaultConfig(),
}
}
93 changes: 93 additions & 0 deletions ocis-pkg/middleware/oidc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package middleware

import (
"context"
"net/http"
"strings"
"sync"

gOidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
"golang.org/x/oauth2"
)

// newOidcOptions initializes the available default options.
func newOidcOptions(opts ...Option) Options {
opt := Options{}

for _, o := range opts {
o(&opt)
}

return opt
}

// OIDCProvider used to mock the oidc provider during tests
type OIDCProvider interface {
UserInfo(ctx context.Context, ts oauth2.TokenSource) (*gOidc.UserInfo, error)
}

// OidcAuth provides a middleware to authenticate a bearer auth with an OpenID Connect identity provider
// It will put all claims provided by the userinfo endpoint in the context
func OidcAuth(opts ...Option) func(http.Handler) http.Handler {
opt := newOidcOptions(opts...)

// TODO use a micro store cache option

providerFunc := func() (OIDCProvider, error) {
// Initialize a provider by specifying the issuer URL.
// it will fetch the keys from the issuer using the .well-known
// endpoint
return gOidc.NewProvider(
context.WithValue(context.Background(), oauth2.HTTPClient, http.Client{}),
opt.OidcIssuer,
)
}
var provider OIDCProvider
getProviderOnce := sync.Once{}

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
authHeader := r.Header.Get("Authorization")
switch {
case strings.HasPrefix(authHeader, "Bearer "):
getProviderOnce.Do(func() {
var err error
provider, err = providerFunc()
if err != nil {
return
}
})

oauth2Token := &oauth2.Token{
AccessToken: strings.TrimPrefix(authHeader, "Bearer "),
}

userInfo, err := provider.UserInfo(
context.WithValue(ctx, oauth2.HTTPClient, http.Client{}),
oauth2.StaticTokenSource(oauth2Token),
)
if err != nil {
w.Header().Add("WWW-Authenticate", `Bearer`)
w.WriteHeader(http.StatusUnauthorized)
return
}
claims := map[string]interface{}{}
err = userInfo.Claims(&claims)
if err != nil {
break
}

ctx = oidc.NewContext(ctx, claims)

default:
// do nothing
next.ServeHTTP(w, r.WithContext(ctx))
return
}

next.ServeHTTP(w, r.WithContext(ctx))
})
}
}
40 changes: 40 additions & 0 deletions ocis-pkg/middleware/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package middleware

import (
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/owncloud/ocis/v2/ocis-pkg/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
// The OpenID Connect Issuer URL
OidcIssuer string
// GatewayAPIClient is a reva gateway client
GatewayAPIClient gatewayv1beta1.GatewayAPIClient
}

// WithLogger provides a function to set the openid connect issuer option.
func WithOidcIssuer(val string) Option {
return func(o *Options) {
o.OidcIssuer = val
}
}

// WithLogger provides a function to set the logger option.
func WithLogger(val log.Logger) Option {
return func(o *Options) {
o.Logger = val
}
}

// WithGatewayAPIClient provides a function to set the reva gateway client option.
func WithGatewayAPIClient(val gatewayv1beta1.GatewayAPIClient) Option {
return func(o *Options) {
o.GatewayAPIClient = val
}
}
31 changes: 31 additions & 0 deletions ocis/pkg/command/webfinger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package command

import (
"github.com/owncloud/ocis/v2/ocis-pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/ocis-pkg/config/parser"
"github.com/owncloud/ocis/v2/ocis/pkg/command/helper"
"github.com/owncloud/ocis/v2/ocis/pkg/register"
"github.com/owncloud/ocis/v2/services/webfinger/pkg/command"
"github.com/urfave/cli/v2"
)

// WebfingerCommand is the entrypoint for the webfinger command.
func WebfingerCommand(cfg *config.Config) *cli.Command {

return &cli.Command{
Name: cfg.Webfinger.Service.Name,
Usage: helper.SubcommandDescription(cfg.Webfinger.Service.Name),
Category: "services",
Before: func(c *cli.Context) error {
configlog.Error(parser.ParseConfig(cfg, true))
cfg.Webfinger.Commons = cfg.Commons
return nil
},
Subcommands: command.GetCommands(cfg.Webfinger),
}
}

func init() {
register.AddCommand(WebfingerCommand)
}
2 changes: 2 additions & 0 deletions ocis/pkg/runtime/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
users "github.com/owncloud/ocis/v2/services/users/pkg/command"
web "github.com/owncloud/ocis/v2/services/web/pkg/command"
webdav "github.com/owncloud/ocis/v2/services/webdav/pkg/command"
webfinger "github.com/owncloud/ocis/v2/services/webfinger/pkg/command"
"github.com/thejerf/suture/v4"
)

Expand Down Expand Up @@ -112,6 +113,7 @@ func NewService(options ...Option) (*Service, error) {
s.ServicesRegistry[opts.Config.Thumbnails.Service.Name] = thumbnails.NewSutureService
s.ServicesRegistry[opts.Config.Web.Service.Name] = web.NewSutureService
s.ServicesRegistry[opts.Config.WebDAV.Service.Name] = webdav.NewSutureService
s.ServicesRegistry[opts.Config.Webfinger.Service.Name] = webfinger.NewSutureService
s.ServicesRegistry[opts.Config.Frontend.Service.Name] = frontend.NewSutureService
s.ServicesRegistry[opts.Config.OCDav.Service.Name] = ocdav.NewSutureService
s.ServicesRegistry[opts.Config.Gateway.Service.Name] = gateway.NewSutureService
Expand Down
7 changes: 6 additions & 1 deletion services/proxy/pkg/config/defaults/defaultconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ func DefaultPolicies() []config.Policy {
Unprotected: true,
},
{
Endpoint: "/.well-known/",
Endpoint: "/.well-known/webfinger",
Service: "com.owncloud.web.webfinger",
Unprotected: true,
},
{
Endpoint: "/.well-known/openid-configuration",
Service: "com.owncloud.web.idp",
Unprotected: true,
},
Expand Down
2 changes: 2 additions & 0 deletions services/webfinger/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!bin/
39 changes: 39 additions & 0 deletions services/webfinger/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
SHELL := bash
NAME := webfinger

include ../../.make/recursion.mk

############ tooling ############
ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
include ../../.bingo/Variables.mk
endif

############ go tooling ############
include ../../.make/go.mk

############ release ############
include ../../.make/release.mk

############ docs generate ############
include ../../.make/docs.mk

.PHONY: docs-generate
docs-generate: config-docs-generate

############ generate ############
include ../../.make/generate.mk

.PHONY: ci-go-generate
ci-go-generate: $(MOCKERY) # CI runs ci-node-generate automatically before this target
$(MOCKERY) --srcpkg github.com/go-ldap/ldap/v3 --case underscore --filename ldapclient.go --name Client


.PHONY: ci-node-generate
ci-node-generate:

############ licenses ############
.PHONY: ci-node-check-licenses
ci-node-check-licenses:

.PHONY: ci-node-save-licenses
ci-node-save-licenses:
Loading

0 comments on commit 2c98d32

Please sign in to comment.