Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Matrix
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Container Registry
Model registry
Operate
Environments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
TeDomum
Matrix
Commits
5ff3d235
Commit
5ff3d235
authored
7 years ago
by
Erik Johnston
Browse files
Options
Downloads
Patches
Plain Diff
Split event creation into a separate handler
parent
a1beca0e
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
synapse/handlers/message.py
+160
-146
160 additions, 146 deletions
synapse/handlers/message.py
with
160 additions
and
146 deletions
synapse/handlers/message.py
+
160
−
146
View file @
5ff3d235
...
@@ -47,21 +47,9 @@ class MessageHandler(BaseHandler):
...
@@ -47,21 +47,9 @@ class MessageHandler(BaseHandler):
self
.
hs
=
hs
self
.
hs
=
hs
self
.
state
=
hs
.
get_state_handler
()
self
.
state
=
hs
.
get_state_handler
()
self
.
clock
=
hs
.
get_clock
()
self
.
clock
=
hs
.
get_clock
()
self
.
validator
=
EventValidator
()
self
.
profile_handler
=
hs
.
get_profile_handler
()
self
.
pagination_lock
=
ReadWriteLock
()
self
.
pagination_lock
=
ReadWriteLock
()
self
.
pusher_pool
=
hs
.
get_pusherpool
()
# We arbitrarily limit concurrent event creation for a room to 5.
# This is to stop us from diverging history *too* much.
self
.
limiter
=
Limiter
(
max_count
=
5
)
self
.
action_generator
=
hs
.
get_action_generator
()
self
.
spam_checker
=
hs
.
get_spam_checker
()
@defer.inlineCallbacks
@defer.inlineCallbacks
def
purge_history
(
self
,
room_id
,
event_id
):
def
purge_history
(
self
,
room_id
,
event_id
):
event
=
yield
self
.
store
.
get_event
(
event_id
)
event
=
yield
self
.
store
.
get_event
(
event_id
)
...
@@ -182,6 +170,162 @@ class MessageHandler(BaseHandler):
...
@@ -182,6 +170,162 @@ class MessageHandler(BaseHandler):
defer
.
returnValue
(
chunk
)
defer
.
returnValue
(
chunk
)
@defer.inlineCallbacks
def
get_room_data
(
self
,
user_id
=
None
,
room_id
=
None
,
event_type
=
None
,
state_key
=
""
,
is_guest
=
False
):
"""
Get data from a room.
Args:
event : The room path event
Returns:
The path data content.
Raises:
SynapseError if something went wrong.
"""
membership
,
membership_event_id
=
yield
self
.
_check_in_room_or_world_readable
(
room_id
,
user_id
)
if
membership
==
Membership
.
JOIN
:
data
=
yield
self
.
state_handler
.
get_current_state
(
room_id
,
event_type
,
state_key
)
elif
membership
==
Membership
.
LEAVE
:
key
=
(
event_type
,
state_key
)
room_state
=
yield
self
.
store
.
get_state_for_events
(
[
membership_event_id
],
[
key
]
)
data
=
room_state
[
membership_event_id
].
get
(
key
)
defer
.
returnValue
(
data
)
@defer.inlineCallbacks
def
_check_in_room_or_world_readable
(
self
,
room_id
,
user_id
):
try
:
# check_user_was_in_room will return the most recent membership
# event for the user if:
# * The user is a non-guest user, and was ever in the room
# * The user is a guest user, and has joined the room
# else it will throw.
member_event
=
yield
self
.
auth
.
check_user_was_in_room
(
room_id
,
user_id
)
defer
.
returnValue
((
member_event
.
membership
,
member_event
.
event_id
))
return
except
AuthError
:
visibility
=
yield
self
.
state_handler
.
get_current_state
(
room_id
,
EventTypes
.
RoomHistoryVisibility
,
""
)
if
(
visibility
and
visibility
.
content
[
"
history_visibility
"
]
==
"
world_readable
"
):
defer
.
returnValue
((
Membership
.
JOIN
,
None
))
return
raise
AuthError
(
403
,
"
Guest access not allowed
"
,
errcode
=
Codes
.
GUEST_ACCESS_FORBIDDEN
)
@defer.inlineCallbacks
def
get_state_events
(
self
,
user_id
,
room_id
,
is_guest
=
False
):
"""
Retrieve all state events for a given room. If the user is
joined to the room then return the current state. If the user has
left the room return the state events from when they left.
Args:
user_id(str): The user requesting state events.
room_id(str): The room ID to get all state events from.
Returns:
A list of dicts representing state events. [{}, {}, {}]
"""
membership
,
membership_event_id
=
yield
self
.
_check_in_room_or_world_readable
(
room_id
,
user_id
)
if
membership
==
Membership
.
JOIN
:
room_state
=
yield
self
.
state_handler
.
get_current_state
(
room_id
)
elif
membership
==
Membership
.
LEAVE
:
room_state
=
yield
self
.
store
.
get_state_for_events
(
[
membership_event_id
],
None
)
room_state
=
room_state
[
membership_event_id
]
now
=
self
.
clock
.
time_msec
()
defer
.
returnValue
(
[
serialize_event
(
c
,
now
)
for
c
in
room_state
.
values
()]
)
@defer.inlineCallbacks
def
get_joined_members
(
self
,
requester
,
room_id
):
"""
Get all the joined members in the room and their profile information.
If the user has left the room return the state events from when they left.
Args:
requester(Requester): The user requesting state events.
room_id(str): The room ID to get all state events from.
Returns:
A dict of user_id to profile info
"""
user_id
=
requester
.
user
.
to_string
()
if
not
requester
.
app_service
:
# We check AS auth after fetching the room membership, as it
# requires us to pull out all joined members anyway.
membership
,
_
=
yield
self
.
_check_in_room_or_world_readable
(
room_id
,
user_id
)
if
membership
!=
Membership
.
JOIN
:
raise
NotImplementedError
(
"
Getting joined members after leaving is not implemented
"
)
users_with_profile
=
yield
self
.
state
.
get_current_user_in_room
(
room_id
)
# If this is an AS, double check that they are allowed to see the members.
# This can either be because the AS user is in the room or becuase there
# is a user in the room that the AS is "interested in"
if
requester
.
app_service
and
user_id
not
in
users_with_profile
:
for
uid
in
users_with_profile
:
if
requester
.
app_service
.
is_interested_in_user
(
uid
):
break
else
:
# Loop fell through, AS has no interested users in room
raise
AuthError
(
403
,
"
Appservice not in room
"
)
defer
.
returnValue
({
user_id
:
{
"
avatar_url
"
:
profile
.
avatar_url
,
"
display_name
"
:
profile
.
display_name
,
}
for
user_id
,
profile
in
users_with_profile
.
iteritems
()
})
class
EventCreationHandler
(
object
):
def
__init__
(
self
,
hs
):
self
.
hs
=
hs
self
.
auth
=
hs
.
get_auth
()
self
.
store
=
hs
.
get_datastore
()
self
.
state
=
hs
.
get_state_handler
()
self
.
clock
=
hs
.
get_clock
()
self
.
validator
=
EventValidator
()
self
.
profile_handler
=
hs
.
get_profile_handler
()
self
.
event_builder_factory
=
hs
.
get_event_builder_factory
()
self
.
server_name
=
hs
.
hostname
self
.
ratelimiter
=
hs
.
get_ratelimiter
()
self
.
notifier
=
hs
.
get_notifier
()
# This is only used to get at ratelimit function, and maybe_kick_guest_users
self
.
base_handler
=
BaseHandler
(
hs
)
self
.
pusher_pool
=
hs
.
get_pusherpool
()
# We arbitrarily limit concurrent event creation for a room to 5.
# This is to stop us from diverging history *too* much.
self
.
limiter
=
Limiter
(
max_count
=
5
)
self
.
action_generator
=
hs
.
get_action_generator
()
self
.
spam_checker
=
hs
.
get_spam_checker
()
@defer.inlineCallbacks
@defer.inlineCallbacks
def
create_event
(
self
,
requester
,
event_dict
,
token_id
=
None
,
txn_id
=
None
,
def
create_event
(
self
,
requester
,
event_dict
,
token_id
=
None
,
txn_id
=
None
,
prev_event_ids
=
None
):
prev_event_ids
=
None
):
...
@@ -262,7 +406,7 @@ class MessageHandler(BaseHandler):
...
@@ -262,7 +406,7 @@ class MessageHandler(BaseHandler):
# We check here if we are currently being rate limited, so that we
# We check here if we are currently being rate limited, so that we
# don't do unnecessary work. We check again just before we actually
# don't do unnecessary work. We check again just before we actually
# send the event.
# send the event.
yield
self
.
ratelimit
(
requester
,
update
=
False
)
yield
self
.
base_handler
.
ratelimit
(
requester
,
update
=
False
)
user
=
UserID
.
from_string
(
event
.
sender
)
user
=
UserID
.
from_string
(
event
.
sender
)
...
@@ -342,134 +486,6 @@ class MessageHandler(BaseHandler):
...
@@ -342,134 +486,6 @@ class MessageHandler(BaseHandler):
)
)
defer
.
returnValue
(
event
)
defer
.
returnValue
(
event
)
@defer.inlineCallbacks
def
get_room_data
(
self
,
user_id
=
None
,
room_id
=
None
,
event_type
=
None
,
state_key
=
""
,
is_guest
=
False
):
"""
Get data from a room.
Args:
event : The room path event
Returns:
The path data content.
Raises:
SynapseError if something went wrong.
"""
membership
,
membership_event_id
=
yield
self
.
_check_in_room_or_world_readable
(
room_id
,
user_id
)
if
membership
==
Membership
.
JOIN
:
data
=
yield
self
.
state_handler
.
get_current_state
(
room_id
,
event_type
,
state_key
)
elif
membership
==
Membership
.
LEAVE
:
key
=
(
event_type
,
state_key
)
room_state
=
yield
self
.
store
.
get_state_for_events
(
[
membership_event_id
],
[
key
]
)
data
=
room_state
[
membership_event_id
].
get
(
key
)
defer
.
returnValue
(
data
)
@defer.inlineCallbacks
def
_check_in_room_or_world_readable
(
self
,
room_id
,
user_id
):
try
:
# check_user_was_in_room will return the most recent membership
# event for the user if:
# * The user is a non-guest user, and was ever in the room
# * The user is a guest user, and has joined the room
# else it will throw.
member_event
=
yield
self
.
auth
.
check_user_was_in_room
(
room_id
,
user_id
)
defer
.
returnValue
((
member_event
.
membership
,
member_event
.
event_id
))
return
except
AuthError
:
visibility
=
yield
self
.
state_handler
.
get_current_state
(
room_id
,
EventTypes
.
RoomHistoryVisibility
,
""
)
if
(
visibility
and
visibility
.
content
[
"
history_visibility
"
]
==
"
world_readable
"
):
defer
.
returnValue
((
Membership
.
JOIN
,
None
))
return
raise
AuthError
(
403
,
"
Guest access not allowed
"
,
errcode
=
Codes
.
GUEST_ACCESS_FORBIDDEN
)
@defer.inlineCallbacks
def
get_state_events
(
self
,
user_id
,
room_id
,
is_guest
=
False
):
"""
Retrieve all state events for a given room. If the user is
joined to the room then return the current state. If the user has
left the room return the state events from when they left.
Args:
user_id(str): The user requesting state events.
room_id(str): The room ID to get all state events from.
Returns:
A list of dicts representing state events. [{}, {}, {}]
"""
membership
,
membership_event_id
=
yield
self
.
_check_in_room_or_world_readable
(
room_id
,
user_id
)
if
membership
==
Membership
.
JOIN
:
room_state
=
yield
self
.
state_handler
.
get_current_state
(
room_id
)
elif
membership
==
Membership
.
LEAVE
:
room_state
=
yield
self
.
store
.
get_state_for_events
(
[
membership_event_id
],
None
)
room_state
=
room_state
[
membership_event_id
]
now
=
self
.
clock
.
time_msec
()
defer
.
returnValue
(
[
serialize_event
(
c
,
now
)
for
c
in
room_state
.
values
()]
)
@defer.inlineCallbacks
def
get_joined_members
(
self
,
requester
,
room_id
):
"""
Get all the joined members in the room and their profile information.
If the user has left the room return the state events from when they left.
Args:
requester(Requester): The user requesting state events.
room_id(str): The room ID to get all state events from.
Returns:
A dict of user_id to profile info
"""
user_id
=
requester
.
user
.
to_string
()
if
not
requester
.
app_service
:
# We check AS auth after fetching the room membership, as it
# requires us to pull out all joined members anyway.
membership
,
_
=
yield
self
.
_check_in_room_or_world_readable
(
room_id
,
user_id
)
if
membership
!=
Membership
.
JOIN
:
raise
NotImplementedError
(
"
Getting joined members after leaving is not implemented
"
)
users_with_profile
=
yield
self
.
state
.
get_current_user_in_room
(
room_id
)
# If this is an AS, double check that they are allowed to see the members.
# This can either be because the AS user is in the room or becuase there
# is a user in the room that the AS is "interested in"
if
requester
.
app_service
and
user_id
not
in
users_with_profile
:
for
uid
in
users_with_profile
:
if
requester
.
app_service
.
is_interested_in_user
(
uid
):
break
else
:
# Loop fell through, AS has no interested users in room
raise
AuthError
(
403
,
"
Appservice not in room
"
)
defer
.
returnValue
({
user_id
:
{
"
avatar_url
"
:
profile
.
avatar_url
,
"
display_name
"
:
profile
.
display_name
,
}
for
user_id
,
profile
in
users_with_profile
.
iteritems
()
})
@measure_func
(
"
_create_new_client_event
"
)
@measure_func
(
"
_create_new_client_event
"
)
@defer.inlineCallbacks
@defer.inlineCallbacks
def
_create_new_client_event
(
self
,
builder
,
requester
=
None
,
prev_event_ids
=
None
):
def
_create_new_client_event
(
self
,
builder
,
requester
=
None
,
prev_event_ids
=
None
):
...
@@ -509,9 +525,7 @@ class MessageHandler(BaseHandler):
...
@@ -509,9 +525,7 @@ class MessageHandler(BaseHandler):
builder
.
prev_events
=
prev_events
builder
.
prev_events
=
prev_events
builder
.
depth
=
depth
builder
.
depth
=
depth
state_handler
=
self
.
state_handler
context
=
yield
self
.
state
.
compute_event_context
(
builder
)
context
=
yield
state_handler
.
compute_event_context
(
builder
)
if
requester
:
if
requester
:
context
.
app_service
=
requester
.
app_service
context
.
app_service
=
requester
.
app_service
...
@@ -551,7 +565,7 @@ class MessageHandler(BaseHandler):
...
@@ -551,7 +565,7 @@ class MessageHandler(BaseHandler):
# We now need to go and hit out to wherever we need to hit out to.
# We now need to go and hit out to wherever we need to hit out to.
if
ratelimit
:
if
ratelimit
:
yield
self
.
ratelimit
(
requester
)
yield
self
.
base_handler
.
ratelimit
(
requester
)
try
:
try
:
yield
self
.
auth
.
check_from_context
(
event
,
context
)
yield
self
.
auth
.
check_from_context
(
event
,
context
)
...
@@ -567,7 +581,7 @@ class MessageHandler(BaseHandler):
...
@@ -567,7 +581,7 @@ class MessageHandler(BaseHandler):
logger
.
exception
(
"
Failed to encode content: %r
"
,
event
.
content
)
logger
.
exception
(
"
Failed to encode content: %r
"
,
event
.
content
)
raise
raise
yield
self
.
maybe_kick_guest_users
(
event
,
context
)
yield
self
.
base_handler
.
maybe_kick_guest_users
(
event
,
context
)
if
event
.
type
==
EventTypes
.
CanonicalAlias
:
if
event
.
type
==
EventTypes
.
CanonicalAlias
:
# Check the alias is acually valid (at this time at least)
# Check the alias is acually valid (at this time at least)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment