99namespace OCA \Talk \Controller ;
1010
1111use OCA \DAV \CalDAV \TimezoneService ;
12+ use OCA \Talk \Authenticator ;
1213use OCA \Talk \Capabilities ;
1314use OCA \Talk \Config ;
1415use OCA \Talk \Events \AAttendeeRemovedEvent ;
3637use OCA \Talk \Exceptions \RoomProperty \SipConfigurationException ;
3738use OCA \Talk \Exceptions \RoomProperty \TypeException ;
3839use OCA \Talk \Exceptions \UnauthorizedException ;
39- use OCA \Talk \Federation \Authenticator ;
4040use OCA \Talk \Federation \FederationManager ;
4141use OCA \Talk \Federation \Proxy \TalkV1 \ProxyRequest ;
4242use OCA \Talk \GuestManager ;
@@ -456,15 +456,32 @@ public function getSingleRoom(string $token): DataResponse {
456456 $ isTalkFederation = $ this ->request ->getHeader ('x-nextcloud-federation ' );
457457
458458 if (!$ isTalkFederation ) {
459- $ sessionId = $ this ->session ->getSessionForRoom ($ token );
460- $ room = $ this ->manager ->getRoomForUserByToken ($ token , $ this ->userId , $ sessionId , $ includeLastMessage , $ isSIPBridgeRequest );
459+ if ($ this ->userId === null && $ this ->federationAuthenticator ->isAuthenticatedEmailGuest ()) {
460+ // Authenticated email guest: the user/public-room check in
461+ // getRoomForUserByToken() would reject non-public rooms, so
462+ // trust the session-stored actor id and require the email
463+ // attendee to still exist.
464+ $ room = $ this ->manager ->getRoomByToken ($ token );
465+ try {
466+ $ participant = $ this ->participantService ->getParticipantByActor (
467+ $ room ,
468+ Attendee::ACTOR_EMAILS ,
469+ $ this ->federationAuthenticator ->getActorId (),
470+ );
471+ } catch (ParticipantNotFoundException ) {
472+ throw new RoomNotFoundException ();
473+ }
474+ } else {
475+ $ sessionId = $ this ->session ->getSessionForRoom ($ token );
476+ $ room = $ this ->manager ->getRoomForUserByToken ($ token , $ this ->userId , $ sessionId , $ includeLastMessage , $ isSIPBridgeRequest );
461477
462- try {
463- $ participant = $ this ->participantService ->getParticipant ($ room , $ this ->userId , $ sessionId );
464- } catch (ParticipantNotFoundException ) {
465478 try {
466- $ participant = $ this ->participantService ->getParticipantBySession ($ room , $ sessionId );
479+ $ participant = $ this ->participantService ->getParticipant ($ room, $ this -> userId , $ sessionId );
467480 } catch (ParticipantNotFoundException ) {
481+ try {
482+ $ participant = $ this ->participantService ->getParticipantBySession ($ room , $ sessionId );
483+ } catch (ParticipantNotFoundException ) {
484+ }
468485 }
469486 }
470487 } else {
@@ -2013,9 +2030,18 @@ public function markConversationAsInsensitive(): DataResponse {
20132030 ])]
20142031 public function joinRoom (string $ token , string $ password = '' , bool $ force = true ): DataResponse {
20152032 $ sessionId = $ this ->session ->getSessionForRoom ($ token );
2033+ $ authenticatedEmailGuest = $ this ->userId === null && $ this ->federationAuthenticator ->isAuthenticatedEmailGuest ()
2034+ ? $ this ->federationAuthenticator ->getActorId ()
2035+ : null ;
20162036 try {
2017- // The participant is just joining, so enforce to not load any session
2018- $ room = $ this ->manager ->getRoomForUserByToken ($ token , $ this ->userId , null );
2037+ // The participant is just joining, so enforce to not load any session.
2038+ // Authenticated email guests bypass the user/public-room access check;
2039+ // the email attendee lookup below is the trust anchor instead.
2040+ if ($ authenticatedEmailGuest !== null ) {
2041+ $ room = $ this ->manager ->getRoomByToken ($ token );
2042+ } else {
2043+ $ room = $ this ->manager ->getRoomForUserByToken ($ token , $ this ->userId , null );
2044+ }
20192045 } catch (RoomNotFoundException $ e ) {
20202046 $ response = new DataResponse (null , Http::STATUS_NOT_FOUND );
20212047 $ response ->throttle (['token ' => $ token , 'action ' => 'talkRoomToken ' ]);
@@ -2065,8 +2091,6 @@ public function joinRoom(string $token, string $password = '', bool $force = tru
20652091 }
20662092 }
20672093
2068- $ authenticatedEmailGuest = $ this ->session ->getAuthedEmailActorIdForRoom ($ token );
2069-
20702094 $ headers = [];
20712095 if ($ authenticatedEmailGuest !== null || $ room ->isFederatedConversation ()
20722096 || ($ previousParticipant instanceof Participant && $ previousParticipant ->isGuest ())) {
@@ -2088,6 +2112,15 @@ public function joinRoom(string $token, string $password = '', bool $force = tru
20882112 try {
20892113 $ previousParticipant = $ this ->participantService ->getParticipantByActor ($ room , Attendee::ACTOR_EMAILS , $ authenticatedEmailGuest );
20902114 } catch (ParticipantNotFoundException ) {
2115+ // Stale spreed-authed-email session: the email attendee was
2116+ // removed (e.g. by a moderator) since the invite link was opened.
2117+ // Without this guard the code below would create a fresh
2118+ // ACTOR_GUESTS attendee with the password check bypassed,
2119+ // re-granting access to a possibly-private room.
2120+ $ this ->session ->removeAuthedEmailActorIdForRoom ($ token );
2121+ $ response = new DataResponse (null , Http::STATUS_NOT_FOUND );
2122+ $ response ->throttle (['token ' => $ token , 'action ' => 'talkRoomToken ' ]);
2123+ return $ response ;
20912124 }
20922125 }
20932126 $ participant = $ this ->participantService ->joinRoomAsNewGuest ($ this ->roomService , $ room , $ password , $ result ['result ' ], $ previousParticipant );
@@ -2537,7 +2570,11 @@ public function leaveRoom(string $token): DataResponse {
25372570 $ this ->session ->removeSessionForRoom ($ token );
25382571
25392572 try {
2540- $ room = $ this ->manager ->getRoomForUserByToken ($ token , $ this ->userId , $ sessionId );
2573+ if ($ this ->userId === null && $ this ->federationAuthenticator ->isAuthenticatedEmailGuest ()) {
2574+ $ room = $ this ->manager ->getRoomByToken ($ token );
2575+ } else {
2576+ $ room = $ this ->manager ->getRoomForUserByToken ($ token , $ this ->userId , $ sessionId );
2577+ }
25412578 $ participant = $ this ->participantService ->getParticipantBySession ($ room , $ sessionId );
25422579
25432580 if ($ room ->isFederatedConversation ()) {
0 commit comments