124 lines
2.9 KiB
Go
124 lines
2.9 KiB
Go
|
package backend
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
|
||
|
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/connector"
|
||
|
"github.com/dexidp/dex/connector/oidc"
|
||
|
"github.com/dexidp/dex/storage"
|
||
|
)
|
||
|
|
||
|
var ErrUnsupportedType = errors.New("unsupported connector type")
|
||
|
|
||
|
type BackendConfig struct {
|
||
|
ID string
|
||
|
Name string
|
||
|
Issuer string
|
||
|
ClientID string
|
||
|
ClientSecret string
|
||
|
RedirectURI string
|
||
|
}
|
||
|
|
||
|
func (bc *BackendConfig) OIDC() oidc.Config {
|
||
|
return oidc.Config{
|
||
|
Issuer: bc.Issuer,
|
||
|
ClientID: bc.ClientID,
|
||
|
ClientSecret: bc.ClientSecret,
|
||
|
RedirectURI: bc.RedirectURI,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (bc *BackendConfig) Storage() (storage.Connector, error) {
|
||
|
oidcJSON, err := json.Marshal(bc.OIDC())
|
||
|
if err != nil {
|
||
|
return storage.Connector{}, fmt.Errorf("failed to serialize oidc config: %w", err)
|
||
|
}
|
||
|
|
||
|
return storage.Connector{
|
||
|
ID: bc.ID,
|
||
|
Type: "oidc",
|
||
|
Name: bc.Name,
|
||
|
Config: oidcJSON,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (bc *BackendConfig) FromConnector(connector storage.Connector) error {
|
||
|
var oidc oidc.Config
|
||
|
if connector.Type != "oidc" {
|
||
|
return ErrUnsupportedType
|
||
|
}
|
||
|
if err := json.Unmarshal(connector.Config, &oidc); err != nil {
|
||
|
return fmt.Errorf("invalid OIDC config: %w", err)
|
||
|
}
|
||
|
bc.ID = connector.ID
|
||
|
bc.Name = connector.Name
|
||
|
bc.ClientID = oidc.ClientID
|
||
|
bc.ClientSecret = oidc.ClientSecret
|
||
|
bc.Issuer = oidc.Issuer
|
||
|
bc.RedirectURI = oidc.RedirectURI
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
type Service interface {
|
||
|
ListBackends() ([]BackendConfig, error)
|
||
|
GetBackend(id string) (BackendConfig, error)
|
||
|
AddBackend(config BackendConfig) error
|
||
|
RemoveBackend(id string) error
|
||
|
}
|
||
|
|
||
|
type concreteBackendService struct {
|
||
|
s storage.Storage
|
||
|
}
|
||
|
|
||
|
func (cbs *concreteBackendService) ListBackends() ([]BackendConfig, error) {
|
||
|
connectors, err := cbs.s.ListConnectors()
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to get connectors from storage: %w", err)
|
||
|
}
|
||
|
var res []BackendConfig
|
||
|
for _, c := range connectors {
|
||
|
|
||
|
// We know that this type is special, we don't want to use it at all here
|
||
|
if c.Type == connector.TypeRefuseAll {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
var b BackendConfig
|
||
|
if err := b.FromConnector(c); err != nil {
|
||
|
return res, err
|
||
|
}
|
||
|
res = append(res, b)
|
||
|
}
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
func (cbs *concreteBackendService) GetBackend(connectorID string) (BackendConfig, error) {
|
||
|
c, err := cbs.s.GetConnector(connectorID)
|
||
|
if err != nil {
|
||
|
return BackendConfig{}, fmt.Errorf("failed to get connector from storage: %w", err)
|
||
|
}
|
||
|
var res BackendConfig
|
||
|
if err := res.FromConnector(c); err != nil {
|
||
|
return BackendConfig{}, err
|
||
|
}
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
func (cbs *concreteBackendService) AddBackend(config BackendConfig) error {
|
||
|
storageConf, err := config.Storage()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to create storage configuration: %w", err)
|
||
|
}
|
||
|
return cbs.s.CreateConnector(storageConf)
|
||
|
}
|
||
|
|
||
|
func (cbs *concreteBackendService) RemoveBackend(connectorID string) error {
|
||
|
return cbs.s.DeleteConnector(connectorID)
|
||
|
}
|
||
|
|
||
|
func New(s storage.Storage) Service {
|
||
|
return &concreteBackendService{s}
|
||
|
}
|