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.