@@ -34,21 +34,29 @@ module Wire.API.Push.V2.Token
34
34
Token (.. ),
35
35
AppName (.. ),
36
36
37
- -- * Swagger
38
- modelPushToken ,
39
- modelPushTokenList ,
40
- typeTransport ,
37
+ -- * API types
38
+ AddTokenError (.. ),
39
+ AddTokenSuccess (.. ),
40
+ AddTokenResponses ,
41
+ DeleteTokenResponses ,
41
42
)
42
43
where
43
44
44
- import Control.Lens (makeLenses )
45
- import Data.Aeson
45
+ import Control.Lens (makeLenses , (?~) , (^.) )
46
+ import qualified Data.Aeson as A
46
47
import Data.Attoparsec.ByteString (takeByteString )
47
48
import Data.ByteString.Conversion
48
49
import Data.Id
49
- import Data.Json.Util
50
- import qualified Data.Swagger.Build.Api as Doc
50
+ import Data.SOP
51
+ import Data.Schema
52
+ import Data.Swagger (ToParamSchema )
53
+ import qualified Data.Swagger as S
54
+ import qualified Generics.SOP as GSOP
51
55
import Imports
56
+ import Servant
57
+ import Wire.API.Error
58
+ import qualified Wire.API.Error.Gundeck as E
59
+ import Wire.API.Routes.MultiVerb
52
60
import Wire.Arbitrary (Arbitrary , GenericUniform (.. ))
53
61
54
62
--------------------------------------------------------------------------------
@@ -59,19 +67,14 @@ newtype PushTokenList = PushTokenList
59
67
}
60
68
deriving stock (Eq , Show )
61
69
deriving newtype (Arbitrary )
70
+ deriving (A.ToJSON , A.FromJSON , S.ToSchema ) via (Schema PushTokenList )
62
71
63
- modelPushTokenList :: Doc. Model
64
- modelPushTokenList = Doc. defineModel " PushTokenList" $ do
65
- Doc. description " List of Native Push Tokens"
66
- Doc. property " tokens" (Doc. array (Doc. ref modelPushToken)) $
67
- Doc. description " Push tokens"
68
-
69
- instance ToJSON PushTokenList where
70
- toJSON (PushTokenList t) = object [" tokens" .= t]
71
-
72
- instance FromJSON PushTokenList where
73
- parseJSON = withObject " PushTokenList" $ \ p ->
74
- PushTokenList <$> p .: " tokens"
72
+ instance ToSchema PushTokenList where
73
+ schema =
74
+ objectWithDocModifier " PushTokenList" (description ?~ " List of Native Push Tokens" ) $
75
+ PushTokenList
76
+ <$> pushTokens
77
+ .= fieldWithDocModifier " tokens" (description ?~ " Push tokens" ) (array schema)
75
78
76
79
data PushToken = PushToken
77
80
{ _tokenTransport :: Transport ,
@@ -81,39 +84,29 @@ data PushToken = PushToken
81
84
}
82
85
deriving stock (Eq , Ord , Show , Generic )
83
86
deriving (Arbitrary ) via (GenericUniform PushToken )
87
+ deriving (A.ToJSON , A.FromJSON , S.ToSchema ) via (Schema PushToken )
84
88
85
89
pushToken :: Transport -> AppName -> Token -> ClientId -> PushToken
86
90
pushToken = PushToken
87
91
88
- modelPushToken :: Doc. Model
89
- modelPushToken = Doc. defineModel " PushToken" $ do
90
- Doc. description " Native Push Token"
91
- Doc. property " transport" typeTransport $
92
- Doc. description " Transport"
93
- Doc. property " app" Doc. string' $
94
- Doc. description " Application"
95
- Doc. property " token" Doc. bytes' $
96
- Doc. description " Access Token"
97
- Doc. property " client" Doc. bytes' $ do
98
- Doc. description " Client ID"
99
- Doc. optional
100
-
101
- instance ToJSON PushToken where
102
- toJSON p =
103
- object $
104
- " transport" .= _tokenTransport p
105
- # " app" .= _tokenApp p
106
- # " token" .= _token p
107
- # " client" .= _tokenClient p
108
- # []
109
-
110
- instance FromJSON PushToken where
111
- parseJSON = withObject " PushToken" $ \ p ->
112
- PushToken
113
- <$> p .: " transport"
114
- <*> p .: " app"
115
- <*> p .: " token"
116
- <*> p .: " client"
92
+ instance ToSchema PushToken where
93
+ schema =
94
+ objectWithDocModifier " PushToken" desc $
95
+ PushToken
96
+ <$> _tokenTransport
97
+ .= fieldWithDocModifier " transport" transDesc schema
98
+ <*> _tokenApp
99
+ .= fieldWithDocModifier " app" appDesc schema
100
+ <*> _token
101
+ .= fieldWithDocModifier " token" tokenDesc schema
102
+ <*> _tokenClient
103
+ .= fieldWithDocModifier " client" clientIdDesc schema
104
+ where
105
+ desc = description ?~ " Native Push Token"
106
+ transDesc = description ?~ " Transport"
107
+ appDesc = description ?~ " Application"
108
+ tokenDesc = description ?~ " Access Token"
109
+ clientIdDesc = description ?~ " Client ID"
117
110
118
111
--------------------------------------------------------------------------------
119
112
-- Transport
@@ -126,33 +119,18 @@ data Transport
126
119
| APNSVoIPSandbox
127
120
deriving stock (Eq , Ord , Show , Bounded , Enum , Generic )
128
121
deriving (Arbitrary ) via (GenericUniform Transport )
129
-
130
- typeTransport :: Doc. DataType
131
- typeTransport =
132
- Doc. string $
133
- Doc. enum
134
- [ " GCM" ,
135
- " APNS" ,
136
- " APNS_SANDBOX" ,
137
- " APNS_VOIP" ,
138
- " APNS_VOIP_SANDBOX"
139
- ]
140
-
141
- instance ToJSON Transport where
142
- toJSON GCM = " GCM"
143
- toJSON APNS = " APNS"
144
- toJSON APNSSandbox = " APNS_SANDBOX"
145
- toJSON APNSVoIP = " APNS_VOIP"
146
- toJSON APNSVoIPSandbox = " APNS_VOIP_SANDBOX"
147
-
148
- instance FromJSON Transport where
149
- parseJSON = withText " transport" $ \ case
150
- " GCM" -> pure GCM
151
- " APNS" -> pure APNS
152
- " APNS_SANDBOX" -> pure APNSSandbox
153
- " APNS_VOIP" -> pure APNSVoIP
154
- " APNS_VOIP_SANDBOX" -> pure APNSVoIPSandbox
155
- x -> fail $ " Invalid push transport: " ++ show x
122
+ deriving (A.ToJSON , A.FromJSON , S.ToSchema ) via (Schema Transport )
123
+
124
+ instance ToSchema Transport where
125
+ schema =
126
+ enum @ Text " Access" $
127
+ mconcat
128
+ [ element " GCM" GCM ,
129
+ element " APNS" APNS ,
130
+ element " APNS_SANDBOX" APNSSandbox ,
131
+ element " APNS_VOIP" APNSVoIP ,
132
+ element " APNS_VOIP_SANDBOX" APNSVoIPSandbox
133
+ ]
156
134
157
135
instance FromByteString Transport where
158
136
parser =
@@ -168,12 +146,72 @@ newtype Token = Token
168
146
{ tokenText :: Text
169
147
}
170
148
deriving stock (Eq , Ord , Show )
171
- deriving newtype (FromJSON , ToJSON , FromByteString , ToByteString , Arbitrary )
149
+ deriving newtype (FromHttpApiData , ToHttpApiData , FromByteString , ToByteString , Arbitrary )
150
+ deriving (A.ToJSON , A.FromJSON , S.ToSchema ) via (Schema Token )
151
+
152
+ instance ToParamSchema Token where
153
+ toParamSchema _ = S. toParamSchema (Proxy @ Text )
154
+
155
+ instance ToSchema Token where
156
+ schema = Token <$> tokenText .= schema
172
157
173
158
newtype AppName = AppName
174
159
{ appNameText :: Text
175
160
}
176
161
deriving stock (Eq , Ord , Show )
177
- deriving newtype (FromJSON , ToJSON , IsString , Arbitrary )
162
+ deriving newtype (IsString , Arbitrary )
163
+ deriving (A.ToJSON , A.FromJSON , S.ToSchema ) via (Schema AppName )
164
+
165
+ instance ToSchema AppName where
166
+ schema = AppName <$> appNameText .= schema
178
167
179
168
makeLenses ''PushToken
169
+
170
+ --------------------------------------------------------------------------------
171
+ -- Add token types
172
+
173
+ type AddTokenErrorResponses =
174
+ '[ ErrorResponse 'E.AddTokenErrorNoBudget ,
175
+ ErrorResponse 'E.AddTokenErrorNotFound ,
176
+ ErrorResponse 'E.AddTokenErrorInvalid ,
177
+ ErrorResponse 'E.AddTokenErrorTooLong ,
178
+ ErrorResponse 'E.AddTokenErrorMetadataTooLong
179
+ ]
180
+
181
+ type AddTokenSuccessResponses =
182
+ WithHeaders
183
+ '[ Header " Location" Token
184
+ ]
185
+ AddTokenSuccess
186
+ (Respond 201 " Push token registered" PushToken )
187
+
188
+ type AddTokenResponses = AddTokenErrorResponses .++ '[AddTokenSuccessResponses ]
189
+
190
+ data AddTokenError
191
+ = AddTokenErrorNoBudget
192
+ | AddTokenErrorNotFound
193
+ | AddTokenErrorInvalid
194
+ | AddTokenErrorTooLong
195
+ | AddTokenErrorMetadataTooLong
196
+ deriving (Show , Generic )
197
+ deriving (AsUnion AddTokenErrorResponses ) via GenericAsUnion AddTokenErrorResponses AddTokenError
198
+
199
+ instance GSOP. Generic AddTokenError
200
+
201
+ data AddTokenSuccess = AddTokenSuccess PushToken
202
+
203
+ instance AsHeaders '[Token ] PushToken AddTokenSuccess where
204
+ fromHeaders (I _ :* Nil , t) = AddTokenSuccess t
205
+ toHeaders (AddTokenSuccess t) = (I (t ^. token) :* Nil , t)
206
+
207
+ instance (res ~ AddTokenResponses ) => AsUnion res (Either AddTokenError AddTokenSuccess ) where
208
+ toUnion = eitherToUnion (toUnion @ AddTokenErrorResponses ) (Z . I )
209
+ fromUnion = eitherFromUnion (fromUnion @ AddTokenErrorResponses ) (unI . unZ)
210
+
211
+ --------------------------------------------------------------------------------
212
+ -- Delete token types
213
+
214
+ type DeleteTokenResponses =
215
+ '[ ErrorResponse 'E.TokenNotFound ,
216
+ RespondEmpty 204 " Push token unregistered"
217
+ ]
0 commit comments