Documentation ¶
Index ¶
- Constants
- Variables
- func AuthenticationMiddleware(firebaseApp IFirebaseApp) func(http.Handler) http.Handler
- func CheckIsAnonymousUser(ctx context.Context) (bool, error)
- func CloseRespBody(resp *http.Response)
- func ComposeUnpaginatedQuery(ctx context.Context, filter *FilterInput, sort *SortInput, node Node) (*firestore.Query, error)
- func CreateAndEncodeCursor(offset int) *string
- func CreateFirebaseCustomToken(ctx context.Context, uid string) (string, error)
- func CreateFirebaseCustomTokenWithClaims(ctx context.Context, uid string, claims map[string]interface{}) (string, error)
- func CreateNode(ctx context.Context, node Node) (string, time.Time, error)
- func DeleteCollection(ctx context.Context, client *firestore.Client, ref *firestore.CollectionRef, ...) error
- func DeleteNode(ctx context.Context, id string, node Node) (bool, error)
- func EncodeCursor(cursor *Cursor) string
- func ExtractBearerToken(r *http.Request) (string, error)
- func ExtractToken(r *http.Request, header string, prefix string) (string, error)
- func GenerateSafeIdentifier() string
- func GetAPIPaginationParams(pagination *PaginationInput) (url.Values, error)
- func GetAnonymousContext(t *testing.T) context.Context
- func GetAuthToken(ctx context.Context, t *testing.T) *auth.Token
- func GetAuthenticatedContext(t *testing.T) context.Context
- func GetAuthenticatedContextAndToken(t *testing.T) (context.Context, *auth.Token)
- func GetAuthenticatedContextFromUID(ctx context.Context, uid string) (*auth.Token, error)
- func GetCollectionName(n Node) string
- func GetFirebaseAuthClient(ctx context.Context) (*auth.Client, error)
- func GetFirebaseUser(ctx context.Context, creds *LoginCredentials) (*auth.UserRecord, error)
- func GetFirestoreClient(ctx context.Context) (*firestore.Client, error)
- func GetFirestoreClientTestUtil(t *testing.T) *firestore.Client
- func GetFirestoreEnvironmentSuffix() string
- func GetLoggedInUserClaims(ctx context.Context) (map[string]interface{}, error)
- func GetLoggedInUserUID(ctx context.Context) (string, error)
- func GetLoginFunc(ctx context.Context, fc IFirebaseClient) http.HandlerFunc
- func GetOrCreateAnonymousUser(ctx context.Context) (*auth.UserRecord, error)
- func GetOrCreateFirebaseUser(ctx context.Context, email string) (*auth.UserRecord, error)
- func GetUserTokenFromContext(ctx context.Context) (*auth.Token, error)
- func HasValidFirebaseBearerToken(r *http.Request, firebaseApp IFirebaseApp) (bool, map[string]string, *auth.Token)
- func NewString(s string) *string
- func OpString(op enumutils.Operation) (string, error)
- func SaveDataToFirestore(firestoreClient *firestore.Client, collection string, data interface{}) (string, error)
- func ShortenLink(ctx context.Context, longLink string) (string, error)
- func SuffixCollection(c string) string
- func Typeof(v interface{}) string
- func UpdateNode(ctx context.Context, id string, node Node) (time.Time, error)
- func UpdateRecordOnFirestore(firestoreClient *firestore.Client, collection string, id string, ...) error
- func ValidateBearerToken(ctx context.Context, token string) (*auth.Token, error)
- func ValidatePaginationParameters(pagination *PaginationInput) error
- type AuditLog
- type ContextKey
- type Cursor
- type FilterInput
- type FilterParam
- type FirebaseAPNSConfigInput
- type FirebaseAndroidConfigInput
- type FirebaseClient
- type FirebaseRefreshResponse
- type FirebaseSimpleNotificationInput
- type FirebaseTokenExchangePayload
- type FirebaseUserTokens
- type FirebaseWebpushConfigInput
- type ID
- type IDValue
- type IFirebaseApp
- type IFirebaseClient
- type LoginCredentials
- type LoginResponse
- type MockFirebaseApp
- func (fa *MockFirebaseApp) Auth(_ context.Context) (*auth.Client, error)
- func (fa *MockFirebaseApp) Firestore(ctx context.Context) (*firestore.Client, error)
- func (fa *MockFirebaseApp) Messaging(ctx context.Context) (*messaging.Client, error)
- func (fa *MockFirebaseApp) RevokeRefreshTokens(ctx context.Context, uid string) error
- type MockFirebaseClient
- type Model
- type Node
- type PageInfo
- type PaginationInput
- type QueryParam
- type SendNotificationPayload
- type SortInput
- type SortParam
- type UserInfo
Constants ¶
const ( // FirebaseWebAPIKeyEnvVarName is the name of the env var that holds a Firebase web API key // for this project FirebaseWebAPIKeyEnvVarName = "FIREBASE_WEB_API_KEY" // FirebaseCustomTokenSigninURL is the Google Identity Toolkit API for signing in over REST FirebaseCustomTokenSigninURL = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=" // FirebaseRefreshTokenURL is used to request Firebase refresh tokens from Google APIs FirebaseRefreshTokenURL = "https://securetoken.googleapis.com/v1/token?key=" // GoogleApplicationCredentialsEnvVarName is used to obtain service account details from the // local server when necessary e.g when running tests on CI or a local developer setup GoogleApplicationCredentialsEnvVarName = "GOOGLE_APPLICATION_CREDENTIALS" // GoogleProjectNumberEnvVarName is a numeric project number that GoogleProjectNumberEnvVarName = "GOOGLE_PROJECT_NUMBER" // AuthTokenContextKey is used to add/retrieve the Firebase UID on the context AuthTokenContextKey = ContextKey("UID") // HTTPClientTimeoutSecs is used to set HTTP client Timeout setting for a request HTTPClientTimeoutSecs = 10 // TestUserEmail is used by integration tests TestUserEmail = "test@bewell.co.ke" // FDLDomainEnvironmentVariableName is firebase dynamic link domain/URL // e.g https://example-one.page.link or https://example-two.page.link FDLDomainEnvironmentVariableName = "FIREBASE_DYNAMIC_LINKS_DOMAIN" // DefaultPageSize is used to paginate records (e.g those fetched from Firebase) // if there is no user specified page size DefaultPageSize = 100 // Sep is a separator, used to create "opaque" IDs Sep = "|" // DefaultRESTAPIPageSize is the page size to use when calling Slade REST API services if the // client does not specify a page size DefaultRESTAPIPageSize = 100 // MaxRestAPIPageSize is the largest page size we'll request MaxRestAPIPageSize = 250 )
Variables ¶
var UnixEpoch = time.Unix(0, 0)
UnixEpoch is used as our version of "time zero". We don't (shouldn't) change it so it's safe to make it a global.
Functions ¶
func AuthenticationMiddleware ¶ added in v0.0.13
func AuthenticationMiddleware(firebaseApp IFirebaseApp) func(http.Handler) http.Handler
AuthenticationMiddleware decodes the share session cookie and packs the session into context
func CheckIsAnonymousUser ¶
CheckIsAnonymousUser determines if the logged in user is an anonymous user
func CloseRespBody ¶
CloseRespBody closes the body of the supplied HTTP response
func ComposeUnpaginatedQuery ¶
func ComposeUnpaginatedQuery( ctx context.Context, filter *FilterInput, sort *SortInput, node Node, ) (*firestore.Query, error)
ComposeUnpaginatedQuery creates a Cloud Firestore query
func CreateAndEncodeCursor ¶ added in v0.0.12
CreateAndEncodeCursor creates a cursor and immediately encodes it. It panics if it cannot encode the cursor. These cursors use ZERO BASED indexing.
func CreateFirebaseCustomToken ¶
CreateFirebaseCustomToken creates a custom auth token for the user with the indicated UID
func CreateFirebaseCustomTokenWithClaims ¶ added in v0.0.19
func CreateFirebaseCustomTokenWithClaims(ctx context.Context, uid string, claims map[string]interface{}) (string, error)
CreateFirebaseCustomTokenWithClaims creates a custom auth token for the user with the indicated UID with additional claims
func CreateNode ¶
CreateNode creates a Node on Firebase
func DeleteCollection ¶
func DeleteCollection( ctx context.Context, client *firestore.Client, ref *firestore.CollectionRef, batchSize int) error
DeleteCollection deletes a firestore collection
func DeleteNode ¶
DeleteNode retrieves a node from Firestore
func EncodeCursor ¶ added in v0.0.12
EncodeCursor converts a cursor to a string
func ExtractBearerToken ¶ added in v0.0.13
ExtractBearerToken gets a bearer token from an Authorization header.
This is expected to contain a Firebase idToken prefixed with "Bearer "
func ExtractToken ¶ added in v0.0.13
ExtractToken extracts a token with the specified prefix from the specified header
func GenerateSafeIdentifier ¶
func GenerateSafeIdentifier() string
GenerateSafeIdentifier generates a shortened alphanumeric identifier.
func GetAPIPaginationParams ¶ added in v0.0.2
func GetAPIPaginationParams(pagination *PaginationInput) (url.Values, error)
GetAPIPaginationParams composes pagination parameters for use by a REST API that uses offset based pagination
func GetAnonymousContext ¶ added in v0.0.6
GetAnonymousContext returns an anonymous logged in context, useful for test purposes
func GetAuthToken ¶ added in v0.0.6
GetAuthToken ...
func GetAuthenticatedContext ¶ added in v0.0.6
GetAuthenticatedContext returns a logged in context, useful for test purposes
func GetAuthenticatedContextAndToken ¶ added in v0.0.6
GetAuthenticatedContextAndToken returns a logged in context and ID token. It is useful for test purposes
func GetAuthenticatedContextFromUID ¶ added in v0.0.8
GetAuthenticatedContextFromUID creates an auth.Token given a valid uid
func GetCollectionName ¶
GetCollectionName calculates the name to give to a node's collection on Firestore
func GetFirebaseAuthClient ¶
GetFirebaseAuthClient initializes a Firebase Authentication client
func GetFirebaseUser ¶ added in v0.0.17
func GetFirebaseUser(ctx context.Context, creds *LoginCredentials) (*auth.UserRecord, error)
GetFirebaseUser logs in the user with the supplied credentials and returns their Firebase auth user record
func GetFirestoreClient ¶
GetFirestoreClient initializes a Firestore client
func GetFirestoreClientTestUtil ¶ added in v0.0.6
GetFirestoreClientTestUtil ...
func GetFirestoreEnvironmentSuffix ¶
func GetFirestoreEnvironmentSuffix() string
GetFirestoreEnvironmentSuffix get the env suffix where the app is running
func GetLoggedInUserClaims ¶ added in v0.0.19
GetLoggedInUserClaims retrieves the logged in user's token custom claims from the supplied context and returns an error if it does not succeed
func GetLoggedInUserUID ¶ added in v0.0.11
GetLoggedInUserUID retrieves the logged in user's Firebase UID from the supplied context and returns an error if it does not succeed
func GetLoginFunc ¶ added in v0.0.17
func GetLoginFunc(ctx context.Context, fc IFirebaseClient) http.HandlerFunc
GetLoginFunc returns a function that can authenticate against Firebase
func GetOrCreateAnonymousUser ¶ added in v0.0.6
func GetOrCreateAnonymousUser(ctx context.Context) (*auth.UserRecord, error)
GetOrCreateAnonymousUser creates an anonymous user For documentation and test purposes only
func GetOrCreateFirebaseUser ¶
GetOrCreateFirebaseUser retrieves the user record of the user with the given email or creates a new one if no user has the specified email
func GetUserTokenFromContext ¶
GetUserTokenFromContext retrieves a Firebase *auth.Token from the supplied context
func HasValidFirebaseBearerToken ¶ added in v0.0.13
func HasValidFirebaseBearerToken(r *http.Request, firebaseApp IFirebaseApp) (bool, map[string]string, *auth.Token)
HasValidFirebaseBearerToken returns true with no errors if the request has a valid bearer token in the authorization header. Otherwise, it returns false and the error in a map with the key "error"
func OpString ¶
OpString translates between an Operation enum value and the appropriate firestore query operator
func SaveDataToFirestore ¶
func SaveDataToFirestore(firestoreClient *firestore.Client, collection string, data interface{}) (string, error)
SaveDataToFirestore takes the supplied data (which can be a map of string to interface{} or a struct with json/firestore tags), a collection name and an intialized firestore client then tries to save the data to that collection.
func ShortenLink ¶
ShortenLink shortens an FDL link
func SuffixCollection ¶
SuffixCollection adds a suffix to the collection name. This will aid in separating collections for different environments
func UpdateNode ¶
UpdateNode updates an existing node's document on Firestore
func UpdateRecordOnFirestore ¶
func UpdateRecordOnFirestore( firestoreClient *firestore.Client, collection string, id string, data interface{}, ) error
UpdateRecordOnFirestore takes the supplied data (which can be a map of string to interface{} or a struct with json/firestore tags), a collection name and an intialized firestore client then tries to update the data in that object
func ValidateBearerToken ¶
ValidateBearerToken checks the bearer token for validity against Firebase
func ValidatePaginationParameters ¶
func ValidatePaginationParameters(pagination *PaginationInput) error
ValidatePaginationParameters ensures that the supplied pagination parameters make sense
Types ¶
type AuditLog ¶
type AuditLog struct { ID uuid.UUID RecordID uuid.UUID // ID of the audited record TypeName string // type of the audited record Operation string // e.g pre_save, post_save When time.Time // timestamp of the operation UID string // UID of the involved user JSON *json.RawMessage // serialized JSON snapshot }
AuditLog records changes made to models
type ContextKey ¶
type ContextKey string
ContextKey is used as a type for the UID key for the Firebase *auth.Token on context.Context. It is a custom type in order to minimize context key collissions on the context (.and to shut up golint).
type Cursor ¶ added in v0.0.12
type Cursor struct {
Offset int `json:"offset"`
}
Cursor represents an opaque "position" for a record, for use in pagination
type FilterInput ¶
type FilterInput struct { Search *string `json:"search"` FilterBy []*FilterParam `json:"filterBy"` }
FilterInput is s generic container for strongly type filter parameters
type FilterParam ¶
type FilterParam struct { FieldName string `json:"fieldName"` FieldType enumutils.FieldType `json:"fieldType"` ComparisonOperation enumutils.Operation `json:"comparisonOperation"` FieldValue interface{} `json:"fieldValue"` }
FilterParam represents a single field filter parameter
type FirebaseAPNSConfigInput ¶ added in v0.0.3
type FirebaseAPNSConfigInput struct {
Headers map[string]interface{} `json:"headers"`
}
FirebaseAPNSConfigInput is used to set Apple APNS settings
type FirebaseAndroidConfigInput ¶ added in v0.0.3
type FirebaseAndroidConfigInput struct { Priority string `json:"priority"` // one of "normal" or "high" CollapseKey *string `json:"collapseKey"` RestrictedPackageName *string `json:"restrictedPackageName"` Data map[string]interface{} `json:"data"` // if specified, overrides the Data field on Message type }
FirebaseAndroidConfigInput is used to send Firebase Android config values
type FirebaseClient ¶
type FirebaseClient struct{}
FirebaseClient is an implementation of the FirebaseClient interface
func (*FirebaseClient) InitFirebase ¶
func (fc *FirebaseClient) InitFirebase() (IFirebaseApp, error)
InitFirebase ensures that we have a working Firebase configuration
type FirebaseRefreshResponse ¶
type FirebaseRefreshResponse struct { ExpiresIn string `json:"expires_in"` TokenType string `json:"token_type"` RefreshToken string `json:"refresh_token"` IDToken string `json:"id_token"` UserID string `json:"user_id"` ProjectID string `json:"project_id"` }
FirebaseRefreshResponse is used to (de)serialize the results of a successful Firebase token refresh
type FirebaseSimpleNotificationInput ¶ added in v0.0.3
type FirebaseSimpleNotificationInput struct { Title string `json:"title,omitempty"` Body string `json:"body,omitempty"` ImageURL *string `json:"image,omitempty"` Data map[string]interface{} `json:"data,omitempty"` }
FirebaseSimpleNotificationInput is used to create/send simple FCM notifications
type FirebaseTokenExchangePayload ¶
type FirebaseTokenExchangePayload struct { Token string `json:"token"` ReturnSecureToken bool `json:"returnSecureToken"` }
FirebaseTokenExchangePayload is marshalled into JSON and sent to the Firebase Auth REST API when exchanging a custom token for an ID token that can be used to make API calls
type FirebaseUserTokens ¶
type FirebaseUserTokens struct { IDToken string `json:"idToken"` RefreshToken string `json:"refreshToken"` ExpiresIn string `json:"expiresIn"` }
FirebaseUserTokens is the unmarshalling target for the JSON response received from the Firebase Auth REST API when exchanging a custom token for an ID token that can be used to make API calls
func AuthenticateCustomFirebaseToken ¶
func AuthenticateCustomFirebaseToken(customAuthToken string) (*FirebaseUserTokens, error)
AuthenticateCustomFirebaseToken takes a custom Firebase auth token and tries to fetch an ID token If successful, a pointer to the ID token is returned Otherwise, an error is returned
type FirebaseWebpushConfigInput ¶ added in v0.0.3
type FirebaseWebpushConfigInput struct { Headers map[string]interface{} `json:"headers"` Data map[string]interface{} `json:"data"` }
FirebaseWebpushConfigInput is used to set the Firebase web config
type IFirebaseApp ¶
type IFirebaseApp interface { Auth(ctx context.Context) (*auth.Client, error) Firestore(ctx context.Context) (*firestore.Client, error) Messaging(ctx context.Context) (*messaging.Client, error) }
IFirebaseApp is an interface that has been extracted in order to support mocking of Firebase auth in tests
type IFirebaseClient ¶
type IFirebaseClient interface {
InitFirebase() (IFirebaseApp, error)
}
IFirebaseClient defines the Firebase methods that we depend on It has been defined in order to facilitate mocking for tests
type LoginCredentials ¶ added in v0.0.17
type LoginCredentials struct { Username string `json:"username"` Password string `json:"password"` }
LoginCredentials is used to (de)serialize the login username and password
func ValidateLoginCreds ¶ added in v0.0.17
func ValidateLoginCreds(w http.ResponseWriter, r *http.Request) (*LoginCredentials, error)
ValidateLoginCreds checks that the credentials supplied in the indicated request are valid
type LoginResponse ¶ added in v0.0.17
type LoginResponse struct { CustomToken string `json:"custom_token"` ExpiresIn int `json:"expires_in"` IDToken string `json:"id_token"` RefreshToken string `json:"refresh_token"` UID string `json:"uid"` Email string `json:"email"` DisplayName string `json:"display_name"` EmailVerified bool `json:"email_verified"` PhoneNumber string `json:"phone_number"` PhotoURL string `json:"photo_url"` Disabled bool `json:"disabled"` TenantID string `json:"tenant_id"` ProviderID string `json:"provider_id"` }
LoginResponse is used to (de)serialize the result of a successful login You can add more or remove fields to suit your organization/project needs
type MockFirebaseApp ¶
type MockFirebaseApp struct { MockAuthErr error MockAuthClient *auth.Client MockRefreshErr error MockFirestore *firestore.Client MockFirestoreErr error MockMessaging *messaging.Client MockMessagingErr error }
MockFirebaseApp is used to mock the behavior of a Firebase app for testing
func (*MockFirebaseApp) Firestore ¶
Firestore returns a mock Firestore or error, as set on the struct
func (*MockFirebaseApp) Messaging ¶
Messaging returns a mock Firebase Cloud Messaging client or error, as set on the struct
func (*MockFirebaseApp) RevokeRefreshTokens ¶
func (fa *MockFirebaseApp) RevokeRefreshTokens(ctx context.Context, uid string) error
RevokeRefreshTokens returns an error on attempted refresh
type MockFirebaseClient ¶
type MockFirebaseClient struct { MockApp IFirebaseApp MockAppInitErr error MockFirebaseUserTokens *FirebaseUserTokens MockFirebaseAuthError error }
MockFirebaseClient is used to mock the behavior of a Firebase client for testing
func (*MockFirebaseClient) AuthenticateCustomFirebaseToken ¶
func (fc *MockFirebaseClient) AuthenticateCustomFirebaseToken(_ string, _ *http.Client) (*FirebaseUserTokens, error)
AuthenticateCustomFirebaseToken returns mock user tokens or an error, as set on the struct
func (*MockFirebaseClient) InitFirebase ¶
func (fc *MockFirebaseClient) InitFirebase() (IFirebaseApp, error)
InitFirebase returns a mock Firebase app or error, as set on the struct
type Model ¶
type Model struct { ID string `json:"id" firestore:"id"` // All models have a non nullable name field // If a derived model does not need this, it should use a placeholder e.g "-" Name string `json:"name" firestore:"name,omitempty"` // All records have an optional description Description string `json:"description" firestore:"description,omitempty"` // bug alert! If you add "omitempty" to the firestore struct tag, `false` // values will not be saved Deleted bool `json:"deleted,omitempty" firestore:"deleted"` // This is used for audit tracking but is not saved or serialized CreatedByUID string `json:"createdByUID" firestore:"createdByUID,omitempty"` UpdatedByUID string `json:"updatedByUID" firestore:"updatedByUID,omitempty"` }
Model defines common behavior for our models. It is also an ideal place to place hooks that are common to all models e.g audit, streaming analytics etc. CAUTION: Model should be evolved with cautions, because of migrations.
type PageInfo ¶
type PageInfo struct { HasNextPage bool `json:"hasNextPage"` HasPreviousPage bool `json:"hasPreviousPage"` StartCursor *string `json:"startCursor"` EndCursor *string `json:"endCursor"` }
PageInfo is used to add pagination information to Relay edges.
func QueryNodes ¶
func QueryNodes( ctx context.Context, pagination *PaginationInput, filter *FilterInput, sort *SortInput, node Node) ([]*firestore.DocumentSnapshot, *PageInfo, error)
QueryNodes prepares and executes queries against Firebase collections
type PaginationInput ¶
type PaginationInput struct { First int `json:"first"` Last int `json:"last"` After string `json:"after"` Before string `json:"before"` }
PaginationInput represents paging parameters
type QueryParam ¶
QueryParam is an interface used for filter and sort parameters
type SendNotificationPayload ¶ added in v0.0.3
type SendNotificationPayload struct { RegistrationTokens []string `json:"registrationTokens"` Data map[string]string `json:"data"` Notification *FirebaseSimpleNotificationInput `json:"notification"` Android *FirebaseAndroidConfigInput `json:"android"` Ios *FirebaseAPNSConfigInput `json:"ios"` Web *FirebaseWebpushConfigInput `json:"web"` }
SendNotificationPayload is used to serialise and save incoming Send FCM notification requests.
type SortInput ¶
type SortInput struct {
SortBy []*SortParam `json:"sortBy"`
}
SortInput is a generic container for strongly typed sorting parameters
type SortParam ¶
type SortParam struct { FieldName string `json:"fieldName"` SortOrder enumutils.SortOrder `json:"sortOrder"` }
SortParam represents a single field sort parameter
type UserInfo ¶
type UserInfo struct { DisplayName string `json:"displayName,omitempty"` Email string `json:"email,omitempty"` PhoneNumber string `json:"phoneNumber,omitempty"` PhotoURL string `json:"photoUrl,omitempty"` // In the ProviderUserInfo[] ProviderID can be a short domain name (e.g. google.com), // or the identity of an OpenID identity provider. // In UserRecord.UserInfo it will return the constant string "firebase". ProviderID string `json:"providerId,omitempty"` UID string `json:"rawId,omitempty"` }
UserInfo is a collection of standard profile information for a user.