mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-08-23 02:47:16 +02:00
@@ -26,6 +26,8 @@ type APISender struct {
|
||||
CustomField2 nullable.Nullable[vo.OptionalString255] `json:"customField2"`
|
||||
CustomField3 nullable.Nullable[vo.OptionalString255] `json:"customField3"`
|
||||
CustomField4 nullable.Nullable[vo.OptionalString255] `json:"customField4"`
|
||||
OAuthProviderID nullable.Nullable[uuid.UUID] `json:"oauthProviderID"`
|
||||
OAuthProvider *OAuthProvider `json:"oauthProvider"`
|
||||
RequestMethod nullable.Nullable[vo.HTTPMethod] `json:"requestMethod"`
|
||||
RequestURL nullable.Nullable[vo.String255] `json:"requestURL"`
|
||||
RequestHeaders nullable.Nullable[APISenderHeaders] `json:"requestHeaders"`
|
||||
@@ -149,6 +151,13 @@ func (a *APISender) ToDBMap() map[string]interface{} {
|
||||
m["expected_response_body"] = expectedResponseBody.String()
|
||||
}
|
||||
}
|
||||
if a.OAuthProviderID.IsSpecified() {
|
||||
if a.OAuthProviderID.IsNull() {
|
||||
m["o_auth_provider_id"] = nil
|
||||
} else {
|
||||
m["o_auth_provider_id"] = a.OAuthProviderID.MustGet()
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/oapi-codegen/nullable"
|
||||
"github.com/phishingclub/phishingclub/validate"
|
||||
"github.com/phishingclub/phishingclub/vo"
|
||||
)
|
||||
|
||||
// OAuthProvider is a user-configured OAuth 2.0 provider
|
||||
type OAuthProvider struct {
|
||||
ID nullable.Nullable[uuid.UUID] `json:"id"`
|
||||
CreatedAt *time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt"`
|
||||
|
||||
Name nullable.Nullable[vo.String127] `json:"name"`
|
||||
|
||||
// oauth endpoints (user configurable)
|
||||
AuthURL nullable.Nullable[vo.String512] `json:"authURL"`
|
||||
TokenURL nullable.Nullable[vo.String512] `json:"tokenURL"`
|
||||
Scopes nullable.Nullable[vo.String512] `json:"scopes"`
|
||||
|
||||
// user's oauth app credentials
|
||||
ClientID nullable.Nullable[vo.String255] `json:"clientID"`
|
||||
ClientSecret nullable.Nullable[vo.OptionalString255] `json:"clientSecret"` // write-only, never returned
|
||||
|
||||
// current token state (stored as plain text like smtp passwords)
|
||||
AccessToken nullable.Nullable[vo.OptionalString1MB] `json:"-"` // never returned in api
|
||||
RefreshToken nullable.Nullable[vo.OptionalString1MB] `json:"-"` // never returned in api
|
||||
TokenExpiresAt *time.Time `json:"tokenExpiresAt"`
|
||||
|
||||
// authorization metadata
|
||||
AuthorizedEmail nullable.Nullable[vo.OptionalString255] `json:"authorizedEmail"` // email of the account that authorized
|
||||
AuthorizedAt *time.Time `json:"authorizedAt"`
|
||||
|
||||
// status
|
||||
IsAuthorized nullable.Nullable[bool] `json:"isAuthorized"` // whether oauth flow completed
|
||||
|
||||
CompanyID nullable.Nullable[uuid.UUID] `json:"companyID"`
|
||||
Company *Company `json:"company"`
|
||||
}
|
||||
|
||||
// Validate checks if the oauth provider has a valid state
|
||||
func (o *OAuthProvider) Validate() error {
|
||||
if err := validate.NullableFieldRequired("name", o.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validate.NullableFieldRequired("authURL", o.AuthURL); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validate.NullableFieldRequired("tokenURL", o.TokenURL); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validate.NullableFieldRequired("scopes", o.Scopes); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validate.NullableFieldRequired("clientID", o.ClientID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validate.NullableFieldRequired("clientSecret", o.ClientSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToDBMap converts the fields that can be stored or updated to a map
|
||||
func (o *OAuthProvider) ToDBMap() map[string]any {
|
||||
m := map[string]any{}
|
||||
|
||||
if o.Name.IsSpecified() {
|
||||
m["name"] = nil
|
||||
if name, err := o.Name.Get(); err == nil {
|
||||
m["name"] = name.String()
|
||||
}
|
||||
}
|
||||
|
||||
if o.AuthURL.IsSpecified() {
|
||||
m["auth_url"] = nil
|
||||
if authURL, err := o.AuthURL.Get(); err == nil {
|
||||
m["auth_url"] = authURL.String()
|
||||
}
|
||||
}
|
||||
|
||||
if o.TokenURL.IsSpecified() {
|
||||
m["token_url"] = nil
|
||||
if tokenURL, err := o.TokenURL.Get(); err == nil {
|
||||
m["token_url"] = tokenURL.String()
|
||||
}
|
||||
}
|
||||
|
||||
if o.Scopes.IsSpecified() {
|
||||
m["scopes"] = nil
|
||||
if scopes, err := o.Scopes.Get(); err == nil {
|
||||
m["scopes"] = scopes.String()
|
||||
}
|
||||
}
|
||||
|
||||
if o.ClientID.IsSpecified() {
|
||||
m["client_id"] = nil
|
||||
if clientID, err := o.ClientID.Get(); err == nil {
|
||||
m["client_id"] = clientID.String()
|
||||
}
|
||||
}
|
||||
|
||||
if o.ClientSecret.IsSpecified() {
|
||||
if o.ClientSecret.IsNull() {
|
||||
// don't update client secret if null
|
||||
} else {
|
||||
if v, err := o.ClientSecret.Get(); err == nil {
|
||||
// only update if non-empty
|
||||
if v.String() != "" {
|
||||
m["client_secret"] = v.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if o.AccessToken.IsSpecified() {
|
||||
if o.AccessToken.IsNull() {
|
||||
m["access_token"] = ""
|
||||
} else {
|
||||
if v, err := o.AccessToken.Get(); err == nil {
|
||||
m["access_token"] = v.String()
|
||||
} else {
|
||||
m["access_token"] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if o.RefreshToken.IsSpecified() {
|
||||
if o.RefreshToken.IsNull() {
|
||||
m["refresh_token"] = ""
|
||||
} else {
|
||||
if v, err := o.RefreshToken.Get(); err == nil {
|
||||
m["refresh_token"] = v.String()
|
||||
} else {
|
||||
m["refresh_token"] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
if o.TokenExpiresAt != nil {
|
||||
m["token_expires_at"] = o.TokenExpiresAt
|
||||
}
|
||||
|
||||
if o.AuthorizedEmail.IsSpecified() {
|
||||
if o.AuthorizedEmail.IsNull() {
|
||||
m["authorized_email"] = ""
|
||||
} else {
|
||||
if v, err := o.AuthorizedEmail.Get(); err == nil {
|
||||
m["authorized_email"] = v.String()
|
||||
} else {
|
||||
m["authorized_email"] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if o.AuthorizedAt != nil {
|
||||
m["authorized_at"] = o.AuthorizedAt
|
||||
}
|
||||
|
||||
if o.IsAuthorized.IsSpecified() {
|
||||
m["is_authorized"] = nil
|
||||
if isAuthorized, err := o.IsAuthorized.Get(); err == nil {
|
||||
m["is_authorized"] = isAuthorized
|
||||
}
|
||||
}
|
||||
|
||||
if o.CompanyID.IsSpecified() {
|
||||
if o.CompanyID.IsNull() {
|
||||
m["company_id"] = nil
|
||||
} else {
|
||||
m["company_id"] = o.CompanyID.MustGet()
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/oapi-codegen/nullable"
|
||||
"github.com/phishingclub/phishingclub/database"
|
||||
"github.com/phishingclub/phishingclub/vo"
|
||||
)
|
||||
|
||||
// OAuthState represents a temporary state token for oauth flow
|
||||
type OAuthState struct {
|
||||
ID nullable.Nullable[uuid.UUID] `json:"id"`
|
||||
CreatedAt *time.Time `json:"createdAt"`
|
||||
|
||||
// the state token sent to oauth provider
|
||||
StateToken nullable.Nullable[vo.String255] `json:"stateToken"`
|
||||
|
||||
// the oauth provider this state is for
|
||||
OAuthProviderID nullable.Nullable[uuid.UUID] `json:"oauthProviderID"`
|
||||
OAuthProvider *OAuthProvider `json:"oauthProvider"`
|
||||
|
||||
// expiration
|
||||
ExpiresAt *time.Time `json:"expiresAt"`
|
||||
|
||||
// whether this state token has been used
|
||||
Used bool `json:"used"`
|
||||
UsedAt *time.Time `json:"usedAt"`
|
||||
}
|
||||
|
||||
// OAuthStateFromDB converts database model to model
|
||||
func OAuthStateFromDB(db *database.OAuthState) *OAuthState {
|
||||
if db == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
stateToken, err := vo.NewString255(db.StateToken)
|
||||
if err != nil {
|
||||
// fallback to empty if token is invalid (should not happen)
|
||||
stateToken = vo.NewString255Must("")
|
||||
}
|
||||
|
||||
state := &OAuthState{
|
||||
ID: nullable.NewNullableWithValue(db.ID),
|
||||
CreatedAt: db.CreatedAt,
|
||||
StateToken: nullable.NewNullableWithValue(*stateToken),
|
||||
OAuthProviderID: nullable.NewNullableWithValue(db.OAuthProviderID),
|
||||
ExpiresAt: db.ExpiresAt,
|
||||
Used: db.Used,
|
||||
UsedAt: db.UsedAt,
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
Reference in New Issue
Block a user