Skip to content

Commit a9b5d03

Browse files
authored
SQSERVICES-1012-backend-servantify-galley-team-member-api (#2309)
1 parent 8f1f841 commit a9b5d03

File tree

12 files changed

+308
-384
lines changed

12 files changed

+308
-384
lines changed

changelog.d/5-internal/pr-2309

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Team Member API has been migrated to Servant

libs/galley-types/src/Galley/Types/Teams.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ module Galley.Types.Teams
7676
nInvitation,
7777
legalHoldStatus,
7878
TeamMemberList,
79+
TeamMemberListOptPerms,
7980
ListType (..),
8081
newTeamMemberList,
8182
teamMembers,
@@ -467,8 +468,8 @@ isTeamMember u = isJust . findTeamMember u
467468
findTeamMember :: Foldable m => UserId -> m TeamMember -> Maybe TeamMember
468469
findTeamMember u = find ((u ==) . view userId)
469470

470-
isTeamOwner :: TeamMember -> Bool
471-
isTeamOwner tm = fullPermissions == (tm ^. permissions)
471+
isTeamOwner :: TeamMemberOptPerms -> Bool
472+
isTeamOwner tm = optionalPermissions tm == Just fullPermissions
472473

473474
-- | Use this to construct the condition expected by 'teamMemberJson', 'teamMemberListJson'
474475
canSeePermsOf :: TeamMember -> TeamMember -> Bool

libs/wire-api/src/Wire/API/Error/Galley.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import Wire.API.Conversation.Role
4444
import Wire.API.Error
4545
import qualified Wire.API.Error.Brig as BrigError
4646
import Wire.API.Routes.API
47+
import Wire.API.Team.Member
4748
import Wire.API.Team.Permission
4849
import Wire.API.Util.Aeson (CustomEncoded (..))
4950

@@ -106,6 +107,8 @@ data GalleyError
106107
| TooManyTeamMembersOnTeamWithLegalhold
107108
| NoLegalHoldDeviceAllocated
108109
| UserLegalHoldNotPending
110+
| -- Team Member errors
111+
BulkGetMemberLimitExceeded
109112
deriving (Show, Eq, Generic)
110113
deriving (FromJSON, ToJSON) via (CustomEncoded GalleyError)
111114

@@ -247,6 +250,11 @@ type instance MapError 'NoLegalHoldDeviceAllocated = 'StaticError 404 "legalhold
247250

248251
type instance MapError 'LegalHoldCouldNotBlockConnections = 'StaticError 500 "legalhold-internal" "legal hold service: could not block connections when resolving policy conflicts."
249252

253+
--------------------------------------------------------------------------------
254+
-- Team Member errors
255+
256+
type instance MapError 'BulkGetMemberLimitExceeded = 'StaticError 400 "too-many-uids" ("Can only process " `AppendSymbol` Show_ HardTruncationLimit `AppendSymbol` " user ids per request.")
257+
250258
--------------------------------------------------------------------------------
251259
-- Authentication errors
252260

libs/wire-api/src/Wire/API/Routes/Public/Galley.hs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ import Wire.API.Team
5757
import Wire.API.Team.Conversation
5858
import Wire.API.Team.Feature
5959
import Wire.API.Team.LegalHold
60+
import Wire.API.Team.Member
6061
import Wire.API.Team.Permission (Perm (..))
6162
import Wire.API.Team.SearchVisibility (TeamSearchVisibilityView)
63+
import qualified Wire.API.User as User
6264

6365
instance AsHeaders '[ConvId] Conversation Conversation where
6466
toHeaders c = (I (qUnqualified (cnvQualifiedId c)) :* Nil, c)
@@ -167,6 +169,7 @@ type ServantAPI =
167169
:<|> MLSAPI
168170
:<|> CustomBackendAPI
169171
:<|> LegalHoldAPI
172+
:<|> TeamMemberAPI
170173

171174
type ConversationAPI =
172175
Named
@@ -1514,6 +1517,156 @@ data GrantConsentResult
15141517

15151518
instance GSOP.Generic GrantConsentResult
15161519

1520+
type TeamMemberAPI =
1521+
Named
1522+
"get-team-members"
1523+
( Summary "Get team members"
1524+
:> CanThrow 'NotATeamMember
1525+
:> ZLocalUser
1526+
:> "teams"
1527+
:> Capture "tid" TeamId
1528+
:> "members"
1529+
:> QueryParam'
1530+
[ Optional,
1531+
Strict,
1532+
Description "Maximum results to be returned"
1533+
]
1534+
"maxResults"
1535+
(Range 1 HardTruncationLimit Int32)
1536+
:> Get '[JSON] TeamMemberListOptPerms
1537+
)
1538+
:<|> Named
1539+
"get-team-member"
1540+
( Summary "Get single team member"
1541+
:> CanThrow 'NotATeamMember
1542+
:> CanThrow 'TeamMemberNotFound
1543+
:> ZLocalUser
1544+
:> "teams"
1545+
:> Capture "tid" TeamId
1546+
:> "members"
1547+
:> Capture "uid" UserId
1548+
:> Get '[JSON] TeamMemberOptPerms
1549+
)
1550+
:<|> Named
1551+
"get-team-members-by-ids"
1552+
( Summary "Get team members by user id list"
1553+
:> Description "The `has_more` field in the response body is always `false`."
1554+
:> CanThrow 'NotATeamMember
1555+
:> CanThrow 'BulkGetMemberLimitExceeded
1556+
:> ZLocalUser
1557+
:> "teams"
1558+
:> Capture "tid" TeamId
1559+
:> "get-members-by-ids-using-post"
1560+
:> QueryParam'
1561+
[ Optional,
1562+
Strict,
1563+
Description "Maximum results to be returned"
1564+
]
1565+
"maxResults"
1566+
(Range 1 HardTruncationLimit Int32)
1567+
:> ReqBody '[JSON] User.UserIdList
1568+
:> Post '[JSON] TeamMemberListOptPerms
1569+
)
1570+
:<|> Named
1571+
"add-team-member"
1572+
( Summary "Add a new team member"
1573+
:> CanThrow 'InvalidPermissions
1574+
:> CanThrow 'NoAddToBinding
1575+
:> CanThrow 'NotATeamMember
1576+
:> CanThrow 'NotConnected
1577+
:> CanThrow OperationDenied
1578+
:> CanThrow 'TeamNotFound
1579+
:> CanThrow 'TooManyTeamMembers
1580+
:> CanThrow 'UserBindingExists
1581+
:> CanThrow 'TooManyTeamMembersOnTeamWithLegalhold
1582+
:> ZLocalUser
1583+
:> ZConn
1584+
:> "teams"
1585+
:> Capture "tid" TeamId
1586+
:> "members"
1587+
:> ReqBody '[JSON] NewTeamMember
1588+
:> MultiVerb1
1589+
'POST
1590+
'[JSON]
1591+
(RespondEmpty 200 "")
1592+
)
1593+
:<|> Named
1594+
"delete-team-member"
1595+
( Summary "Remove an existing team member"
1596+
:> CanThrow AuthenticationError
1597+
:> CanThrow 'AccessDenied
1598+
:> CanThrow 'TeamMemberNotFound
1599+
:> CanThrow 'TeamNotFound
1600+
:> CanThrow 'NotATeamMember
1601+
:> CanThrow OperationDenied
1602+
:> ZLocalUser
1603+
:> ZConn
1604+
:> "teams"
1605+
:> Capture "tid" TeamId
1606+
:> "members"
1607+
:> Capture "uid" UserId
1608+
:> ReqBody '[JSON] TeamMemberDeleteData
1609+
:> MultiVerb
1610+
'DELETE
1611+
'[JSON]
1612+
TeamMemberDeleteResultResponseType
1613+
TeamMemberDeleteResult
1614+
)
1615+
:<|> Named
1616+
"delete-non-binding-team-member"
1617+
( Summary "Remove an existing team member"
1618+
:> CanThrow AuthenticationError
1619+
:> CanThrow 'AccessDenied
1620+
:> CanThrow 'TeamMemberNotFound
1621+
:> CanThrow 'TeamNotFound
1622+
:> CanThrow 'NotATeamMember
1623+
:> CanThrow OperationDenied
1624+
:> ZLocalUser
1625+
:> ZConn
1626+
:> "teams"
1627+
:> Capture "tid" TeamId
1628+
:> "members"
1629+
:> Capture "uid" UserId
1630+
:> MultiVerb
1631+
'DELETE
1632+
'[JSON]
1633+
TeamMemberDeleteResultResponseType
1634+
TeamMemberDeleteResult
1635+
)
1636+
:<|> Named
1637+
"update-team-member"
1638+
( Summary "Update an existing team member"
1639+
:> CanThrow 'AccessDenied
1640+
:> CanThrow 'InvalidPermissions
1641+
:> CanThrow 'TeamNotFound
1642+
:> CanThrow 'TeamMemberNotFound
1643+
:> CanThrow 'NotATeamMember
1644+
:> CanThrow OperationDenied
1645+
:> ZLocalUser
1646+
:> ZConn
1647+
:> "teams"
1648+
:> Capture "tid" TeamId
1649+
:> "members"
1650+
:> ReqBody '[JSON] NewTeamMember
1651+
:> MultiVerb1
1652+
'PUT
1653+
'[JSON]
1654+
(RespondEmpty 200 "")
1655+
)
1656+
1657+
type TeamMemberDeleteResultResponseType =
1658+
'[ RespondEmpty 202 "Team member scheduled for deletion",
1659+
RespondEmpty 200 ""
1660+
]
1661+
1662+
data TeamMemberDeleteResult
1663+
= TeamMemberDeleteAccepted
1664+
| TeamMemberDeleteCompleted
1665+
deriving (Generic)
1666+
deriving (AsUnion TeamMemberDeleteResultResponseType) via GenericAsUnion TeamMemberDeleteResultResponseType TeamMemberDeleteResult
1667+
1668+
instance GSOP.Generic TeamMemberDeleteResult
1669+
15171670
-- This is a work-around for the fact that we sometimes want to send larger lists of user ids
15181671
-- in the filter query than fits the url length limit. For details, see
15191672
-- https://github.com/zinfra/backend-issues/issues/1248

