Skip to content

Commit

Permalink
chore: Add static clients (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Antoine Gelloz committed Sep 20, 2022
1 parent a503e9e commit 69f49e3
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 31 deletions.
13 changes: 0 additions & 13 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,3 @@ tasks:
install-deps-demo-client:
cmds:
- cd demo && rm package-lock.json && yarn install

create-demo-client:
vars:
CLIENT_ID:
sh: >
curl -X POST 'http://localhost:8080/clients'
-H 'Content-Type: application/json'
-d '{"public": true, "name": "demo", "postLogoutRedirectUris": ["http://localhost:3000/"], "redirectUris": ["http://localhost:3000/auth-callback"]}' | jq -r .data.id
preconditions:
- sh: '[ "{{.CLIENT_ID}}" != "null" ]'
cmds:
- |
echo export const REACT_APP_CLIENT_ID=\'{{.CLIENT_ID}}\' > demo/src/config.js
28 changes: 25 additions & 3 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
"context"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"

auth "github.com/formancehq/auth/pkg"
"github.com/formancehq/auth/pkg/api"
"github.com/formancehq/auth/pkg/delegatedauth"
"github.com/formancehq/auth/pkg/storage"
"github.com/numary/go-libs/sharedlogging"
"github.com/numary/go-libs/sharedotlp/pkg/sharedotlptraces"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.uber.org/fx"
Expand All @@ -24,6 +25,7 @@ const (
delegatedIssuerFlag = "delegated-issuer"
baseUrlFlag = "base-url"
signingKeyFlag = "signing-key"
configFlag = "config"
)

var serveCmd = &cobra.Command{
Expand All @@ -32,7 +34,6 @@ var serveCmd = &cobra.Command{
return bindFlagsToViper(cmd)
},
RunE: func(cmd *cobra.Command, args []string) error {

baseUrl := viper.GetString(baseUrlFlag)
if baseUrl == "" {
return errors.New("base url must be defined")
Expand Down Expand Up @@ -66,10 +67,28 @@ var serveCmd = &cobra.Command{
return err
}

viper.SetConfigName(viper.GetString(configFlag))
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
sharedlogging.GetLogger(cmd.Context()).Infof("no viper config file found")
} else {
return errors.Wrap(err, "reading viper config file")
}
}

type clientOptions struct {
Clients []auth.ClientOptions `json:"clients" yaml:"clients"`
}
o := clientOptions{}
if err := viper.Unmarshal(&o); err != nil {
return errors.Wrap(err, "unmarshal viper config")
}

options := []fx.Option{
fx.Supply(fx.Annotate(cmd.Context(), fx.As(new(context.Context)))),
api.Module(baseUrl, ":8080"),
storage.Module(viper.GetString(postgresUriFlag), key),
storage.Module(viper.GetString(postgresUriFlag), key, o.Clients),
delegatedauth.Module(delegatedauth.Config{
Issuer: delegatedIssuer,
ClientID: delegatedClientID,
Expand All @@ -81,6 +100,7 @@ var serveCmd = &cobra.Command{
}),
fx.NopLogger,
}

if tm := sharedotlptraces.CLITracesModule(viper.GetViper()); tm != nil {
options = append(options, tm)
}
Expand All @@ -105,5 +125,7 @@ func init() {
serveCmd.Flags().String(baseUrlFlag, "http://localhost:8080", "Base service url")
serveCmd.Flags().String(signingKeyFlag, "", "Signing key")

serveCmd.Flags().String(configFlag, "config", "Config file name without extension")

sharedotlptraces.InitOTLPTracesFlags(serveCmd.Flags())
}
8 changes: 8 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
clients:
- id: demo
public: true
redirectUris:
- http://localhost:3000/auth-callback
name: demo
postLogoutRedirectUris:
- http://localhost:3000/
3 changes: 1 addition & 2 deletions demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import './index.css';
import reportWebVitals from './reportWebVitals';
import {OidcProvider, OidcSecure} from "@axa-fr/react-oidc";
import {Info} from "./Info";
import {REACT_APP_CLIENT_ID} from "./config";

const configuration = {
client_id: REACT_APP_CLIENT_ID,
client_id: 'demo',
redirect_uri: 'http://localhost:3000/auth-callback',
silent_redirect_uri: 'http://localhost:3000/silent-auth-callback',
scope: 'openid offline_access email',
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/numary/go-libs v1.0.1
github.com/numary/go-libs/sharedhealth v0.0.0-20220905094731-f6d6d1cf83f3
github.com/numary/go-libs/sharedotlp v0.0.0-20220905094731-f6d6d1cf83f3
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.5.0
github.com/spf13/viper v1.13.0
Expand Down
19 changes: 12 additions & 7 deletions pkg/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,22 @@ func (c *Client) HasScope(id string) bool {
}

type ClientOptions struct {
Public bool `json:"public"`
RedirectUris []string `json:"redirectUris"`
Description string `json:"description"`
Name string `json:"name"`
PostLogoutRedirectUris []string `json:"postLogoutRedirectUris"`
Metadata Metadata `json:"metadata"`
ID string `json:"id" yaml:"id"`
Public bool `json:"public" yaml:"public"`
RedirectUris []string `json:"redirectUris" yaml:"redirectUris"`
Description string `json:"description" yaml:"description"`
Name string `json:"name" yaml:"name"`
PostLogoutRedirectUris []string `json:"postLogoutRedirectUris" yaml:"postLogoutRedirectUris"`
Metadata Metadata `json:"metadata" yaml:"metadata"`
}

func NewClient(opts ClientOptions) *Client {
if opts.ID == "" {
opts.ID = uuid.NewString()
}

client := &Client{
Id: uuid.NewString(),
Id: opts.ID,
ApplicationType: op.ApplicationTypeWeb,
ResponseTypes: []oidc.ResponseType{oidc.ResponseTypeCode},
AccessTokenType: op.AccessTokenTypeJWT,
Expand Down
4 changes: 3 additions & 1 deletion pkg/storage/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package storage
import (
"crypto/rsa"

auth "github.com/formancehq/auth/pkg"
sharedhealth "github.com/numary/go-libs/sharedhealth/pkg"
"github.com/zitadel/oidc/pkg/op"
"go.uber.org/fx"
)

func Module(uri string, key *rsa.PrivateKey) fx.Option {
func Module(uri string, key *rsa.PrivateKey, opts []auth.ClientOptions) fx.Option {
return fx.Options(
gormModule(uri),
fx.Supply(key),
fx.Supply(opts),
fx.Provide(fx.Annotate(New, fx.As(new(Storage)), fx.As(new(op.Storage)))),
sharedhealth.ProvideHealthCheck(func(storage op.Storage) sharedhealth.NamedCheck {
return sharedhealth.NewNamedCheck("Database", sharedhealth.CheckFn(storage.Health))
Expand Down
23 changes: 18 additions & 5 deletions pkg/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ type Storage interface {
var _ Storage = (*storage)(nil)

type storage struct {
signingKey signingKey
db *gorm.DB
relyingParty rp.RelyingParty
signingKey signingKey
db *gorm.DB
relyingParty rp.RelyingParty
staticClients []*auth.Client
}

func (s *storage) ClientCredentialsTokenRequest(ctx context.Context, clientID string, scopes []string) (op.TokenRequest, error) {
Expand Down Expand Up @@ -102,15 +103,21 @@ type signingKey struct {
Key *rsa.PrivateKey
}

func New(db *gorm.DB, relyingParty rp.RelyingParty, key *rsa.PrivateKey) *storage {
func New(db *gorm.DB, relyingParty rp.RelyingParty, key *rsa.PrivateKey, opts []auth.ClientOptions) *storage {
var staticClients []*auth.Client
for _, c := range opts {
staticClients = append(staticClients, auth.NewClient(c))
}

return &storage{
relyingParty: relyingParty,
signingKey: signingKey{
ID: "id",
Algorithm: "RS256",
Key: key,
},
db: db,
staticClients: staticClients,
db: db,
}
}

Expand Down Expand Up @@ -329,6 +336,12 @@ func (s *storage) GetKeySet(ctx context.Context) (*jose.JSONWebKeySet, error) {
// GetClientByClientID implements the op.Storage interface
// it will be called whenever information (type, redirect_uris, ...) about the client behind the client_id is needed
func (s *storage) getClientByClientID(ctx context.Context, clientID string) (*auth.Client, error) {
for _, c := range s.staticClients {
if c.Id == clientID {
return c, nil
}
}

client := &auth.Client{}
return client, s.db.
WithContext(ctx).
Expand Down

0 comments on commit 69f49e3

Please sign in to comment.