diff --git a/sharedmodel/auth.go b/sharedmodel/auth.go index 6ea3dac..cd231a6 100644 --- a/sharedmodel/auth.go +++ b/sharedmodel/auth.go @@ -1,14 +1,18 @@ package sharedmodel import ( + "google.golang.org/protobuf/types/known/structpb" "gorm.io/gorm" - "whiteboxsystems.nl/openkvpoc/openkv" + "src.whiteboxsystems.nl/DECOZO/okapi" ) +const AuthMethodDecozoMTLS = "http://decozo.org/proto/auth/mtls" +const AuthMethodDecozoBearerToken = "http://decozo.org/proto/auth/bearer-token" + type AuthConfig struct { gorm.Model Raw string - Method openkv.AuthMethod + Method string } func (cfg AuthConfig) Clone() *AuthConfig { @@ -18,19 +22,44 @@ func (cfg AuthConfig) Clone() *AuthConfig { } } -func NewAuthConfig(cfg *openkv.AuthConfig) *AuthConfig { +func (cfg AuthConfig) ToOkapi() *okapi.ProtocolAuthConfiguration { + conf := &structpb.Struct{} + + switch cfg.Method { + case "BearerToken": + conf, _ = structpb.NewStruct(map[string]interface{}{ + "token": cfg.Raw, + }) + } + + return &okapi.ProtocolAuthConfiguration{ + Method: cfg.Method, + Configuration: conf, + } +} + +func NewAuthConfig(cfg *okapi.ProtocolAuthConfiguration) *AuthConfig { authConfig := &AuthConfig{ Method: cfg.Method, } switch cfg.Method { - case openkv.AuthMethod_JWT: - authConfig.Raw = cfg.GetJwtConfig().GetPublicKey() - case openkv.AuthMethod_APIToken: - authConfig.Raw = cfg.GetApiTokenConfig().GetToken() - case openkv.AuthMethod_mTLS: - authConfig.Raw = cfg.GetMtlsConfig().GetPublicKey() + case "BearerToken": + authConfig.Raw, _ = cfg.GetConfiguration().AsMap()["token"].(string) } return authConfig } + +type XISAuthConfig struct { + gorm.Model + Raw string + Method int32 +} + +func (cfg XISAuthConfig) Clone() *XISAuthConfig { + return &XISAuthConfig{ + Raw: cfg.Raw, + Method: cfg.Method, + } +} diff --git a/sharedmodel/connection.go b/sharedmodel/connection.go index 35753fe..7f04f34 100644 --- a/sharedmodel/connection.go +++ b/sharedmodel/connection.go @@ -6,10 +6,10 @@ import ( type Connection struct { gorm.Model - OrganisationId string - OrganisationIdSystem string - OrganisationDisplayName string - AuthConfigID uint - AuthConfig *AuthConfig - Services []ServiceConfig + OrganisationIdentifier string + OrganisationIdentifierType string + OrganisationDisplayName string + AuthConfigID uint + AuthConfig *XISAuthConfig `gorm:"constraint:OnDelete:CASCADE;"` + Services []ServiceConfig `gorm:"constraint:OnDelete:CASCADE;"` } diff --git a/sharedmodel/model.go b/sharedmodel/model.go index cea4a40..a717a1e 100644 --- a/sharedmodel/model.go +++ b/sharedmodel/model.go @@ -6,12 +6,35 @@ import ( "errors" "fmt" - "whiteboxsystems.nl/openkvpoc/openkv" + "src.whiteboxsystems.nl/DECOZO/okapi" ) type Protocol struct { Protocol string - AuthMethods AuthMethodArray + AuthMethods []string +} + +type ListOfStrings []string + +// Scan scan value into Jsonb, implements sql.Scanner interface +func (j *ListOfStrings) Scan(value interface{}) error { + bytes, ok := value.([]byte) + if !ok { + return errors.New(fmt.Sprint("Failed to unmarshal ListOfStrings value:", value)) + } + + result := []string{} + err := json.Unmarshal(bytes, &result) + *j = ListOfStrings(result) + return err +} + +// Value return json value, implement driver.Valuer interface +func (j ListOfStrings) Value() (driver.Value, error) { + if len(j) == 0 { + return nil, nil + } + return json.Marshal(j) } type ProtocolArray []Protocol @@ -37,7 +60,7 @@ func (j ProtocolArray) Value() (driver.Value, error) { return json.Marshal(j) } -type AuthMethodArray []openkv.AuthMethod +type AuthMethodArray []okapi.ProtocolAuthConfiguration // Scan scan value into Jsonb, implements sql.Scanner interface func (j *AuthMethodArray) Scan(value interface{}) error { @@ -46,7 +69,7 @@ func (j *AuthMethodArray) Scan(value interface{}) error { return errors.New(fmt.Sprint("Failed to unmarshal AuthMethodArray value:", value)) } - result := []openkv.AuthMethod{} + result := []okapi.ProtocolAuthConfiguration{} err := json.Unmarshal(bytes, &result) *j = AuthMethodArray(result) return err diff --git a/sharedmodel/registration.go b/sharedmodel/registration.go index 7250d4b..8352442 100644 --- a/sharedmodel/registration.go +++ b/sharedmodel/registration.go @@ -1,8 +1,12 @@ package sharedmodel import ( + "crypto" + "fmt" + "gorm.io/gorm" - "whiteboxsystems.nl/openkvpoc/openkv" + "src.whiteboxsystems.nl/DECOZO/okapi" + "whiteboxsystems.nl/okapidemo/certgen" ) type RegistrationStatus string @@ -14,29 +18,39 @@ const ( type Registration struct { gorm.Model - OrganisationId string - OrganisationIdSystem string - OrganisationDisplayName string - AuthConfigID uint - AuthConfig *AuthConfig - Reference string - PSK string - Status RegistrationStatus + OrganisationIdentifier string + OrganisationIdentifierType string + OrganisationDisplayName string + AuthConfigID uint + AuthConfig *XISAuthConfig + Reference string + PSK string + Status RegistrationStatus } -func (r *Registration) SetAuthConfig(cfg *openkv.AuthConfig) { - authConfig := &AuthConfig{ - Method: cfg.Method, +func (r *Registration) SetAuthConfig(cfg *okapi.XISAuthConfiguration) error { + authConfig := &XISAuthConfig{ + Method: int32(cfg.Method), } switch cfg.Method { - case openkv.AuthMethod_JWT: - authConfig.Raw = cfg.GetJwtConfig().GetPublicKey() - case openkv.AuthMethod_APIToken: - authConfig.Raw = cfg.GetApiTokenConfig().GetToken() - case openkv.AuthMethod_mTLS: - authConfig.Raw = cfg.GetMtlsConfig().GetPublicKey() + case okapi.XISAuthMethod_mTLS: + k, err := certgen.StringToJWK(cfg.GetMtlsConfiguration().GetPublicKey()) + + if err != nil { + return err + } + + tp, err := k.Thumbprint(crypto.SHA256) + + if err != nil { + return err + } + + authConfig.Raw = fmt.Sprintf("%X", tp) } r.AuthConfig = authConfig + + return nil } diff --git a/sharedmodel/service.go b/sharedmodel/service.go index fb8ef6e..96a9e63 100644 --- a/sharedmodel/service.go +++ b/sharedmodel/service.go @@ -3,25 +3,26 @@ package sharedmodel import ( "encoding/json" + "google.golang.org/protobuf/types/known/structpb" "gorm.io/gorm" - "whiteboxsystems.nl/openkvpoc/openkv" + "src.whiteboxsystems.nl/DECOZO/okapi" ) -type Service struct { +type ServiceDefinition struct { gorm.Model ServiceID string Name string Description string - SubscriptionPolicy openkv.SubscriptionPolicy - ConsentPolicy openkv.ConsentPolicy + SubscriptionPolicy okapi.SubscriptionPolicy + ConsentPolicy okapi.ConsentPolicy FetchProtocols ProtocolArray `gorm:"type:text"` PushProtocols ProtocolArray `gorm:"type:text"` } -func (s Service) GetFetchProtocols() []*openkv.ProtocolDefinition { - protoDefs := []*openkv.ProtocolDefinition{} +func (s ServiceDefinition) GetFetchProtocols() []*okapi.ProtocolDefinition { + protoDefs := []*okapi.ProtocolDefinition{} for _, sd := range s.FetchProtocols { - protoDefs = append(protoDefs, &openkv.ProtocolDefinition{ + protoDefs = append(protoDefs, &okapi.ProtocolDefinition{ Protocol: sd.Protocol, AuthMethods: sd.AuthMethods, }) @@ -30,10 +31,10 @@ func (s Service) GetFetchProtocols() []*openkv.ProtocolDefinition { return protoDefs } -func (s Service) GetPushProtocols() []*openkv.ProtocolDefinition { - protoDefs := []*openkv.ProtocolDefinition{} +func (s ServiceDefinition) GetPushProtocols() []*okapi.ProtocolDefinition { + protoDefs := []*okapi.ProtocolDefinition{} for _, sd := range s.PushProtocols { - protoDefs = append(protoDefs, &openkv.ProtocolDefinition{ + protoDefs = append(protoDefs, &okapi.ProtocolDefinition{ Protocol: sd.Protocol, AuthMethods: sd.AuthMethods, }) @@ -46,7 +47,7 @@ type ProtocolConfig struct { gorm.Model Protocol string AuthConfigID uint - AuthConfig *AuthConfig + AuthConfig *AuthConfig `gorm:"constraint:OnDelete:CASCADE;"` Config string } @@ -54,6 +55,15 @@ func (pc ProtocolConfig) UnmarshalConfig(in interface{}) error { return json.Unmarshal([]byte(pc.Config), in) } +func (pc ProtocolConfig) ConfigToOkapi() *structpb.Struct { + config := map[string]interface{}{} + pc.UnmarshalConfig(&config) + + cnf, _ := structpb.NewStruct(config) + + return cnf +} + func (pc *ProtocolConfig) SetConfig(in interface{}) error { b, err := json.Marshal(in) if err != nil { @@ -67,13 +77,12 @@ func (pc *ProtocolConfig) SetConfig(in interface{}) error { type ServiceConfig struct { gorm.Model ServiceID uint - Service Service - Enabled bool + Service ServiceDefinition ConnectionID uint Connection Connection `json:"-"` PushProtocolID uint - PushProtocol *ProtocolConfig `gorm:"foreignKey:PushProtocolID"` + PushProtocol *ProtocolConfig `gorm:"foreignKey:PushProtocolID;constraint:OnDelete:CASCADE;"` FetchProtocolID uint - FetchProtocol *ProtocolConfig `gorm:"foreignKey:FetchProtocolID"` - Subscriptions []*Subscription + FetchProtocol *ProtocolConfig `gorm:"foreignKey:FetchProtocolID;constraint:OnDelete:CASCADE;"` + Subscriptions []*Subscription `gorm:"constraint:OnDelete:CASCADE;"` } diff --git a/sharedmodel/subscription.go b/sharedmodel/subscription.go index 42d52af..e5485cc 100644 --- a/sharedmodel/subscription.go +++ b/sharedmodel/subscription.go @@ -2,19 +2,33 @@ package sharedmodel import ( "encoding/json" + "time" "gorm.io/gorm" ) type Subscription struct { - gorm.Model - SubjectExternalId string - SubjectExternalIdSystem string - SubjectName string - SubjectBirthdate string - ProtocolMeta string - ServiceConfigID uint - ServiceConfig *ServiceConfig + ID string `gorm:"primarykey"` + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt gorm.DeletedAt `gorm:"index"` + SubjectExternalId string + SubjectExternalIdSystem string + SubjectDisplayName string + SubjectGiven ListOfStrings `gorm:"type:text"` + SubjectOwnName string + SubjectOwnNamePrefix string + SubjectPartnerName string + SubjectPartnerNamePrefix string + SubjectBirthdate string + SubjectAddressStreet string + SubjectAddressStreetNumber string + SubjectAddressPostalCode string + SubjectAddressCity string + SubjectAddressCountry string + ProtocolMeta string + ServiceConfigID uint + ServiceConfig *ServiceConfig } func (s Subscription) GetProtocolMeta(meta interface{}) error {