Skip to content

Commit

Permalink
Recover "WPB-5204 Remove unused APNS_VOIP code (#3695)" (#3967)
Browse files Browse the repository at this point in the history
* Recover "WPB-5204 Remove unused APNS_VOIP code (#3695)"

This reverts commit 133a740.

* Fix: do not choke on deprecated APNSVoIP* transport tokens.
  • Loading branch information
fisx authored Mar 21, 2024
1 parent 53989b5 commit 232a882
Show file tree
Hide file tree
Showing 22 changed files with 48 additions and 146 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove support for push token transport types APNSVoIP, APNSVoIPSandbox from gundeck.
3 changes: 0 additions & 3 deletions libs/gundeck-types/src/Gundeck/Types/Push/V2.hs
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,14 @@ newtype ApsLocKey = ApsLocKey {fromLocKey :: Text}

data ApsPreference
= ApsStdPreference
| ApsVoIPPreference
deriving (Eq, Show, Generic)
deriving (Arbitrary) via GenericUniform ApsPreference

instance ToJSON ApsPreference where
toJSON ApsVoIPPreference = "voip"
toJSON ApsStdPreference = "std"

instance FromJSON ApsPreference where
parseJSON = withText "ApsPreference" $ \case
"voip" -> pure ApsVoIPPreference
"std" -> pure ApsStdPreference
x -> fail $ "Invalid preference: " ++ show x

Expand Down
8 changes: 1 addition & 7 deletions libs/wire-api/src/Wire/API/Push/V2/Token.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ data Transport
= GCM
| APNS
| APNSSandbox
| APNSVoIP
| APNSVoIPSandbox
deriving stock (Eq, Ord, Show, Bounded, Enum, Generic)
deriving (Arbitrary) via (GenericUniform Transport)
deriving (A.ToJSON, A.FromJSON, S.ToSchema) via (Schema Transport)
Expand All @@ -127,9 +125,7 @@ instance ToSchema Transport where
mconcat
[ element "GCM" GCM,
element "APNS" APNS,
element "APNS_SANDBOX" APNSSandbox,
element "APNS_VOIP" APNSVoIP,
element "APNS_VOIP_SANDBOX" APNSVoIPSandbox
element "APNS_SANDBOX" APNSSandbox
]

instance FromByteString Transport where
Expand All @@ -138,8 +134,6 @@ instance FromByteString Transport where
"GCM" -> pure GCM
"APNS" -> pure APNS
"APNS_SANDBOX" -> pure APNSSandbox
"APNS_VOIP" -> pure APNSVoIP
"APNS_VOIP_SANDBOX" -> pure APNSVoIPSandbox
x -> fail $ "Invalid push transport: " <> show x

newtype Token = Token
Expand Down
6 changes: 0 additions & 6 deletions libs/wire-api/test/golden/Test/Wire/API/Golden/Generated.hs
Original file line number Diff line number Diff line change
Expand Up @@ -791,12 +791,6 @@ tests =
),
( Test.Wire.API.Golden.Generated.Push_2eToken_2eTransport_user.testObject_Push_2eToken_2eTransport_user_3,
"testObject_Push_2eToken_2eTransport_user_3.json"
),
( Test.Wire.API.Golden.Generated.Push_2eToken_2eTransport_user.testObject_Push_2eToken_2eTransport_user_4,
"testObject_Push_2eToken_2eTransport_user_4.json"
),
( Test.Wire.API.Golden.Generated.Push_2eToken_2eTransport_user.testObject_Push_2eToken_2eTransport_user_5,
"testObject_Push_2eToken_2eTransport_user_5.json"
)
],
testGroup "Golden: Token_user" $
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

module Test.Wire.API.Golden.Generated.Push_2eToken_2eTransport_user where

import Wire.API.Push.Token (Transport (APNS, APNSSandbox, APNSVoIP, APNSVoIPSandbox, GCM))
import Wire.API.Push.Token (Transport (APNS, APNSSandbox, GCM))
import Wire.API.Push.Token qualified as Push.Token (Transport)

testObject_Push_2eToken_2eTransport_user_1 :: Push.Token.Transport
Expand All @@ -28,9 +28,3 @@ testObject_Push_2eToken_2eTransport_user_2 = APNS

testObject_Push_2eToken_2eTransport_user_3 :: Push.Token.Transport
testObject_Push_2eToken_2eTransport_user_3 = APNSSandbox

testObject_Push_2eToken_2eTransport_user_4 :: Push.Token.Transport
testObject_Push_2eToken_2eTransport_user_4 = APNSVoIP

testObject_Push_2eToken_2eTransport_user_5 :: Push.Token.Transport
testObject_Push_2eToken_2eTransport_user_5 = APNSVoIPSandbox
4 changes: 0 additions & 4 deletions libs/wire-api/test/golden/Test/Wire/API/Golden/Manual.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import Test.Wire.API.Golden.Manual.QualifiedUserClientPrekeyMap
import Test.Wire.API.Golden.Manual.SearchResultContact
import Test.Wire.API.Golden.Manual.SubConversation
import Test.Wire.API.Golden.Manual.TeamSize
import Test.Wire.API.Golden.Manual.Token
import Test.Wire.API.Golden.Manual.UserClientPrekeyMap
import Test.Wire.API.Golden.Manual.UserEvent
import Test.Wire.API.Golden.Manual.UserIdList
Expand Down Expand Up @@ -145,9 +144,6 @@ tests =
testGroup "GroupId" $
testObjects
[(testObject_GroupId_1, "testObject_GroupId_1.json")],
testGroup "PushToken" $
testObjects
[(testObject_Token_1, "testObject_Token_1.json")],
testGroup "TeamSize" $
testObjects
[ (testObject_TeamSize_1, "testObject_TeamSize_1.json"),
Expand Down
29 changes: 0 additions & 29 deletions libs/wire-api/test/golden/Test/Wire/API/Golden/Manual/Token.hs

This file was deleted.

This file was deleted.

This file was deleted.

6 changes: 0 additions & 6 deletions libs/wire-api/test/golden/testObject_Token_1.json

This file was deleted.

2 changes: 1 addition & 1 deletion libs/wire-api/test/unit/Test/Wire/API/MLS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ spawn cp minput = do
in snd <$> concurrently writeInput readOutput
case (mout, ex) of
(Just out, ExitSuccess) -> pure out
_ -> assertFailure "Failed spawning process"
_ -> assertFailure $ "Failed spawning process\n" <> show mout <> "\n" <> show ex

cli :: String -> FilePath -> [String] -> CreateProcess
cli store tmp args =
Expand Down
1 change: 0 additions & 1 deletion libs/wire-api/wire-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,6 @@ test-suite wire-api-golden-tests
Test.Wire.API.Golden.Manual.SearchResultContact
Test.Wire.API.Golden.Manual.SubConversation
Test.Wire.API.Golden.Manual.TeamSize
Test.Wire.API.Golden.Manual.Token
Test.Wire.API.Golden.Manual.UserClientPrekeyMap
Test.Wire.API.Golden.Manual.UserEvent
Test.Wire.API.Golden.Manual.UserIdList
Expand Down
4 changes: 1 addition & 3 deletions services/brig/docs/swagger-v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
"enum": [
"GCM",
"APNS",
"APNS_SANDBOX",
"APNS_VOIP",
"APNS_VOIP_SANDBOX"
"APNS_SANDBOX"
],
"type": "string"
},
Expand Down
4 changes: 1 addition & 3 deletions services/brig/docs/swagger-v4.json
Original file line number Diff line number Diff line change
Expand Up @@ -4828,9 +4828,7 @@
"enum": [
"GCM",
"APNS",
"APNS_SANDBOX",
"APNS_VOIP",
"APNS_VOIP_SANDBOX"
"APNS_SANDBOX"
],
"type": "string"
},
Expand Down
19 changes: 5 additions & 14 deletions services/gundeck/src/Gundeck/Aws.hs
Original file line number Diff line number Diff line change
Expand Up @@ -369,17 +369,12 @@ newtype Attributes = Attributes

-- Note [VoIP TTLs]
-- ~~~~~~~~~~~~~~~~
-- The TTL message attributes for APNS_VOIP and APNS_VOIP_SANDBOX are not
-- documented but appear to work. The reason might be that TTLs were
-- introduced before support for VoIP notifications. There is a catch,
-- however. For GCM, APNS and APNS_SANDBOX, SNS treats the TTL "0"
-- For GCM, APNS and APNS_SANDBOX, SNS treats the TTL "0"
-- specially, i.e. it forwards it to the provider where it has a special
-- meaning. That does not appear to be the case for APNS_VOIP and
-- APNS_VOIP_SANDBOX, for which the TTL is interpreted normally, which means
-- if the TTL is lower than the "dwell time" in SNS, the notification is
-- never sent to the provider. So we must specify a reasonably large TTL
-- for transient VoIP notifications, so that they are not discarded
-- already by SNS.
-- meaning. Which means if the TTL is lower than the "dwell time" in SNS,
-- the notification is never sent to the provider. So we must specify a
-- reasonably large TTL for transient VoIP notifications, so that they are
-- not discarded already by SNS.
--
-- cf. http://docs.aws.amazon.com/sns/latest/dg/sns-ttl.html

Expand All @@ -395,13 +390,9 @@ timeToLive t s = Attributes (Endo (ttlAttr s))
ttlNow GCM = "0"
ttlNow APNS = "0"
ttlNow APNSSandbox = "0"
ttlNow APNSVoIP = "15" -- See note [VoIP TTLs]
ttlNow APNSVoIPSandbox = "15" -- See note [VoIP TTLs]
ttlKey GCM = "AWS.SNS.MOBILE.GCM.TTL"
ttlKey APNS = "AWS.SNS.MOBILE.APNS.TTL"
ttlKey APNSSandbox = "AWS.SNS.MOBILE.APNS_SANDBOX.TTL"
ttlKey APNSVoIP = "AWS.SNS.MOBILE.APNS_VOIP.TTL"
ttlKey APNSVoIPSandbox = "AWS.SNS.MOBILE.APNS_VOIP_SANDBOX.TTL"

publish :: EndpointArn -> LT.Text -> Attributes -> Amazon (Either PublishError ())
publish arn txt attrs = do
Expand Down
4 changes: 0 additions & 4 deletions services/gundeck/src/Gundeck/Aws/Arn.hs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ arnTransportText :: Transport -> Text
arnTransportText GCM = "GCM"
arnTransportText APNS = "APNS"
arnTransportText APNSSandbox = "APNS_SANDBOX"
arnTransportText APNSVoIP = "APNS_VOIP"
arnTransportText APNSVoIPSandbox = "APNS_VOIP_SANDBOX"

-- Parsers --------------------------------------------------------------------

Expand Down Expand Up @@ -165,7 +163,5 @@ endpointTopicParser = do
transportParser :: Parser Transport
transportParser =
string "GCM" $> GCM
<|> string "APNS_VOIP_SANDBOX" $> APNSVoIPSandbox
<|> string "APNS_VOIP" $> APNSVoIP
<|> string "APNS_SANDBOX" $> APNSSandbox
<|> string "APNS" $> APNS
23 changes: 12 additions & 11 deletions services/gundeck/src/Gundeck/Instances.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,22 @@ import Gundeck.Aws.Arn (EndpointArn)
import Gundeck.Types
import Imports

instance Cql Transport where
-- | We provide a instance for `Either Int Transport` so we can handle (ie., gracefully ignore
-- rather than crash on) deprecated values in cassandra. See "Gundeck.Push.Data".
instance Cql (Either Int32 Transport) where
ctype = Tagged IntColumn

