@@ -103,6 +103,7 @@ import qualified Wire.API.Provider as Public
103
103
import qualified Wire.API.Provider.Bot as Public (BotUserView )
104
104
import qualified Wire.API.Provider.Service as Public
105
105
import qualified Wire.API.Provider.Service.Tag as Public
106
+ import qualified Wire.API.Team.Feature as Feature
106
107
import Wire.API.Team.LegalHold (LegalholdProtectee (UnprotectedBot ))
107
108
import qualified Wire.API.User as Public (UserProfile , publicProfile )
108
109
import qualified Wire.API.User.Client as Public (Client , ClientCapability (ClientSupportsLegalholdImplicitConsent ), PubClient (.. ), UserClientPrekeyMap , UserClients , userClients )
@@ -319,6 +320,7 @@ routesInternal = do
319
320
320
321
newAccountH :: JsonRequest Public. NewProvider -> (Handler r ) Response
321
322
newAccountH req = do
323
+ guardSecondFactorDisabled Nothing
322
324
setStatus status201 . json <$> (newAccount =<< parseJsonBody req)
323
325
324
326
newAccount :: Public. NewProvider -> (Handler r ) Public. NewProviderResponse
@@ -355,6 +357,7 @@ newAccount new = do
355
357
356
358
activateAccountKeyH :: Code. Key ::: Code. Value -> (Handler r ) Response
357
359
activateAccountKeyH (key ::: val) = do
360
+ guardSecondFactorDisabled Nothing
358
361
maybe (setStatus status204 empty) json <$> activateAccountKey key val
359
362
360
363
activateAccountKey :: Code. Key -> Code. Value -> (Handler r ) (Maybe Public. ProviderActivationResponse )
@@ -381,6 +384,7 @@ activateAccountKey key val = do
381
384
382
385
getActivationCodeH :: Public. Email -> (Handler r ) Response
383
386
getActivationCodeH e = do
387
+ guardSecondFactorDisabled Nothing
384
388
json <$> getActivationCode e
385
389
386
390
getActivationCode :: Public. Email -> (Handler r ) FoundActivationCode
@@ -401,6 +405,7 @@ instance ToJSON FoundActivationCode where
401
405
402
406
approveAccountKeyH :: Code. Key ::: Code. Value -> (Handler r ) Response
403
407
approveAccountKeyH (key ::: val) = do
408
+ guardSecondFactorDisabled Nothing
404
409
empty <$ approveAccountKey key val
405
410
406
411
approveAccountKey :: Code. Key -> Code. Value -> (Handler r ) ()
@@ -415,6 +420,7 @@ approveAccountKey key val = do
415
420
416
421
loginH :: JsonRequest Public. ProviderLogin -> (Handler r ) Response
417
422
loginH req = do
423
+ guardSecondFactorDisabled Nothing
418
424
tok <- login =<< parseJsonBody req
419
425
setProviderCookie tok empty
420
426
@@ -428,6 +434,7 @@ login l = do
428
434
429
435
beginPasswordResetH :: JsonRequest Public. PasswordReset -> (Handler r ) Response
430
436
beginPasswordResetH req = do
437
+ guardSecondFactorDisabled Nothing
431
438
setStatus status201 empty <$ (beginPasswordReset =<< parseJsonBody req)
432
439
433
440
beginPasswordReset :: Public. PasswordReset -> (Handler r ) ()
@@ -449,6 +456,7 @@ beginPasswordReset (Public.PasswordReset target) = do
449
456
450
457
completePasswordResetH :: JsonRequest Public. CompletePasswordReset -> (Handler r ) Response
451
458
completePasswordResetH req = do
459
+ guardSecondFactorDisabled Nothing
452
460
empty <$ (completePasswordReset =<< parseJsonBody req)
453
461
454
462
completePasswordReset :: Public. CompletePasswordReset -> (Handler r ) ()
@@ -469,6 +477,7 @@ completePasswordReset (Public.CompletePasswordReset key val newpwd) = do
469
477
470
478
getAccountH :: ProviderId -> (Handler r ) Response
471
479
getAccountH pid = do
480
+ guardSecondFactorDisabled Nothing
472
481
getAccount pid <&> \ case
473
482
Just p -> json p
474
483
Nothing -> setStatus status404 empty
@@ -478,6 +487,7 @@ getAccount = wrapClientE . DB.lookupAccount
478
487
479
488
updateAccountProfileH :: ProviderId ::: JsonRequest Public. UpdateProvider -> (Handler r ) Response
480
489
updateAccountProfileH (pid ::: req) = do
490
+ guardSecondFactorDisabled Nothing
481
491
empty <$ (updateAccountProfile pid =<< parseJsonBody req)
482
492
483
493
updateAccountProfile :: ProviderId -> Public. UpdateProvider -> (Handler r ) ()
@@ -492,6 +502,7 @@ updateAccountProfile pid upd = do
492
502
493
503
updateAccountEmailH :: ProviderId ::: JsonRequest Public. EmailUpdate -> (Handler r ) Response
494
504
updateAccountEmailH (pid ::: req) = do
505
+ guardSecondFactorDisabled Nothing
495
506
setStatus status202 empty <$ (updateAccountEmail pid =<< parseJsonBody req)
496
507
497
508
updateAccountEmail :: ProviderId -> Public. EmailUpdate -> (Handler r ) ()
@@ -514,6 +525,7 @@ updateAccountEmail pid (Public.EmailUpdate new) = do
514
525
515
526
updateAccountPasswordH :: ProviderId ::: JsonRequest Public. PasswordChange -> (Handler r ) Response
516
527
updateAccountPasswordH (pid ::: req) = do
528
+ guardSecondFactorDisabled Nothing
517
529
empty <$ (updateAccountPassword pid =<< parseJsonBody req)
518
530
519
531
updateAccountPassword :: ProviderId -> Public. PasswordChange -> (Handler r ) ()
@@ -527,6 +539,7 @@ updateAccountPassword pid upd = do
527
539
528
540
addServiceH :: ProviderId ::: JsonRequest Public. NewService -> (Handler r ) Response
529
541
addServiceH (pid ::: req) = do
542
+ guardSecondFactorDisabled Nothing
530
543
setStatus status201 . json <$> (addService pid =<< parseJsonBody req)
531
544
532
545
addService :: ProviderId -> Public. NewService -> (Handler r ) Public. NewServiceResponse
@@ -546,13 +559,16 @@ addService pid new = do
546
559
return $ Public. NewServiceResponse sid rstoken
547
560
548
561
listServicesH :: ProviderId -> (Handler r ) Response
549
- listServicesH pid = json <$> listServices pid
562
+ listServicesH pid = do
563
+ guardSecondFactorDisabled Nothing
564
+ json <$> listServices pid
550
565
551
566
listServices :: ProviderId -> (Handler r ) [Public. Service ]
552
567
listServices = wrapClientE . DB. listServices
553
568
554
569
getServiceH :: ProviderId ::: ServiceId -> (Handler r ) Response
555
570
getServiceH (pid ::: sid) = do
571
+ guardSecondFactorDisabled Nothing
556
572
json <$> getService pid sid
557
573
558
574
getService :: ProviderId -> ServiceId -> (Handler r ) Public. Service
@@ -561,6 +577,7 @@ getService pid sid =
561
577
562
578
updateServiceH :: ProviderId ::: ServiceId ::: JsonRequest Public. UpdateService -> (Handler r ) Response
563
579
updateServiceH (pid ::: sid ::: req) = do
580
+ guardSecondFactorDisabled Nothing
564
581
empty <$ (updateService pid sid =<< parseJsonBody req)
565
582
566
583
updateService :: ProviderId -> ServiceId -> Public. UpdateService -> (Handler r ) ()
@@ -593,6 +610,7 @@ updateService pid sid upd = do
593
610
594
611
updateServiceConnH :: ProviderId ::: ServiceId ::: JsonRequest Public. UpdateServiceConn -> (Handler r ) Response
595
612
updateServiceConnH (pid ::: sid ::: req) = do
613
+ guardSecondFactorDisabled Nothing
596
614
empty <$ (updateServiceConn pid sid =<< parseJsonBody req)
597
615
598
616
updateServiceConn :: ProviderId -> ServiceId -> Public. UpdateServiceConn -> (Handler r ) ()
@@ -638,6 +656,7 @@ updateServiceConn pid sid upd = do
638
656
-- delete the service. See 'finishDeleteService'.
639
657
deleteServiceH :: ProviderId ::: ServiceId ::: JsonRequest Public. DeleteService -> (Handler r ) Response
640
658
deleteServiceH (pid ::: sid ::: req) = do
659
+ guardSecondFactorDisabled Nothing
641
660
setStatus status202 empty <$ (deleteService pid sid =<< parseJsonBody req)
642
661
643
662
-- | The endpoint that is called to delete a service.
@@ -676,6 +695,7 @@ finishDeleteService pid sid = do
676
695
677
696
deleteAccountH :: ProviderId ::: JsonRequest Public. DeleteProvider -> (Handler r ) Response
678
697
deleteAccountH (pid ::: req) = do
698
+ guardSecondFactorDisabled Nothing
679
699
empty <$ (deleteAccount pid =<< parseJsonBody req)
680
700
681
701
deleteAccount :: ProviderId -> Public. DeleteProvider -> (Handler r ) ()
@@ -700,6 +720,7 @@ deleteAccount pid del = do
700
720
701
721
getProviderProfileH :: ProviderId -> (Handler r ) Response
702
722
getProviderProfileH pid = do
723
+ guardSecondFactorDisabled Nothing
703
724
json <$> getProviderProfile pid
704
725
705
726
getProviderProfile :: ProviderId -> (Handler r ) Public. ProviderProfile
@@ -708,13 +729,15 @@ getProviderProfile pid =
708
729
709
730
listServiceProfilesH :: ProviderId -> (Handler r ) Response
710
731
listServiceProfilesH pid = do
732
+ guardSecondFactorDisabled Nothing
711
733
json <$> listServiceProfiles pid
712
734
713
735
listServiceProfiles :: ProviderId -> (Handler r ) [Public. ServiceProfile ]
714
736
listServiceProfiles = wrapClientE . DB. listServiceProfiles
715
737
716
738
getServiceProfileH :: ProviderId ::: ServiceId -> (Handler r ) Response
717
739
getServiceProfileH (pid ::: sid) = do
740
+ guardSecondFactorDisabled Nothing
718
741
json <$> getServiceProfile pid sid
719
742
720
743
getServiceProfile :: ProviderId -> ServiceId -> (Handler r ) Public. ServiceProfile
@@ -723,6 +746,7 @@ getServiceProfile pid sid =
723
746
724
747
searchServiceProfilesH :: Maybe (Public. QueryAnyTags 1 3 ) ::: Maybe Text ::: Range 10 100 Int32 -> (Handler r ) Response
725
748
searchServiceProfilesH (qt ::: start ::: size) = do
749
+ guardSecondFactorDisabled Nothing
726
750
json <$> searchServiceProfiles qt start size
727
751
728
752
-- TODO: in order to actually make it possible for clients to implement
@@ -742,6 +766,7 @@ searchTeamServiceProfilesH ::
742
766
UserId ::: TeamId ::: Maybe (Range 1 128 Text ) ::: Bool ::: Range 10 100 Int32 ->
743
767
(Handler r ) Response
744
768
searchTeamServiceProfilesH (uid ::: tid ::: prefix ::: filterDisabled ::: size) = do
769
+ guardSecondFactorDisabled (Just uid)
745
770
json <$> searchTeamServiceProfiles uid tid prefix filterDisabled size
746
771
747
772
-- NB: unlike 'searchServiceProfiles', we don't filter by service provider here
@@ -763,7 +788,9 @@ searchTeamServiceProfiles uid tid prefix filterDisabled size = do
763
788
wrapClientE $ DB. paginateServiceWhitelist tid prefix filterDisabled (fromRange size)
764
789
765
790
getServiceTagListH :: () -> (Handler r ) Response
766
- getServiceTagListH () = json <$> getServiceTagList ()
791
+ getServiceTagListH () = do
792
+ guardSecondFactorDisabled Nothing
793
+ json <$> getServiceTagList ()
767
794
768
795
getServiceTagList :: () -> Monad m => m Public. ServiceTagList
769
796
getServiceTagList () = return (Public. ServiceTagList allTags)
@@ -772,6 +799,7 @@ getServiceTagList () = return (Public.ServiceTagList allTags)
772
799
773
800
updateServiceWhitelistH :: UserId ::: ConnId ::: TeamId ::: JsonRequest Public. UpdateServiceWhitelist -> (Handler r ) Response
774
801
updateServiceWhitelistH (uid ::: con ::: tid ::: req) = do
802
+ guardSecondFactorDisabled (Just uid)
775
803
resp <- updateServiceWhitelist uid con tid =<< parseJsonBody req
776
804
let status = case resp of
777
805
UpdateServiceWhitelistRespChanged -> status200
@@ -819,6 +847,7 @@ updateServiceWhitelist uid con tid upd = do
819
847
820
848
addBotH :: UserId ::: ConnId ::: ConvId ::: JsonRequest Public. AddBot -> (Handler r ) Response
821
849
addBotH (zuid ::: zcon ::: cid ::: req) = do
850
+ guardSecondFactorDisabled (Just zuid)
822
851
setStatus status201 . json <$> (addBot zuid zcon cid =<< parseJsonBody req)
823
852
824
853
addBot :: UserId -> ConnId -> ConvId -> Public. AddBot -> (Handler r ) Public. AddBotResponse
@@ -897,6 +926,7 @@ addBot zuid zcon cid add = do
897
926
898
927
removeBotH :: UserId ::: ConnId ::: ConvId ::: BotId -> (Handler r ) Response
899
928
removeBotH (zusr ::: zcon ::: cid ::: bid) = do
929
+ guardSecondFactorDisabled (Just zusr)
900
930
maybe (setStatus status204 empty) json <$> removeBot zusr zcon cid bid
901
931
902
932
removeBot :: UserId -> ConnId -> ConvId -> BotId -> (Handler r ) (Maybe Public. RemoveBotResponse )
@@ -918,7 +948,9 @@ removeBot zusr zcon cid bid = do
918
948
-- Bot API
919
949
920
950
botGetSelfH :: BotId -> (Handler r ) Response
921
- botGetSelfH bot = json <$> botGetSelf bot
951
+ botGetSelfH bot = do
952
+ guardSecondFactorDisabled (Just (botUserId bot))
953
+ json <$> botGetSelf bot
922
954
923
955
botGetSelf :: BotId -> (Handler r ) Public. UserProfile
924
956
botGetSelf bot = do
@@ -927,6 +959,7 @@ botGetSelf bot = do
927
959
928
960
botGetClientH :: BotId -> (Handler r ) Response
929
961
botGetClientH bot = do
962
+ guardSecondFactorDisabled (Just (botUserId bot))
930
963
maybe (throwErrorDescriptionType @ ClientNotFound ) (pure . json) =<< lift (botGetClient bot)
931
964
932
965
botGetClient :: BotId -> (AppIO r ) (Maybe Public. Client )
@@ -935,6 +968,7 @@ botGetClient bot =
935
968
936
969
botListPrekeysH :: BotId -> (Handler r ) Response
937
970
botListPrekeysH bot = do
971
+ guardSecondFactorDisabled (Just (botUserId bot))
938
972
json <$> botListPrekeys bot
939
973
940
974
botListPrekeys :: BotId -> (Handler r ) [Public. PrekeyId ]
@@ -946,6 +980,7 @@ botListPrekeys bot = do
946
980
947
981
botUpdatePrekeysH :: BotId ::: JsonRequest Public. UpdateBotPrekeys -> (Handler r ) Response
948
982
botUpdatePrekeysH (bot ::: req) = do
983
+ guardSecondFactorDisabled (Just (botUserId bot))
949
984
empty <$ (botUpdatePrekeys bot =<< parseJsonBody req)
950
985
951
986
botUpdatePrekeys :: BotId -> Public. UpdateBotPrekeys -> (Handler r ) ()
@@ -959,6 +994,7 @@ botUpdatePrekeys bot upd = do
959
994
960
995
botClaimUsersPrekeysH :: JsonRequest Public. UserClients -> (Handler r ) Response
961
996
botClaimUsersPrekeysH req = do
997
+ guardSecondFactorDisabled Nothing
962
998
json <$> (botClaimUsersPrekeys =<< parseJsonBody req)
963
999
964
1000
botClaimUsersPrekeys :: Public. UserClients -> (Handler r ) Public. UserClientPrekeyMap
@@ -970,6 +1006,7 @@ botClaimUsersPrekeys body = do
970
1006
971
1007
botListUserProfilesH :: List UserId -> (Handler r ) Response
972
1008
botListUserProfilesH uids = do
1009
+ guardSecondFactorDisabled Nothing -- should we check all user ids?
973
1010
json <$> botListUserProfiles uids
974
1011
975
1012
botListUserProfiles :: List UserId -> (Handler r ) [Public. BotUserView ]
@@ -979,6 +1016,7 @@ botListUserProfiles uids = do
979
1016
980
1017
botGetUserClientsH :: UserId -> (Handler r ) Response
981
1018
botGetUserClientsH uid = do
1019
+ guardSecondFactorDisabled (Just uid)
982
1020
json <$> lift (botGetUserClients uid)
983
1021
984
1022
botGetUserClients :: UserId -> (AppIO r ) [Public. PubClient ]
@@ -989,10 +1027,12 @@ botGetUserClients uid =
989
1027
990
1028
botDeleteSelfH :: BotId ::: ConvId -> (Handler r ) Response
991
1029
botDeleteSelfH (bid ::: cid) = do
1030
+ guardSecondFactorDisabled (Just (botUserId bid))
992
1031
empty <$ botDeleteSelf bid cid
993
1032
994
1033
botDeleteSelf :: BotId -> ConvId -> (Handler r ) ()
995
1034
botDeleteSelf bid cid = do
1035
+ guardSecondFactorDisabled (Just (botUserId bid))
996
1036
bot <- lift . wrapClient $ User. lookupUser NoPendingInvitations (botUserId bid)
997
1037
_ <- maybeInvalidBot (userService =<< bot)
998
1038
_ <- lift $ deleteBot (botUserId bid) Nothing bid cid
@@ -1001,6 +1041,13 @@ botDeleteSelf bid cid = do
1001
1041
--------------------------------------------------------------------------------
1002
1042
-- Utilities
1003
1043
1044
+ -- | If second factor auth is enabled, make sure that end-points that don't support it, but should, are blocked completely.
1045
+ -- (This is a workaround until we have 2FA for those end-points as well.)
1046
+ guardSecondFactorDisabled :: Maybe UserId -> Handler r ()
1047
+ guardSecondFactorDisabled mbUserId = do
1048
+ enabled <- lift $ (==) Feature. TeamFeatureEnabled . Feature. tfwoStatus <$> RPC. getTeamFeatureStatusSndFactorPasswordChallenge mbUserId
1049
+ when enabled $ throwStd accessDenied
1050
+
1004
1051
minRsaKeySize :: Int
1005
1052
minRsaKeySize = 256 -- Bytes (= 2048 bits)
1006
1053
@@ -1138,5 +1185,8 @@ serviceError :: RPC.ServiceError -> Wai.Error
1138
1185
serviceError RPC. ServiceUnavailable = badGateway
1139
1186
serviceError RPC. ServiceBotConflict = tooManyBots
1140
1187
1188
+ accessDenied :: Wai. Error
1189
+ accessDenied = Wai. mkError status403 " access-denied" " Access denied."
1190
+
1141
1191
randServiceToken :: MonadIO m => m Public. ServiceToken
1142
1192
randServiceToken = ServiceToken . Ascii. encodeBase64Url <$> liftIO (randBytes 18 )
0 commit comments