package provider import ( "net/http" "dynatron.me/x/blasphem/pkg/flow" "dynatron.me/x/blasphem/pkg/storage" ) type Constructor func(storage.Store) (AuthProvider, error) var Providers = make(map[string]Constructor) type AuthProvider interface { // TODO: this should include stepping AuthProviderMetadata ProviderBase() AuthProviderBase FlowSchema() flow.Schema NewCredData() interface{} ValidateCreds(r *http.Request, reqMap map[string]interface{}) (user ProviderUser, success bool) Lookup(ProviderUser) ProviderUser } func Register(providerName string, f func(storage.Store) (AuthProvider, error)) { Providers[providerName] = f } type Credentials struct { ID CredID `json:"id"` UserID UserID `json:"user_id"` AuthProviderType string `json:"auth_provider_type"` AuthProviderID *string `json:"auth_provider_id"` DataRaw *json.RawMessage `json:"data,omitempty"` user ProviderUser `json:"-"` } func (cred *Credentials) MarshalJSON() ([]byte, error) { type CredAlias Credentials // alias so ΓΈ method set and we don't recurse nCd := (*CredAlias)(cred) if cred.user != nil { providerData := cred.user.UserData() if providerData != nil { b, err := json.Marshal(providerData) if err != nil { return nil, err } dr := json.RawMessage(b) nCd.DataRaw = &dr } } return json.Marshal(nCd) } type ProviderUser interface { // TODO: make sure this is sane with all the ProviderUser and UserData type stuff UserData() ProviderUser Credentials() *Credentials } type AuthProviderBase struct { Name string `json:"name"` ID *string `json:"id"` Type string `json:"type"` } type AuthProviderMetadata interface { ProviderName() string ProviderID() *string ProviderType() string } func (bp *AuthProviderBase) ProviderName() string { return bp.Name } func (bp *AuthProviderBase) ProviderID() *string { return bp.ID } func (bp *AuthProviderBase) ProviderType() string { return bp.Type } func (bp *AuthProviderBase) ProviderBase() AuthProviderBase { return *bp }