libs/wire-api/src/Wire/API/Swagger.hs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import qualified Wire.API.Team as Team
3535
import qualified Wire.API.Team.Conversation as Team.Conversation
3636
import qualified Wire.API.Team.Feature as Team.Feature
3737
import qualified Wire.API.Team.Invitation as Team.Invitation
38-
import qualified Wire.API.Team.Member as Team.Member
3938
import qualified Wire.API.Team.Permission as Team.Permission
4039
import qualified Wire.API.User as User
4140
import qualified Wire.API.User.Activation as User.Activation
@@ -93,8 +92,6 @@ models =
9392
Push.Token.modelPushTokenList,
9493
Team.modelTeam,
9594
Team.modelTeamList,
96-
Team.modelNewNonBindingTeam,
97-
Team.modelUpdateData,
9895
Team.modelTeamDelete,
9996
Team.Conversation.modelTeamConversation,
10097
Team.Conversation.modelTeamConversationList,
@@ -118,10 +115,6 @@ models =
118115
Team.Invitation.modelTeamInvitation,
119116
Team.Invitation.modelTeamInvitationList,
120117
Team.Invitation.modelTeamInvitationRequest,
121-
Team.Member.modelTeamMember,
122-
Team.Member.modelTeamMemberList,
123-
Team.Member.modelNewTeamMember,
124-
Team.Member.modelTeamMemberDelete,
125118
Team.Permission.modelPermissions,
126119
User.modelUserIdList,
127120
User.modelUser,

