Skip to content

Commit 4125673

Browse files
committed
Fix: store optional Role in Invitation.
this is essential for backwards-compatibility, thanks @jschaul!
1 parent 94a4b66 commit 4125673

File tree

8 files changed

+52
-35
lines changed

8 files changed

+52
-35
lines changed

libs/brig-types/src/Brig/Types/Team/Invitation.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Brig.Types.Common
77
import Data.Aeson
88
import Data.Id
99
import Data.Json.Util
10-
import Galley.Types.Teams (Role, Permissions)
10+
import Galley.Types.Teams (Role)
1111

1212
data InvitationRequest = InvitationRequest
1313
{ irEmail :: !Email
@@ -18,7 +18,7 @@ data InvitationRequest = InvitationRequest
1818

1919
data Invitation = Invitation
2020
{ inTeam :: !TeamId
21-
, inPerms :: !Permissions
21+
, inRole :: !(Maybe Role)
2222
, inInvitation :: !InvitationId
2323
, inIdentity :: !Email
2424
, inCreatedAt :: !UTCTimeMillis
@@ -48,7 +48,7 @@ instance ToJSON InvitationRequest where
4848
instance FromJSON Invitation where
4949
parseJSON = withObject "invitation" $ \o ->
5050
Invitation <$> o .: "team"
51-
<*> o .: "perms"
51+
<*> o .: "role"
5252
<*> o .: "id"
5353
<*> o .: "email"
5454
<*> o .: "created_at"
@@ -57,7 +57,7 @@ instance FromJSON Invitation where
5757
instance ToJSON Invitation where
5858
toJSON i = object $
5959
[ "team" .= inTeam i
60-
, "perms" .= inPerms i
60+
, "role" .= inRole i
6161
, "id" .= inInvitation i
6262
, "email" .= inIdentity i
6363
, "created_at" .= inCreatedAt i

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,22 @@ instance ToJSON TeamDeleteData where
725725
]
726726

727727
#ifdef WITH_CQL
728+
instance Cql.Cql Role where
729+
ctype = Cql.Tagged Cql.IntColumn
730+
731+
toCql RoleOwner = Cql.CqlInt 1
732+
toCql RoleAdmin = Cql.CqlInt 2
733+
toCql RoleMember = Cql.CqlInt 3
734+
toCql RoleCollaborator = Cql.CqlInt 4
735+
736+
fromCql (Cql.CqlInt i) = case i of
737+
1 -> return RoleOwner
738+
2 -> return RoleAdmin
739+
3 -> return RoleMember
740+
4 -> return RoleCollaborator
741+
n -> fail $ "Unexpected Role value: " ++ show n
742+
fromCql _ = fail "Role value: int expected"
743+
728744
instance Cql.Cql Permissions where
729745
ctype = Cql.Tagged $ Cql.UdtColumn "permissions" [("self", Cql.BigIntColumn), ("copy", Cql.BigIntColumn)]
730746

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ teamMember = defineModel "TeamMember" $ do
9494
\ (only visible with permission `GetMemberPermissions`)."
9595
optional -- not optional in the type, but in the json instance. (in
9696
-- servant, we could probably just add a helper type for this.)
97+
-- TODO: even without servant, it would be nicer to introduce
98+
-- a type with optional permissions.
9799

98100
permissions :: Model
99101
permissions = defineModel "Permissions" $ do

services/brig/schema/src/V55.hs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,5 @@ import Cassandra.Schema
88
import Text.RawString.QQ
99

1010
migration :: Migration
11-
migration = Migration 55 "Add perms to team invitations" $ do
12-
schema' [r| CREATE TYPE permissions (self bigint, copy bigint); |]
13-
14-
schema' [r| alter table team_invitation add perms frozen<permissions>; |]
11+
migration = Migration 55 "Add optional role to team invitations" $ do
12+
schema' [r| alter table team_invitation add role int; |]

services/brig/src/Brig/API/User.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ createUser new@NewUser{..} = do
257257
ok <- lift $ Data.claimKey uk uid
258258
unless ok $
259259
throwE $ DuplicateUserKey uk
260-
let minvmeta :: (Maybe (UserId, UTCTimeMillis), Team.Permissions)
261-
minvmeta = ((, inCreatedAt inv) <$> inCreatedBy inv, Team.inPerms inv)
260+
let minvmeta :: (Maybe (UserId, UTCTimeMillis), Maybe Team.Role)
261+
minvmeta = ((, inCreatedAt inv) <$> inCreatedBy inv, Team.inRole inv)
262262
added <- lift $ Intra.addTeamMember uid (Team.iiTeam ii) minvmeta
263263
unless added $
264264
throwE TooManyTeamMembers
@@ -273,7 +273,7 @@ createUser new@NewUser{..} = do
273273
addUserToTeamSSO :: UserAccount -> TeamId -> UserIdentity -> ExceptT CreateUserError AppIO CreateUserTeam
274274
addUserToTeamSSO account tid ident = do
275275
let uid = userId (accountUser account)
276-
added <- lift $ Intra.addTeamMember uid tid (Nothing, Team.rolePermissions Team.RoleMember)
276+
added <- lift $ Intra.addTeamMember uid tid (Nothing, Nothing)
277277
unless added $
278278
throwE TooManyTeamMembers
279279
lift $ do

services/brig/src/Brig/IO/Intra.hs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,21 +529,22 @@ rmClient u c = do
529529
-------------------------------------------------------------------------------
530530
-- Team Management
531531

532-
addTeamMember :: UserId -> TeamId -> (Maybe (UserId, UTCTimeMillis), Team.Permissions) -> AppIO Bool
533-
addTeamMember u tid (minvmeta, permissions) = do
532+
addTeamMember :: UserId -> TeamId -> (Maybe (UserId, UTCTimeMillis), Maybe Team.Role) -> AppIO Bool
533+
addTeamMember u tid (minvmeta, mrole) = do
534534
debug $ remote "galley"
535535
. msg (val "Adding member to team")
536-
rs <- galleyRequest POST (req permissions)
536+
rs <- galleyRequest POST req
537537
return $ case Bilge.statusCode rs of
538538
200 -> True
539539
_ -> False
540540
where
541-
t prm = Team.newNewTeamMember $ Team.newTeamMember u prm minvmeta
542-
req p = paths ["i", "teams", toByteString' tid, "members"]
541+
prm = Team.rolePermissions $ fromMaybe Team.RoleMember mrole
542+
bdy = Team.newNewTeamMember $ Team.newTeamMember u prm minvmeta
543+
req = paths ["i", "teams", toByteString' tid, "members"]
543544
. header "Content-Type" "application/json"
544545
. zUser u
545546
. expect [status200, status403]
546-
. lbytes (encode $ t p)
547+
. lbytes (encode bdy)
547548

548549
createTeam :: UserId -> Team.BindingNewTeam -> TeamId -> AppIO CreateUserTeam
549550
createTeam u t@(Team.BindingNewTeam bt) teamid = do

services/brig/src/Brig/Team/API.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,12 @@ createInvitation (_ ::: uid ::: tid ::: req) = do
180180
user <- lift $ Data.lookupKey uk
181181
case user of
182182
Just _ -> throwStd emailExists
183-
Nothing -> doInvite inviteePerms email from (irLocale body)
183+
Nothing -> doInvite (irRole body) email from (irLocale body)
184184
where
185-
doInvite perms to from lc = lift $ do
185+
doInvite role to from lc = lift $ do
186186
now <- liftIO =<< view currentTime
187187
timeout <- setTeamInvitationTimeout <$> view settings
188-
(newInv, code) <- DB.insertInvitation tid perms to now (Just uid) timeout
188+
(newInv, code) <- DB.insertInvitation tid role to now (Just uid) timeout
189189
void $ sendInvitationMail to tid from code lc
190190
return . setStatus status201 . loc (inInvitation newInv) $ json newInv
191191

services/brig/src/Brig/Team/DB.hs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import Brig.Options
3030
import Brig.Types.Common
3131
import Brig.Types.User
3232
import Brig.Types.Team.Invitation
33-
import Galley.Types.Teams (Permissions)
33+
import Galley.Types.Teams (Role)
3434
import Cassandra
3535
import UnliftIO.Async (pooledMapConcurrentlyN_)
3636
import Data.Id
@@ -58,35 +58,35 @@ data InvitationInfo = InvitationInfo
5858

5959
insertInvitation :: MonadClient m
6060
=> TeamId
61-
-> Permissions
61+
-> Maybe Role
6262
-> Email
6363
-> UTCTime
6464
-> Maybe UserId
6565
-> Timeout -- ^ The timeout for the invitation code.
6666
-> m (Invitation, InvitationCode)
67-
insertInvitation t perms email (toUTCTimeMillis -> now) minviter timeout = do
67+
insertInvitation t role email (toUTCTimeMillis -> now) minviter timeout = do
6868
iid <- liftIO mkInvitationId
6969
code <- liftIO mkInvitationCode
70-
let inv = Invitation t perms iid email now minviter
70+
let inv = Invitation t role iid email now minviter
7171
retry x5 $ batch $ do
7272
setType BatchLogged
7373
setConsistency Quorum
74-
addPrepQuery cqlInvitation (t, perms, iid, code, email, now, minviter, round timeout)
74+
addPrepQuery cqlInvitation (t, role, iid, code, email, now, minviter, round timeout)
7575
addPrepQuery cqlInvitationInfo (code, t, iid, round timeout)
7676
return (inv, code)
7777
where
7878
cqlInvitationInfo :: PrepQuery W (InvitationCode, TeamId, InvitationId, Int32) ()
7979
cqlInvitationInfo = "INSERT INTO team_invitation_info (code, team, id) VALUES (?, ?, ?) USING TTL ?"
8080

81-
cqlInvitation :: PrepQuery W (TeamId, Permissions, InvitationId, InvitationCode, Email, UTCTimeMillis, Maybe UserId, Int32) ()
82-
cqlInvitation = "INSERT INTO team_invitation (team, perms, id, code, email, created_at, created_by) VALUES (?, ?, ?, ?, ?, ?, ?) USING TTL ?"
81+
cqlInvitation :: PrepQuery W (TeamId, Maybe Role, InvitationId, InvitationCode, Email, UTCTimeMillis, Maybe UserId, Int32) ()
82+
cqlInvitation = "INSERT INTO team_invitation (team, role, id, code, email, created_at, created_by) VALUES (?, ?, ?, ?, ?, ?, ?) USING TTL ?"
8383

8484
lookupInvitation :: MonadClient m => TeamId -> InvitationId -> m (Maybe Invitation)
8585
lookupInvitation t r = fmap toInvitation <$>
8686
retry x1 (query1 cqlInvitation (params Quorum (t, r)))
8787
where
88-
cqlInvitation :: PrepQuery R (TeamId, InvitationId) (TeamId, Permissions, InvitationId, Email, UTCTimeMillis, Maybe UserId)
89-
cqlInvitation = "SELECT team, perms, id, email, created_at, created_by FROM team_invitation WHERE team = ? AND id = ?"
88+
cqlInvitation :: PrepQuery R (TeamId, InvitationId) (TeamId, Maybe Role, InvitationId, Email, UTCTimeMillis, Maybe UserId)
89+
cqlInvitation = "SELECT team, role, id, email, created_at, created_by FROM team_invitation WHERE team = ? AND id = ?"
9090

9191
lookupInvitationByCode :: MonadClient m => InvitationCode -> m (Maybe Invitation)
9292
lookupInvitationByCode i = lookupInvitationInfo i >>= \case
@@ -111,11 +111,11 @@ lookupInvitations team start (fromRange -> size) = do
111111
toResult more invs = cassandraResultPage $ emptyPage { result = invs
112112
, hasMore = more
113113
}
114-
cqlSelect :: PrepQuery R (Identity TeamId) (TeamId, Permissions, InvitationId, Email, UTCTimeMillis, Maybe UserId)
115-
cqlSelect = "SELECT team, perms, id, email, created_at, created_by FROM team_invitation WHERE team = ? ORDER BY id ASC"
114+
cqlSelect :: PrepQuery R (Identity TeamId) (TeamId, Maybe Role, InvitationId, Email, UTCTimeMillis, Maybe UserId)
115+
cqlSelect = "SELECT team, role, id, email, created_at, created_by FROM team_invitation WHERE team = ? ORDER BY id ASC"
116116

117-
cqlSelectFrom :: PrepQuery R (TeamId, InvitationId) (TeamId, Permissions, InvitationId, Email, UTCTimeMillis, Maybe UserId)
118-
cqlSelectFrom = "SELECT team, perms, id, email, created_at, created_by FROM team_invitation WHERE team = ? AND id > ? ORDER BY id ASC"
117+
cqlSelectFrom :: PrepQuery R (TeamId, InvitationId) (TeamId, Maybe Role, InvitationId, Email, UTCTimeMillis, Maybe UserId)
118+
cqlSelectFrom = "SELECT team, role, id, email, created_at, created_by FROM team_invitation WHERE team = ? AND id > ? ORDER BY id ASC"
119119

120120
deleteInvitation :: MonadClient m => TeamId -> InvitationId -> m ()
121121
deleteInvitation t i = do
@@ -162,5 +162,5 @@ countInvitations t = fromMaybe 0 . fmap runIdentity <$>
162162
cqlSelect :: PrepQuery R (Identity TeamId) (Identity Int64)
163163
cqlSelect = "SELECT count(*) FROM team_invitation WHERE team = ?"
164164

165-
toInvitation :: (TeamId, Permissions, InvitationId, Email, UTCTimeMillis, Maybe UserId) -> Invitation
166-
toInvitation (t, p, i, e, tm, minviter) = Invitation t p i e tm minviter
165+
toInvitation :: (TeamId, Maybe Role, InvitationId, Email, UTCTimeMillis, Maybe UserId) -> Invitation
166+
toInvitation (t, r, i, e, tm, minviter) = Invitation t r i e tm minviter

0 commit comments

Comments
 (0)