Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minimal webfinger #5373

Merged
merged 23 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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