diff --git a/Makefile b/Makefile
index 9f2f6767fc3..77a68d9cc10 100644
--- a/Makefile
+++ b/Makefile
@@ -608,9 +608,9 @@ upload-bombon:
openapi-validate:
@echo -e "Make sure you are running the backend in another terminal (make cr)\n"
vacuum lint -a -d -e <(curl http://localhost:8082/v7/api/swagger.json)
-# vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/cannon-swagger.json)
-# vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/cargohold-swagger.json)
-# vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/spar-swagger.json)
-# vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/gundeck-swagger.json)
-# vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/brig-swagger.json)
-# vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/galley-swagger.json)
+ vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/cannon-swagger.json)
+ vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/cargohold-swagger.json)
+ vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/spar-swagger.json)
+ vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/gundeck-swagger.json)
+ vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/brig-swagger.json)
+ vacuum lint -a -d -e <(curl http://localhost:8082/api-internal/swagger-ui/galley-swagger.json)
diff --git a/changelog.d/5-internal/fix-galley-overlaps b/changelog.d/5-internal/fix-galley-overlaps
new file mode 100644
index 00000000000..784bbe17f2a
--- /dev/null
+++ b/changelog.d/5-internal/fix-galley-overlaps
@@ -0,0 +1 @@
+Fix overlapping paths errors in galley's internal API
diff --git a/integration/test/Test/Swagger.hs b/integration/test/Test/Swagger.hs
index 514bf532299..2fe53d487bb 100644
--- a/integration/test/Test/Swagger.hs
+++ b/integration/test/Test/Swagger.hs
@@ -86,6 +86,20 @@ testSwaggerToc = do
html :: String
html = "
please pick an api version
/v0/api/swagger-ui/
/v1/api/swagger-ui/
/v2/api/swagger-ui/
/v3/api/swagger-ui/
/v4/api/swagger-ui/
/v5/api/swagger-ui/
/v6/api/swagger-ui/
/v7/api/swagger-ui/
"
+data Swagger = SwaggerPublic | SwaggerInternal Service
+
+instance TestCases Swagger where
+ mkTestCases =
+ pure
+ [ MkTestCase "[swagger=ibrig]" (SwaggerInternal Brig),
+ MkTestCase "[swagger=icannon]" (SwaggerInternal Cannon),
+ MkTestCase "[swagger=icargohold]" (SwaggerInternal Cargohold),
+ MkTestCase "[swagger=igalley]" (SwaggerInternal Galley),
+ MkTestCase "[swagger=igundeck]" (SwaggerInternal Gundeck),
+ MkTestCase "[swagger=ispar]" (SwaggerInternal Spar),
+ MkTestCase "[swagger=public]" SwaggerPublic
+ ]
+
-- | This runs the swagger linter [vacuum](https://quobix.com/vacuum/).
--
-- The reason for adding the linter in the integration tests, and not in the lint job, is that
@@ -93,10 +107,20 @@ testSwaggerToc = do
--
-- There is also a make rule that does this, for convenience in your develop
-- flow. Make sure that brig is running before using the make rule.
-testSwaggerLint :: (HasCallStack) => App ()
-testSwaggerLint = do
+testSwaggerLint :: (HasCallStack) => Swagger -> App ()
+testSwaggerLint sw = do
withSystemTempDirectory "swagger" $ \tmp -> do
- req <- baseRequest OwnDomain Brig Versioned $ joinHttpPath ["api", "swagger.json"]
+ req <- case sw of
+ SwaggerPublic ->
+ baseRequest OwnDomain Brig Versioned
+ $ joinHttpPath ["api", "swagger.json"]
+ (SwaggerInternal service) ->
+ baseRequest OwnDomain Brig Unversioned
+ $ joinHttpPath
+ [ "api-internal",
+ "swagger-ui",
+ serviceName service <> "-swagger.json"
+ ]
swagger <- submit "GET" req >>= getBody 200
liftIO $ B.writeFile (tmp > "swagger.json") swagger
let cmd = shell $ "vacuum lint -a -d -e " <> (tmp > "swagger.json")
diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs
index cdb072d749f..bdae90491ca 100644
--- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs
@@ -387,7 +387,7 @@ type IConversationAPI =
Named
"conversation-get-member"
( "conversations"
- :> Capture "cnv" ConvId
+ :> QualifiedCapture "cnv" ConvId
:> "members"
:> Capture "usr" UserId
:> Get '[JSON] (Maybe Member)
@@ -408,16 +408,6 @@ type IConversationAPI =
:> "v2"
:> Put '[JSON] Conversation
)
- :<|> Named
- "conversation-block-unqualified"
- ( CanThrow 'InvalidOperation
- :> CanThrow 'ConvNotFound
- :> ZUser
- :> "conversations"
- :> Capture "cnv" ConvId
- :> "block"
- :> Put '[JSON] ()
- )
:<|> Named
"conversation-block"
( CanThrow 'InvalidOperation
@@ -432,21 +422,6 @@ type IConversationAPI =
-- - MemberJoin event to you, if the conversation existed and had < 2 members before
-- - MemberJoin event to other, if the conversation existed and only the other was member
-- before
- :<|> Named
- "conversation-unblock-unqualified"
- ( CanThrow 'InvalidOperation
- :> CanThrow 'ConvNotFound
- :> ZLocalUser
- :> ZOptConn
- :> "conversations"
- :> Capture "cnv" ConvId
- :> "unblock"
- :> Put '[JSON] Conversation
- )
- -- This endpoint can lead to the following events being sent:
- -- - MemberJoin event to you, if the conversation existed and had < 2 members before
- -- - MemberJoin event to other, if the conversation existed and only the other was member
- -- before
:<|> Named
"conversation-unblock"
( CanThrow 'InvalidOperation
@@ -470,8 +445,7 @@ type IConversationAPI =
"conversation-mls-one-to-one"
( CanThrow 'NotConnected
:> CanThrow 'MLSNotEnabled
- :> "conversations"
- :> "mls-one2one"
+ :> "mls-one2one-conversations"
:> ZLocalUser
:> QualifiedCapture "user" UserId
:> Get '[JSON] Conversation
@@ -481,8 +455,7 @@ type IConversationAPI =
( CanThrow 'NotConnected
:> CanThrow 'MLSNotEnabled
:> ZLocalUser
- :> "conversations"
- :> "mls-one2one"
+ :> "mls-one2one-conversations"
:> QualifiedCapture "user" UserId
:> "established"
:> Get '[JSON] Bool
diff --git a/libs/wire-subsystems/src/Wire/GalleyAPIAccess/Rpc.hs b/libs/wire-subsystems/src/Wire/GalleyAPIAccess/Rpc.hs
index f7ee1c47f65..ba9538f12de 100644
--- a/libs/wire-subsystems/src/Wire/GalleyAPIAccess/Rpc.hs
+++ b/libs/wire-subsystems/src/Wire/GalleyAPIAccess/Rpc.hs
@@ -575,8 +575,7 @@ checkMLSOne2OneEstablished self (Qualified other otherDomain) = do
method GET
. paths
[ "i",
- "conversations",
- "mls-one2one",
+ "mls-one2one-conversations",
toByteString' otherDomain,
toByteString' other,
"established"
diff --git a/services/brig/test/integration/Util.hs b/services/brig/test/integration/Util.hs
index 8c39a9a7e4c..18f9eef6912 100644
--- a/services/brig/test/integration/Util.hs
+++ b/services/brig/test/integration/Util.hs
@@ -748,7 +748,14 @@ isMember g usr cnv = do
res <-
get $
g
- . paths ["i", "conversations", toByteString' cnv, "members", toByteString' (tUnqualified usr)]
+ . paths
+ [ "i",
+ "conversations",
+ toByteString' (tDomain usr),
+ toByteString' cnv,
+ "members",
+ toByteString' (tUnqualified usr)
+ ]
. expect2xx
case responseJsonMaybe res of
Nothing -> pure False
diff --git a/services/galley/src/Galley/API/Internal.hs b/services/galley/src/Galley/API/Internal.hs
index 2e273aef847..411ad8fe295 100644
--- a/services/galley/src/Galley/API/Internal.hs
+++ b/services/galley/src/Galley/API/Internal.hs
@@ -174,9 +174,7 @@ conversationAPI :: API IConversationAPI GalleyEffects
conversationAPI =
mkNamedAPI @"conversation-get-member" Query.internalGetMember
<@> mkNamedAPI @"conversation-accept-v2" Update.acceptConv
- <@> mkNamedAPI @"conversation-block-unqualified" Update.blockConvUnqualified
<@> mkNamedAPI @"conversation-block" Update.blockConv
- <@> mkNamedAPI @"conversation-unblock-unqualified" Update.unblockConvUnqualified
<@> mkNamedAPI @"conversation-unblock" Update.unblockConv
<@> mkNamedAPI @"conversation-meta" Query.getConversationMeta
<@> mkNamedAPI @"conversation-mls-one-to-one" Query.getMLSOne2OneConversationInternal
diff --git a/services/galley/src/Galley/API/Query.hs b/services/galley/src/Galley/API/Query.hs
index a0edf6be781..47fb3365508 100644
--- a/services/galley/src/Galley/API/Query.hs
+++ b/services/galley/src/Galley/API/Query.hs
@@ -590,15 +590,17 @@ iterateConversations luid pageSize handleConvs = go Nothing
internalGetMember ::
( Member ConversationStore r,
+ Member (Error FederationError) r,
Member (Input (Local ())) r,
Member MemberStore r
) =>
- ConvId ->
+ Qualified ConvId ->
UserId ->
Sem r (Maybe Public.Member)
-internalGetMember cnv usr = do
+internalGetMember qcnv usr = do
lusr <- qualifyLocal usr
- getLocalSelf lusr cnv
+ lcnv <- ensureLocal lusr qcnv
+ getLocalSelf lusr (tUnqualified lcnv)
getLocalSelf ::
( Member ConversationStore r,
diff --git a/services/galley/test/integration/API.hs b/services/galley/test/integration/API.hs
index 2ddc71bce90..fab0d096d8b 100644
--- a/services/galley/test/integration/API.hs
+++ b/services/galley/test/integration/API.hs
@@ -2067,10 +2067,19 @@ postRepeatConnectConvCancel = do
where
cancel u c = do
g <- viewGalley
- let cnvId = qUnqualified . cnvQualifiedId
- put (g . paths ["/i/conversations", toByteString' (cnvId c), "block"] . zUser u)
+ let qConvId = cnvQualifiedId c
+ put
+ ( g
+ . paths
+ [ "/i/conversations",
+ toByteString' (qDomain qConvId),
+ toByteString' (qUnqualified qConvId),
+ "block"
+ ]
+ . zUser u
+ )
!!! const 200 === statusCode
- getConv u (cnvId c) !!! const 403 === statusCode
+ getConv u (qUnqualified qConvId) !!! const 403 === statusCode
putBlockConvOk :: TestM ()
putBlockConvOk = do
@@ -2082,23 +2091,59 @@ putBlockConvOk = do
let convId = qUnqualified qconvId
getConvQualified alice qconvId !!! const 200 === statusCode
getConvQualified bob qconvId !!! const 403 === statusCode
- put (g . paths ["/i/conversations", toByteString' convId, "block"] . zUser bob)
+ put
+ ( g
+ . paths
+ [ "/i/conversations",
+ toByteString' (qDomain qconvId),
+ toByteString' convId,
+ "block"
+ ]
+ . zUser bob
+ )
!!! const 200 === statusCode
-- A is still the only member of the 1-1
getConvQualified alice qconvId !!! do
const 200 === statusCode
const (cnvMembers conv) === cnvMembers . responseJsonUnsafeWithMsg "conversation"
-- B accepts the conversation by unblocking
- put (g . paths ["/i/conversations", toByteString' convId, "unblock"] . zUser bob)
+ put
+ ( g
+ . paths
+ [ "/i/conversations",
+ toByteString' (qDomain qconvId),
+ toByteString' convId,
+ "unblock"
+ ]
+ . zUser bob
+ )
!!! const 200 === statusCode
getConvQualified bob qconvId !!! const 200 === statusCode
-- B blocks A in the 1-1
- put (g . paths ["/i/conversations", toByteString' convId, "block"] . zUser bob)
+ put
+ ( g
+ . paths
+ [ "/i/conversations",
+ toByteString' (qDomain qconvId),
+ toByteString' convId,
+ "block"
+ ]
+ . zUser bob
+ )
!!! const 200 === statusCode
-- B no longer sees the 1-1
getConvQualified bob qconvId !!! const 403 === statusCode
-- B unblocks A in the 1-1
- put (g . paths ["/i/conversations", toByteString' convId, "unblock"] . zUser bob)
+ put
+ ( g
+ . paths
+ [ "/i/conversations",
+ toByteString' (qDomain qconvId),
+ toByteString' convId,
+ "unblock"
+ ]
+ . zUser bob
+ )
!!! const 200 === statusCode
-- B sees the blocked 1-1 again
getConvQualified bob qconvId !!! do