/hierarchy - return public and knockable rooms for authed users (#2578)
When requesting the room hierarchy with an authenticated user, return public and knockable rooms. According to the spec, https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/2946-spaces-summary.md ``` Any child room that the user is joined or is potentially joinable is included in the response. ``` This is currently not the case. See discussion here: https://matrix.to/#/!NasysSDfxKxZBzJJoE:matrix.org/$t2Csj-6y1PVsn8GOnFZfXzeQW13NfqvrFCxB-XI_uhA?via=matrix.org&via=libera.chat&via=element.io and here: https://matrix.to/#/!NasysSDfxKxZBzJJoE:matrix.org/$EHp1x1DY7tnYZtx_PVEb-sKB9lmJajqHx2uGlhrRh6k?via=matrix.org&via=libera.chat&via=element.io Test Plan: create and register clients bob and alice have bob create a public space have bob create a public room parented to the space have alice join the space(room) have alice sync the space expect alice to see two rooms in the space hierarchy, the space and the child room Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com>
This commit is contained in:
parent
6d0d7a0bc3
commit
e55cd6ea78
|
@ -479,7 +479,7 @@ func (w *walker) authorised(roomID, parentRoomID string) (authed, isJoinedOrInvi
|
||||||
return w.authorisedServer(roomID), false
|
return w.authorisedServer(roomID), false
|
||||||
}
|
}
|
||||||
|
|
||||||
// authorisedServer returns true iff the server is joined this room or the room is world_readable
|
// authorisedServer returns true iff the server is joined this room or the room is world_readable, public, or knockable
|
||||||
func (w *walker) authorisedServer(roomID string) bool {
|
func (w *walker) authorisedServer(roomID string) bool {
|
||||||
// Check history visibility / join rules first
|
// Check history visibility / join rules first
|
||||||
hisVisTuple := gomatrixserverlib.StateKeyTuple{
|
hisVisTuple := gomatrixserverlib.StateKeyTuple{
|
||||||
|
@ -513,9 +513,22 @@ func (w *walker) authorisedServer(roomID string) bool {
|
||||||
// in addition to the actual room ID (but always do the actual one first as it's quicker in the common case)
|
// in addition to the actual room ID (but always do the actual one first as it's quicker in the common case)
|
||||||
allowJoinedToRoomIDs := []string{roomID}
|
allowJoinedToRoomIDs := []string{roomID}
|
||||||
joinRuleEv := queryRoomRes.StateEvents[joinRuleTuple]
|
joinRuleEv := queryRoomRes.StateEvents[joinRuleTuple]
|
||||||
|
|
||||||
if joinRuleEv != nil {
|
if joinRuleEv != nil {
|
||||||
|
rule, ruleErr := joinRuleEv.JoinRule()
|
||||||
|
if ruleErr != nil {
|
||||||
|
util.GetLogger(w.ctx).WithError(ruleErr).WithField("parent_room_id", roomID).Warn("failed to get join rule")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule == gomatrixserverlib.Public || rule == gomatrixserverlib.Knock {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule == gomatrixserverlib.Restricted {
|
||||||
allowJoinedToRoomIDs = append(allowJoinedToRoomIDs, w.restrictedJoinRuleAllowedRooms(joinRuleEv, "m.room_membership")...)
|
allowJoinedToRoomIDs = append(allowJoinedToRoomIDs, w.restrictedJoinRuleAllowedRooms(joinRuleEv, "m.room_membership")...)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if server is joined to any allowed room
|
// check if server is joined to any allowed room
|
||||||
for _, allowedRoomID := range allowJoinedToRoomIDs {
|
for _, allowedRoomID := range allowJoinedToRoomIDs {
|
||||||
|
@ -537,7 +550,8 @@ func (w *walker) authorisedServer(roomID string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// authorisedUser returns true iff the user is invited/joined this room or the room is world_readable.
|
// authorisedUser returns true iff the user is invited/joined this room or the room is world_readable
|
||||||
|
// or if the room has a public or knock join rule.
|
||||||
// Failing that, if the room has a restricted join rule and belongs to the space parent listed, it will return true.
|
// Failing that, if the room has a restricted join rule and belongs to the space parent listed, it will return true.
|
||||||
func (w *walker) authorisedUser(roomID, parentRoomID string) (authed bool, isJoinedOrInvited bool) {
|
func (w *walker) authorisedUser(roomID, parentRoomID string) (authed bool, isJoinedOrInvited bool) {
|
||||||
hisVisTuple := gomatrixserverlib.StateKeyTuple{
|
hisVisTuple := gomatrixserverlib.StateKeyTuple{
|
||||||
|
@ -579,15 +593,22 @@ func (w *walker) authorisedUser(roomID, parentRoomID string) (authed bool, isJoi
|
||||||
}
|
}
|
||||||
joinRuleEv := queryRes.StateEvents[joinRuleTuple]
|
joinRuleEv := queryRes.StateEvents[joinRuleTuple]
|
||||||
if parentRoomID != "" && joinRuleEv != nil {
|
if parentRoomID != "" && joinRuleEv != nil {
|
||||||
|
var allowed bool
|
||||||
|
rule, ruleErr := joinRuleEv.JoinRule()
|
||||||
|
if ruleErr != nil {
|
||||||
|
util.GetLogger(w.ctx).WithError(ruleErr).WithField("parent_room_id", parentRoomID).Warn("failed to get join rule")
|
||||||
|
} else if rule == gomatrixserverlib.Public || rule == gomatrixserverlib.Knock {
|
||||||
|
allowed = true
|
||||||
|
} else if rule == gomatrixserverlib.Restricted {
|
||||||
allowedRoomIDs := w.restrictedJoinRuleAllowedRooms(joinRuleEv, "m.room_membership")
|
allowedRoomIDs := w.restrictedJoinRuleAllowedRooms(joinRuleEv, "m.room_membership")
|
||||||
// check parent is in the allowed set
|
// check parent is in the allowed set
|
||||||
var allowed bool
|
|
||||||
for _, a := range allowedRoomIDs {
|
for _, a := range allowedRoomIDs {
|
||||||
if parentRoomID == a {
|
if parentRoomID == a {
|
||||||
allowed = true
|
allowed = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if allowed {
|
if allowed {
|
||||||
// ensure caller is joined to the parent room
|
// ensure caller is joined to the parent room
|
||||||
var queryRes2 roomserver.QueryCurrentStateResponse
|
var queryRes2 roomserver.QueryCurrentStateResponse
|
||||||
|
@ -615,7 +636,7 @@ func (w *walker) authorisedUser(roomID, parentRoomID string) (authed bool, isJoi
|
||||||
|
|
||||||
func (w *walker) restrictedJoinRuleAllowedRooms(joinRuleEv *gomatrixserverlib.HeaderedEvent, allowType string) (allows []string) {
|
func (w *walker) restrictedJoinRuleAllowedRooms(joinRuleEv *gomatrixserverlib.HeaderedEvent, allowType string) (allows []string) {
|
||||||
rule, _ := joinRuleEv.JoinRule()
|
rule, _ := joinRuleEv.JoinRule()
|
||||||
if rule != "restricted" {
|
if rule != gomatrixserverlib.Restricted {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var jrContent gomatrixserverlib.JoinRuleContent
|
var jrContent gomatrixserverlib.JoinRuleContent
|
||||||
|
|
Loading…
Reference in a new issue