Files
opencloud/services/webfinger/pkg/command/server.go
Ralf Haferkamp 4f1aca6d90 feat(webfinger): use webfinger properties instead new relations
This works the previous commits so that clients can add an addtional
'platform' query parameter to the webfinger request that  can be used
to query the oidc client id and list of scopes that the clients need
to use when connecting to the IDP.

This also removes the non-standard issuer relatation introduced in a
previous commit as we can just introduce new relations in the
http://openid.net name space.

For IDP like Authentik that create a separate issuer url per Client
(Application in Authentik's terms) it is suggested to just configure
as single Client and use that id for all platforms (i.e. setting
'WEBFINGER_ANDROID_OIDC_CLIENT_ID', 'WEBFINGER_DESKTOP_OIDC_CLIENT_ID',
'WEBFINGER_IOS_OIDC_CLIENT_ID' and 'WEBFINGER_WEB_OIDC_CLIENT_ID' to
same value.

Related: #2088
Related: https://github.com/opencloud-eu/desktop/issues/246
2026-02-17 10:41:35 +01:00

137 lines
3.9 KiB
Go

package command
import (
"context"
"fmt"
"os/signal"
"github.com/opencloud-eu/opencloud/pkg/config/configlog"
"github.com/opencloud-eu/opencloud/pkg/log"
"github.com/opencloud-eu/opencloud/pkg/runner"
"github.com/opencloud-eu/opencloud/pkg/tracing"
"github.com/opencloud-eu/opencloud/pkg/version"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/config"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/config/parser"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/metrics"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/relations"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/server/debug"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/server/http"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/service/v0"
"github.com/spf13/cobra"
)
// Server is the entrypoint for the server command.
func Server(cfg *config.Config) *cobra.Command {
return &cobra.Command{
Use: "server",
Short: fmt.Sprintf("start the %s service without runtime (unsupervised mode)", cfg.Service.Name),
PreRunE: func(cmd *cobra.Command, args []string) error {
return configlog.ReturnFatal(parser.ParseConfig(cfg))
},
RunE: func(cmd *cobra.Command, args []string) error {
logger := log.Configure(cfg.Service.Name, cfg.Commons, cfg.LogLevel)
traceProvider, err := tracing.GetTraceProvider(cmd.Context(), cfg.Commons.TracesExporter, cfg.Service.Name)
if err != nil {
return err
}
var cancel context.CancelFunc
if cfg.Context == nil {
cfg.Context, cancel = signal.NotifyContext(context.Background(), runner.StopSignals...)
defer cancel()
}
ctx := cfg.Context
m := metrics.New(metrics.Logger(logger))
m.BuildInfo.WithLabelValues(version.GetString()).Set(1)
gr := runner.NewGroup()
{
relationProviders, err := getRelationProviders(cfg)
if err != nil {
logger.Error().Err(err).Msg("relation provider init")
return err
}
svc, err := service.New(
service.Logger(logger),
service.Config(cfg),
service.WithRelationProviders(relationProviders),
)
if err != nil {
logger.Error().Err(err).Msg("handler init")
return err
}
svc = service.NewInstrument(svc, m)
svc = service.NewLogging(svc, logger) // this logs service specific data
svc = service.NewTracing(svc, traceProvider)
server, err := http.Server(
http.Logger(logger),
http.Context(ctx),
http.Config(cfg),
http.Service(svc),
http.TraceProvider(traceProvider),
)
if err != nil {
logger.Info().
Err(err).
Str("server", "http").
Msg("Failed to initialize server")
return err
}
gr.Add(runner.NewGoMicroHttpServerRunner(cfg.Service.Name+".http", server))
}
{
debugServer, err := debug.Server(
debug.Logger(logger),
debug.Context(ctx),
debug.Config(cfg),
)
if err != nil {
logger.Info().Err(err).Str("transport", "debug").Msg("Failed to initialize server")
return err
}
gr.Add(runner.NewGolangHttpServerRunner(cfg.Service.Name+".debug", debugServer))
}
grResults := gr.Run(ctx)
// return the first non-nil error found in the results
for _, grResult := range grResults {
if grResult.RunnerError != nil {
return grResult.RunnerError
}
}
return nil
},
}
}
func getRelationProviders(cfg *config.Config) (map[string]service.RelationProvider, error) {
rels := map[string]service.RelationProvider{}
for _, relationURI := range cfg.Relations {
switch relationURI {
case relations.OpenIDConnectRel:
rels[relationURI] = relations.OpenIDDiscovery(cfg.IDP, cfg.OIDCClientConfigs)
case relations.OpenCloudInstanceRel:
var err error
rels[relationURI], err = relations.OpenCloudInstance(cfg.Instances, cfg.OpenCloudURL)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unknown relation '%s'", relationURI)
}
}
return rels, nil
}