forked from firebase/firebase-admin-go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
iid.go
156 lines (133 loc) · 5.39 KB
/
iid.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package iid contains functions for deleting instance IDs from Firebase projects.
package iid // import "firebase.google.com/go/iid"
import (
"errors"
"fmt"
"net/http"
"golang.org/x/net/context"
"google.golang.org/api/transport"
"firebase.google.com/go/internal"
)
const iidEndpoint = "https://console.firebase.google.com/v1"
const (
invalidArgument = "invalid-argument"
unauthorized = "unauthorized"
insufficientPermission = "insufficient-permission"
notFound = "instance-id-not-found"
alreadyDeleted = "instance-id-already-deleted"
tooManyRequests = "too-many-requests"
internalError = "internal-error"
serverUnavailable = "server-unavailable"
unknown = "unknown-error"
)
var errorCodes = map[int]struct {
code, message string
}{
http.StatusBadRequest: {invalidArgument, "malformed instance id argument"},
http.StatusUnauthorized: {insufficientPermission, "request not authorized"},
http.StatusForbidden: {
insufficientPermission,
"project does not match instance ID or the client does not have sufficient privileges",
},
http.StatusNotFound: {notFound, "failed to find the instance id"},
http.StatusConflict: {alreadyDeleted, "already deleted"},
http.StatusTooManyRequests: {tooManyRequests, "request throttled out by the backend server"},
http.StatusInternalServerError: {internalError, "internal server error"},
http.StatusServiceUnavailable: {serverUnavailable, "backend servers are over capacity"},
}
// IsInvalidArgument checks if the given error was due to an invalid instance ID argument.
func IsInvalidArgument(err error) bool {
return internal.HasErrorCode(err, invalidArgument)
}
// IsInsufficientPermission checks if the given error was due to the request not having the
// required authorization. This could be due to the client not having the required permission
// or the specified instance ID not matching the target Firebase project.
func IsInsufficientPermission(err error) bool {
return internal.HasErrorCode(err, insufficientPermission)
}
// IsNotFound checks if the given error was due to a non existing instance ID.
func IsNotFound(err error) bool {
return internal.HasErrorCode(err, notFound)
}
// IsAlreadyDeleted checks if the given error was due to the instance ID being already deleted from
// the project.
func IsAlreadyDeleted(err error) bool {
return internal.HasErrorCode(err, alreadyDeleted)
}
// IsTooManyRequests checks if the given error was due to the client sending too many requests
// causing a server quota to exceed.
func IsTooManyRequests(err error) bool {
return internal.HasErrorCode(err, tooManyRequests)
}
// IsInternal checks if the given error was due to an internal server error.
func IsInternal(err error) bool {
return internal.HasErrorCode(err, internalError)
}
// IsServerUnavailable checks if the given error was due to the backend server being temporarily
// unavailable.
func IsServerUnavailable(err error) bool {
return internal.HasErrorCode(err, serverUnavailable)
}
// IsUnknown checks if the given error was due to unknown error returned by the backend server.
func IsUnknown(err error) bool {
return internal.HasErrorCode(err, unknown)
}
// Client is the interface for the Firebase Instance ID service.
type Client struct {
// To enable testing against arbitrary endpoints.
endpoint string
client *internal.HTTPClient
project string
}
// NewClient creates a new instance of the Firebase instance ID Client.
//
// This function can only be invoked from within the SDK. Client applications should access the
// the instance ID service through firebase.App.
func NewClient(ctx context.Context, c *internal.InstanceIDConfig) (*Client, error) {
if c.ProjectID == "" {
return nil, errors.New("project id is required to access instance id client")
}
hc, _, err := transport.NewHTTPClient(ctx, c.Opts...)
if err != nil {
return nil, err
}
return &Client{
endpoint: iidEndpoint,
client: &internal.HTTPClient{Client: hc},
project: c.ProjectID,
}, nil
}
// DeleteInstanceID deletes an instance ID from Firebase.
//
// This can be used to delete an instance ID and associated user data from a Firebase project,
// pursuant to the General Data protection Regulation (GDPR).
func (c *Client) DeleteInstanceID(ctx context.Context, iid string) error {
if iid == "" {
return errors.New("instance id must not be empty")
}
url := fmt.Sprintf("%s/project/%s/instanceId/%s", c.endpoint, c.project, iid)
resp, err := c.client.Do(ctx, &internal.Request{Method: http.MethodDelete, URL: url})
if err != nil {
return err
}
if info, ok := errorCodes[resp.Status]; ok {
return internal.Errorf(info.code, "instance id %q: %s", iid, info.message)
}
if err := resp.CheckStatus(http.StatusOK); err != nil {
return internal.Error(unknown, err.Error())
}
return nil
}