libs/wire-api/src/Wire/API/Team.hs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,12 @@ module Wire.API.Team
6666
-- * Swagger
6767
modelTeam,
6868
modelTeamList,
69-
modelNewNonBindingTeam,
7069
modelUpdateData,
7170
modelTeamDelete,
7271
)
7372
where
7473

75-
import Control.Lens (makeLenses)
74+
import Control.Lens (makeLenses, (?~))
7675
import Data.Aeson (FromJSON, ToJSON, Value (..))
7776
import Data.Aeson.Types (Parser)
7877
import qualified Data.Attoparsec.ByteString as Atto (Parser, string)
@@ -90,7 +89,7 @@ import Imports
9089
import Test.QuickCheck.Gen (suchThat)
9190
import Wire.API.Arbitrary (Arbitrary (arbitrary), GenericUniform (..))
9291
import Wire.API.Asset (AssetKey)
93-
import Wire.API.Team.Member (TeamMember, modelTeamMember)
92+
import Wire.API.Team.Member (TeamMember)
9493

9594
--------------------------------------------------------------------------------
9695
-- Team
@@ -218,20 +217,6 @@ instance ToSchema NonBindingNewTeam where
218217
sch :: ValueSchema SwaggerDoc (Range 1 127 [TeamMember])
219218
sch = fromRange .= rangedSchema (array schema)
220219

221-
modelNewNonBindingTeam :: Doc.Model
222-
modelNewNonBindingTeam = Doc.defineModel "newNonBindingTeam" $ do
223-
Doc.description "Required data when creating new regular teams"
224-
Doc.property "name" Doc.string' $
225-
Doc.description "team name"
226-
Doc.property "icon" Doc.string' $
227-
Doc.description "team icon (asset ID)"
228-
Doc.property "icon_key" Doc.string' $ do
229-
Doc.description "team icon asset key"
230-
Doc.optional
231-
Doc.property "members" (Doc.unique $ Doc.array (Doc.ref modelTeamMember)) $ do
232-
Doc.description "initial team member ids (between 1 and 127)"
233-
Doc.optional
234-
235220
data NewTeam a = NewTeam
236221
{ _newTeamName :: Range 1 256 Text,
237222
_newTeamIcon :: Icon,
@@ -247,10 +232,10 @@ newNewTeam nme ico = NewTeam nme ico Nothing Nothing
247232
newTeamObjectSchema :: ValueSchema SwaggerDoc a -> ObjectSchema SwaggerDoc (NewTeam a)
248233
newTeamObjectSchema sch =
249234
NewTeam
250-
<$> _newTeamName .= field "name" schema
251-
<*> _newTeamIcon .= field "icon" schema
252-
<*> _newTeamIconKey .= maybe_ (optField "icon_key" schema)
253-
<*> _newTeamMembers .= maybe_ (optField "members" sch)
235+
<$> _newTeamName .= fieldWithDocModifier "name" (description ?~ "team name") schema
236+
<*> _newTeamIcon .= fieldWithDocModifier "icon" (description ?~ "team icon (asset ID)") schema
237+
<*> _newTeamIconKey .= maybe_ (optFieldWithDocModifier "icon_key" (description ?~ "team icon asset key") schema)
238+
<*> _newTeamMembers .= maybe_ (optFieldWithDocModifier "members" (description ?~ "initial team member ids (between 1 and 127)") sch)
254239

255240
--------------------------------------------------------------------------------
256241
-- TeamUpdateData

0 commit comments

Comments
 (0)