toCql GCM = CqlInt 0
toCql APNS = CqlInt 1
toCql APNSSandbox = CqlInt 2
toCql APNSVoIP = CqlInt 3
toCql APNSVoIPSandbox = CqlInt 4
toCql (Right GCM) = CqlInt 0
toCql (Right APNS) = CqlInt 1
toCql (Right APNSSandbox) = CqlInt 2
toCql (Left i) = CqlInt i -- (this is weird, but it's helpful for cleaning up deprecated tokens.)

fromCql (CqlInt i) = case i of
0 -> pure GCM
1 -> pure APNS
2 -> pure APNSSandbox
3 -> pure APNSVoIP
4 -> pure APNSVoIPSandbox
0 -> pure $ Right GCM
1 -> pure $ Right APNS
2 -> pure $ Right APNSSandbox
3 -> pure (Left 3) -- `APNSVoIPV1` tokens are deprecated and will be ignored
4 -> pure (Left 4) -- `APNSVoIPSandboxV1` tokens are deprecated and will be ignored
n -> Left $ "unexpected transport: " ++ show n
fromCql _ = Left "transport: int expected"

Expand Down
23 changes: 4 additions & 19 deletions services/gundeck/src/Gundeck/Push.hs
Original file line number Diff line number Diff line change
Expand Up @@ -374,31 +374,16 @@ nativeTargets psh rcps' alreadySent =
null (psh ^. pushConnections)
|| a ^. addrConn `elem` psh ^. pushConnections
-- Apply transport preference in case of alternative transports for the
-- same client (currently only APNS vs APNS VoIP). If no explicit
-- preference is given, the default preference depends on the priority.
-- same client. If no explicit preference is given, the default preference depends on the priority.
preference as =
let pref = psh ^. pushNativeAps >>= view apsPreference
in filter (pick (fromMaybe defPreference pref)) as
where
pick pr a = case a ^. addrTransport of
GCM -> True
APNS -> pr == ApsStdPreference || notAny a APNSVoIP
APNSSandbox -> pr == ApsStdPreference || notAny a APNSVoIPSandbox
APNSVoIP -> pr == ApsVoIPPreference || notAny a APNS
APNSVoIPSandbox -> pr == ApsVoIPPreference || notAny a APNSSandbox
notAny a t =
not
( any
( \a' ->
addrEqualClient a a'
&& a ^. addrApp == a' ^. addrApp
&& a' ^. addrTransport == t
)
as
)
defPreference = case psh ^. pushNativePriority of
LowPriority -> ApsStdPreference
HighPriority -> ApsVoIPPreference
APNS -> pr == ApsStdPreference
APNSSandbox -> pr == ApsStdPreference
defPreference = ApsStdPreference
check :: Either SomeException [a] -> m [a]
check (Left e) = mntgtLogErr e >> pure []
check (Right r) = pure r
Expand Down
31 changes: 19 additions & 12 deletions services/gundeck/src/Gundeck/Push/Data.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,29 @@ import System.Logger.Class qualified as Log
lookup :: (MonadClient m, MonadLogger m) => UserId -> Consistency -> m [Address]
lookup u c = foldM mk [] =<< retry x1 (query q (params c (Identity u)))
where
q :: PrepQuery R (Identity UserId) (UserId, Transport, AppName, Token, Maybe EndpointArn, ConnId, Maybe ClientId)
q :: PrepQuery R (Identity UserId) (UserId, Either Int32 Transport, AppName, Token, Maybe EndpointArn, ConnId, Maybe ClientId)
q = "select usr, transport, app, ptoken, arn, connection, client from user_push where usr = ?"
mk as r = maybe as (: as) <$> mkAddr r

insert :: MonadClient m => UserId -> Transport -> AppName -> Token -> EndpointArn -> ConnId -> ClientId -> m ()
insert u t a p e o c = retry x5 $ write q (params LocalQuorum (u, t, a, p, e, o, c))
insert u t a p e o c = retry x5 $ write q (params LocalQuorum (u, Right t, a, p, e, o, c))
where
q :: PrepQuery W (UserId, Transport, AppName, Token, EndpointArn, ConnId, ClientId) ()
q :: PrepQuery W (UserId, Either Int32 Transport, AppName, Token, EndpointArn, ConnId, ClientId) ()
q = "insert into user_push (usr, transport, app, ptoken, arn, connection, client) values (?, ?, ?, ?, ?, ?, ?)"

updateArn :: MonadClient m => UserId -> Transport -> AppName -> Token -> EndpointArn -> m ()
updateArn uid transport app token arn = retry x5 $ write q (params LocalQuorum (arn, uid, transport, app, token))
updateArn uid transport app token arn = retry x5 $ write q (params LocalQuorum (arn, uid, Right transport, app, token))
where
q :: PrepQuery W (EndpointArn, UserId, Transport, AppName, Token) ()
q :: PrepQuery W (EndpointArn, UserId, Either Int32 Transport, AppName, Token) ()
q = {- `IF EXISTS`, but that requires benchmarking -} "update user_push set arn = ? where usr = ? and transport = ? and app = ? and ptoken = ?"

delete :: MonadClient m => UserId -> Transport -> AppName -> Token -> m ()
delete u t a p = retry x5 $ write q (params LocalQuorum (u, t, a, p))
delete u t = deleteAux u (Right t)

deleteAux :: MonadClient m => UserId -> Either Int32 Transport -> AppName -> Token -> m ()
deleteAux u t a p = retry x5 $ write q (params LocalQuorum (u, t, a, p))
where
q :: PrepQuery W (UserId, Transport, AppName, Token) ()
q :: PrepQuery W (UserId, Either Int32 Transport, AppName, Token) ()
q = "delete from user_push where usr = ? and transport = ? and app = ? and ptoken = ?"

erase :: MonadClient m => UserId -> m ()
Expand All @@ -68,16 +71,20 @@ erase u = retry x5 $ write q (params LocalQuorum (Identity u))

mkAddr ::
(MonadClient m, MonadLogger m) =>
(UserId, Transport, AppName, Token, Maybe EndpointArn, ConnId, Maybe ClientId) ->
(UserId, Either Int32 Transport, AppName, Token, Maybe EndpointArn, ConnId, Maybe ClientId) ->
m (Maybe Address)
mkAddr (usr, trp, app, tok, arn, con, clt) = case (clt, arn) of
(Just c, Just a) -> pure $! Just $! Address usr a con (pushToken trp app tok c)
mkAddr (usr, trp, app, tok, arn, con, clt) = case (trp, clt, arn) of
(Right t, Just c, Just a) -> pure $! Just $! Address usr a con (pushToken t app tok c)
_ -> do
Log.info $
field "user" (toByteString usr)
~~ field "transport" (show trp)
~~ field "app" (appNameText app)
~~ field "token" (tokenText tok)
~~ msg (val "Deleting legacy push token without a client or ARN.")
delete usr trp app tok
~~ msg
( val
"Deleting legacy push token without a client or ARN, or with deprecated \
\APNSVoIP* transports (transport type not shown in this message)."
)
deleteAux usr trp app tok
pure Nothing
9 changes: 0 additions & 9 deletions services/gundeck/src/Gundeck/Push/Native/Serialise.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ renderText t prio x = case t of
GCM -> trim "GCM" (jsonString gcmJson)
APNS -> trim "APNS" (jsonString stdApnsJson)
APNSSandbox -> trim "APNS_SANDBOX" (jsonString stdApnsJson)
APNSVoIP -> trim "APNS_VOIP" (jsonString voipApnsJson)
APNSVoIPSandbox -> trim "APNS_VOIP_SANDBOX" (jsonString voipApnsJson)
where
gcmJson =
object
Expand All @@ -67,11 +65,6 @@ renderText t prio x = case t of
[ "aps" .= apsDict,
"data" .= x
]
voipApnsJson =
object
[ "aps" .= object [],
"data" .= x
]
-- https://developer.apple.com/documentation/usernotifications/modifying_content_in_newly_delivered_notifications
-- Must contain `mutable-content: 1` and include an alert dictionary with title, subtitle, or body information.
-- Since we have no useful data here, we send a default payload that gets overridden by the client
Expand All @@ -94,8 +87,6 @@ maxPayloadSize :: Transport -> Int64
maxPayloadSize GCM = 4096
maxPayloadSize APNS = 4096
maxPayloadSize APNSSandbox = 4096
maxPayloadSize APNSVoIP = 5120
maxPayloadSize APNSVoIPSandbox = 5120

gcmPriority :: Priority -> Text
gcmPriority LowPriority = "normal"
Expand Down
Loading

0 comments on commit 232a882

Please sign in to comment.