* initial webfinger stub Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * add webfinger to proxy, return current host Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * some cleanup Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * allow passing multiple rel params Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * introduce interfaces Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * parse oidc auth token Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * add templating, drop chain, use map of relation providers Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * fix ocis url yaml Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * fix typos Co-authored-by: Dominik Schmidt <dschmidt@owncloud.com> * switch to userinfo claims Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * readme cleanup Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * add TODO.md with ideas Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * replace subject on authenticated request responses Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * Apply suggestions from code review Co-authored-by: Martin <github@diemattels.at> * markdown lint Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * return a 401 when bearer token expired, some more docs Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * Apply suggestions from code review Co-authored-by: Martin <github@diemattels.at> * fix docs Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * clarify env var Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * extract handler func Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * use correct service in reflex.conf Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * test relations Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * Update services/webfinger/pkg/config/config.go --------- Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> Co-authored-by: Dominik Schmidt <dschmidt@owncloud.com> Co-authored-by: Martin <github@diemattels.at>
111 lines
3.1 KiB
Go
111 lines
3.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
|
|
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
|
"github.com/owncloud/ocis/v2/services/webfinger/pkg/config"
|
|
"github.com/owncloud/ocis/v2/services/webfinger/pkg/webfinger"
|
|
)
|
|
|
|
const (
|
|
OwnCloudInstanceRel = "http://webfinger.owncloud/rel/server-instance"
|
|
OpenIDConnectRel = "http://openid.net/specs/connect/1.0/issuer"
|
|
)
|
|
|
|
// Service defines the extension handlers.
|
|
type Service interface {
|
|
// Webfinger is the endpoint for retrieving various href relations.
|
|
//
|
|
// GET /.well-known/webfinger?
|
|
// resource=acct%3Acarol%40example.com&
|
|
// rel=http%3A%2F%2Fwebfinger.owncloud%rel%2Fserver-instance
|
|
// HTTP/1.1
|
|
// Host: example.com
|
|
//
|
|
// The server might respond like this:
|
|
//
|
|
// HTTP/1.1 200 OK
|
|
// Access-Control-Allow-Origin: *
|
|
// Content-Type: application/jrd+json
|
|
//
|
|
// {
|
|
// "subject" : "acct:carol@example.com",
|
|
// "links" :
|
|
// [
|
|
// {
|
|
// "rel" : "http://webfinger.owncloud/rel/server-instance",
|
|
// "href" : "https://instance.example.com",
|
|
// "titles": {
|
|
// "en": "Readable Instance Name"
|
|
// }
|
|
// },
|
|
// {
|
|
// "rel" : "http://webfinger.owncloud/rel/server-instance",
|
|
// "href" : "https://otherinstance.example.com",
|
|
// "titles": {
|
|
// "en": "Other Readable Instance Name"
|
|
// }
|
|
// }
|
|
// ]
|
|
// }
|
|
Webfinger(ctx context.Context, queryTarget *url.URL, rels []string) (webfinger.JSONResourceDescriptor, error)
|
|
}
|
|
|
|
type RelationProvider interface {
|
|
Add(ctx context.Context, jrd *webfinger.JSONResourceDescriptor)
|
|
}
|
|
|
|
// New returns a new instance of Service
|
|
func New(opts ...Option) (Service, error) {
|
|
options := newOptions(opts...)
|
|
|
|
// TODO use fallback implementations of InstanceIdLookup and InstanceLookup?
|
|
// The InstanceIdLookup may have to happen earlier?
|
|
|
|
return svc{
|
|
log: options.Logger,
|
|
config: options.Config,
|
|
relationProviders: options.RelationProviders,
|
|
}, nil
|
|
}
|
|
|
|
type svc struct {
|
|
config *config.Config
|
|
log log.Logger
|
|
relationProviders map[string]RelationProvider
|
|
}
|
|
|
|
// TODO implement different implementations:
|
|
// static one returning the href or a configureable domain
|
|
// regex one returning different instances based on the regex that matches
|
|
// claim one that reads a claim and then fetches the instance?
|
|
// that is actually two interfaces / steps:
|
|
// - one that determines the instances/schools id (read from claim, regex match)
|
|
// - one that looks up in instance by id (use template, read from json, read from ldap, read from graph)
|
|
|
|
// Webfinger implements the service interface
|
|
func (s svc) Webfinger(ctx context.Context, queryTarget *url.URL, rel []string) (webfinger.JSONResourceDescriptor, error) {
|
|
|
|
jrd := webfinger.JSONResourceDescriptor{
|
|
Subject: queryTarget.String(),
|
|
}
|
|
|
|
if len(rel) == 0 {
|
|
// add all configured relation providers
|
|
for _, relation := range s.relationProviders {
|
|
relation.Add(ctx, &jrd)
|
|
}
|
|
} else {
|
|
// only add requested relations
|
|
for _, r := range rel {
|
|
if relation, ok := s.relationProviders[r]; ok {
|
|
relation.Add(ctx, &jrd)
|
|
}
|
|
}
|
|
}
|
|
|
|
return jrd, nil
|
|
}
|