Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
synapse
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Monitor
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Timo Ley
synapse
Commits
d33ae65e
Commit
d33ae65e
authored
9 years ago
by
Kegan Dougal
Browse files
Options
Downloads
Patches
Plain Diff
Remove more reg/unreg methods. Read config not database for cache.
parent
e7887e37
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
synapse/handlers/appservice.py
+0
-37
0 additions, 37 deletions
synapse/handlers/appservice.py
synapse/storage/appservice.py
+59
-160
59 additions, 160 deletions
synapse/storage/appservice.py
tests/storage/test_appservice.py
+0
-39
0 additions, 39 deletions
tests/storage/test_appservice.py
with
59 additions
and
236 deletions
synapse/handlers/appservice.py
+
0
−
37
View file @
d33ae65e
...
@@ -16,10 +16,8 @@
...
@@ -16,10 +16,8 @@
from
twisted.internet
import
defer
from
twisted.internet
import
defer
from
synapse.api.constants
import
EventTypes
,
Membership
from
synapse.api.constants
import
EventTypes
,
Membership
from
synapse.api.errors
import
Codes
,
StoreError
,
SynapseError
from
synapse.appservice
import
ApplicationService
from
synapse.appservice
import
ApplicationService
from
synapse.types
import
UserID
from
synapse.types
import
UserID
import
synapse.util.stringutils
as
stringutils
import
logging
import
logging
...
@@ -49,38 +47,6 @@ class ApplicationServicesHandler(object):
...
@@ -49,38 +47,6 @@ class ApplicationServicesHandler(object):
self
.
scheduler
=
appservice_scheduler
self
.
scheduler
=
appservice_scheduler
self
.
started_scheduler
=
False
self
.
started_scheduler
=
False
@defer.inlineCallbacks
def
register
(
self
,
app_service
):
logger
.
info
(
"
Register -> %s
"
,
app_service
)
# check the token is recognised
try
:
stored_service
=
yield
self
.
store
.
get_app_service_by_token
(
app_service
.
token
)
if
not
stored_service
:
raise
StoreError
(
404
,
"
Application service not found
"
)
app_service
.
id
=
stored_service
.
id
except
StoreError
:
raise
SynapseError
(
403
,
"
Unrecognised application services token.
"
"
Consult the home server admin.
"
,
errcode
=
Codes
.
FORBIDDEN
)
app_service
.
hs_token
=
self
.
_generate_hs_token
()
# create a sender for this application service which is used when
# creating rooms, etc..
account
=
yield
self
.
hs
.
get_handlers
().
registration_handler
.
register
()
app_service
.
sender
=
account
[
0
]
yield
self
.
store
.
update_app_service
(
app_service
)
defer
.
returnValue
(
app_service
)
@defer.inlineCallbacks
def
unregister
(
self
,
token
):
logger
.
info
(
"
Unregister as_token=%s
"
,
token
)
yield
self
.
store
.
unregister_app_service
(
token
)
@defer.inlineCallbacks
@defer.inlineCallbacks
def
notify_interested_services
(
self
,
event
):
def
notify_interested_services
(
self
,
event
):
"""
Notifies (pushes) all application services interested in this event.
"""
Notifies (pushes) all application services interested in this event.
...
@@ -223,6 +189,3 @@ class ApplicationServicesHandler(object):
...
@@ -223,6 +189,3 @@ class ApplicationServicesHandler(object):
exists
=
yield
self
.
query_user_exists
(
user_id
)
exists
=
yield
self
.
query_user_exists
(
user_id
)
defer
.
returnValue
(
exists
)
defer
.
returnValue
(
exists
)
defer
.
returnValue
(
True
)
defer
.
returnValue
(
True
)
def
_generate_hs_token
(
self
):
return
stringutils
.
random_string
(
24
)
This diff is collapsed.
Click to expand it.
synapse/storage/appservice.py
+
59
−
160
View file @
d33ae65e
...
@@ -13,12 +13,12 @@
...
@@ -13,12 +13,12 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
import
logging
import
logging
import
yaml
from
simplejson
import
JSONDecodeError
from
simplejson
import
JSONDecodeError
import
simplejson
as
json
import
simplejson
as
json
from
twisted.internet
import
defer
from
twisted.internet
import
defer
from
synapse.api.constants
import
Membership
from
synapse.api.constants
import
Membership
from
synapse.api.errors
import
StoreError
from
synapse.appservice
import
ApplicationService
,
AppServiceTransaction
from
synapse.appservice
import
ApplicationService
,
AppServiceTransaction
from
synapse.storage.roommember
import
RoomsForUser
from
synapse.storage.roommember
import
RoomsForUser
from
._base
import
SQLBaseStore
from
._base
import
SQLBaseStore
...
@@ -27,141 +27,18 @@ from ._base import SQLBaseStore
...
@@ -27,141 +27,18 @@ from ._base import SQLBaseStore
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
def
log_failure
(
failure
):
logger
.
error
(
"
Failed to detect application services: %s
"
,
failure
.
value
)
logger
.
error
(
failure
.
getTraceback
())
class
ApplicationServiceStore
(
SQLBaseStore
):
class
ApplicationServiceStore
(
SQLBaseStore
):
def
__init__
(
self
,
hs
):
def
__init__
(
self
,
hs
):
super
(
ApplicationServiceStore
,
self
).
__init__
(
hs
)
super
(
ApplicationServiceStore
,
self
).
__init__
(
hs
)
self
.
services_cache
=
[]
self
.
services_cache
=
[]
self
.
cache_defer
=
self
.
_populate_appservice_cache
()
self
.
_populate_appservice_cache
(
self
.
cache_defer
.
addErrback
(
log_failure
)
hs
.
config
.
app_service_config_files
@defer.inlineCallbacks
def
unregister_app_service
(
self
,
token
):
"""
Unregisters this service.
This removes all AS specific regex and the base URL. The token is the
only thing preserved for future registration attempts.
"""
yield
self
.
cache_defer
# make sure the cache is ready
yield
self
.
runInteraction
(
"
unregister_app_service
"
,
self
.
_unregister_app_service_txn
,
token
,
)
# update cache TODO: Should this be in the txn?
for
service
in
self
.
services_cache
:
if
service
.
token
==
token
:
service
.
url
=
None
service
.
namespaces
=
None
service
.
hs_token
=
None
def
_unregister_app_service_txn
(
self
,
txn
,
token
):
# kill the url to prevent pushes
txn
.
execute
(
"
UPDATE application_services SET url=NULL WHERE token=?
"
,
(
token
,)
)
# cleanup regex
as_id
=
self
.
_get_as_id_txn
(
txn
,
token
)
if
not
as_id
:
logger
.
warning
(
"
unregister_app_service_txn: Failed to find as_id for token=
"
,
token
)
return
False
txn
.
execute
(
"
DELETE FROM application_services_regex WHERE as_id=?
"
,
(
as_id
,)
)
return
True
@defer.inlineCallbacks
def
update_app_service
(
self
,
service
):
"""
Update an application service, clobbering what was previously there.
Args:
service(ApplicationService): The updated service.
"""
yield
self
.
cache_defer
# make sure the cache is ready
# NB: There is no "insert" since we provide no public-facing API to
# allocate new ASes. It relies on the server admin inserting the AS
# token into the database manually.
if
not
service
.
token
or
not
service
.
url
:
raise
StoreError
(
400
,
"
Token and url must be specified.
"
)
if
not
service
.
hs_token
:
raise
StoreError
(
500
,
"
No HS token
"
)
as_id
=
yield
self
.
runInteraction
(
"
update_app_service
"
,
self
.
_update_app_service_txn
,
service
)
)
service
.
id
=
as_id
# update cache TODO: Should this be in the txn?
for
(
index
,
cache_service
)
in
enumerate
(
self
.
services_cache
):
if
service
.
token
==
cache_service
.
token
:
self
.
services_cache
[
index
]
=
service
logger
.
info
(
"
Updated: %s
"
,
service
)
return
# new entry
self
.
services_cache
.
append
(
service
)
logger
.
info
(
"
Updated(new): %s
"
,
service
)
def
_update_app_service_txn
(
self
,
txn
,
service
):
as_id
=
self
.
_get_as_id_txn
(
txn
,
service
.
token
)
if
not
as_id
:
logger
.
warning
(
"
update_app_service_txn: Failed to find as_id for token=
"
,
service
.
token
)
return
txn
.
execute
(
"
UPDATE application_services SET url=?, hs_token=?, sender=?
"
"
WHERE id=?
"
,
(
service
.
url
,
service
.
hs_token
,
service
.
sender
,
as_id
,)
)
# cleanup regex
txn
.
execute
(
"
DELETE FROM application_services_regex WHERE as_id=?
"
,
(
as_id
,)
)
for
(
ns_int
,
ns_str
)
in
enumerate
(
ApplicationService
.
NS_LIST
):
if
ns_str
in
service
.
namespaces
:
for
regex_obj
in
service
.
namespaces
[
ns_str
]:
txn
.
execute
(
"
INSERT INTO application_services_regex(
"
"
as_id, namespace, regex) values(?,?,?)
"
,
(
as_id
,
ns_int
,
json
.
dumps
(
regex_obj
))
)
return
as_id
def
_get_as_id_txn
(
self
,
txn
,
token
):
cursor
=
txn
.
execute
(
"
SELECT id FROM application_services WHERE token=?
"
,
(
token
,)
)
res
=
cursor
.
fetchone
()
if
res
:
return
res
[
0
]
@defer.inlineCallbacks
def
get_app_services
(
self
):
def
get_app_services
(
self
):
yield
self
.
cache_defer
# make sure the cache is ready
defer
.
succeed
(
self
.
services_cache
)
defer
.
returnValue
(
self
.
services_cache
)
@defer.inlineCallbacks
def
get_app_service_by_user_id
(
self
,
user_id
):
def
get_app_service_by_user_id
(
self
,
user_id
):
"""
Retrieve an application service from their user ID.
"""
Retrieve an application service from their user ID.
...
@@ -175,37 +52,24 @@ class ApplicationServiceStore(SQLBaseStore):
...
@@ -175,37 +52,24 @@ class ApplicationServiceStore(SQLBaseStore):
Returns:
Returns:
synapse.appservice.ApplicationService or None.
synapse.appservice.ApplicationService or None.
"""
"""
yield
self
.
cache_defer
# make sure the cache is ready
for
service
in
self
.
services_cache
:
for
service
in
self
.
services_cache
:
if
service
.
sender
==
user_id
:
if
service
.
sender
==
user_id
:
defer
.
returnValue
(
service
)
defer
.
succeed
(
service
)
return
return
defer
.
returnValue
(
None
)
defer
.
succeed
(
None
)
@defer.inlineCallbacks
def
get_app_service_by_token
(
self
,
token
):
def
get_app_service_by_token
(
self
,
token
,
from_cache
=
True
):
"""
Get the application service with the given appservice token.
"""
Get the application service with the given appservice token.
Args:
Args:
token (str): The application service token.
token (str): The application service token.
from_cache (bool): True to get this service from the cache, False to
Returns:
check the database.
synapse.appservice.ApplicationService or None.
Raises:
StoreError if there was a problem retrieving this service.
"""
"""
yield
self
.
cache_defer
# make sure the cache is ready
for
service
in
self
.
services_cache
:
if
service
.
token
==
token
:
if
from_cache
:
return
defer
.
succeed
(
service
)
for
service
in
self
.
services_cache
:
defer
.
succeed
(
None
)
if
service
.
token
==
token
:
defer
.
returnValue
(
service
)
return
defer
.
returnValue
(
None
)
# TODO: The from_cache=False impl
# TODO: This should be JOINed with the application_services_regex table.
def
get_app_service_rooms
(
self
,
service
):
def
get_app_service_rooms
(
self
,
service
):
"""
Get a list of RoomsForUser for this application service.
"""
Get a list of RoomsForUser for this application service.
...
@@ -336,18 +200,53 @@ class ApplicationServiceStore(SQLBaseStore):
...
@@ -336,18 +200,53 @@ class ApplicationServiceStore(SQLBaseStore):
))
))
return
service_list
return
service_list
@defer.inlineCallbacks
def
_load_appservice
(
self
,
as_info
):
def
_populate_appservice_cache
(
self
):
required_string_fields
=
[
"
url
"
,
"
as_token
"
,
"
hs_token
"
,
"
sender
"
]
"""
Populates the ApplicationServiceCache from the database.
"""
for
field
in
required_string_fields
:
sql
=
(
"
SELECT r.*, a.* FROM application_services AS a LEFT JOIN
"
if
not
isinstance
(
as_info
.
get
(
field
),
basestring
):
"
application_services_regex AS r ON a.id = r.as_id
"
)
raise
KeyError
(
"
Required string field:
'
%s
'"
,
field
)
results
=
yield
self
.
_execute_and_decode
(
"
appservice_cache
"
,
sql
)
# namespace checks
services
=
self
.
_parse_services_dict
(
results
)
if
not
isinstance
(
as_info
.
get
(
"
namespaces
"
),
dict
):
raise
KeyError
(
"
Requires
'
namespaces
'
object.
"
)
for
ns
in
ApplicationService
.
NS_LIST
:
# specific namespaces are optional
if
ns
in
as_info
[
"
namespaces
"
]:
# expect a list of dicts with exclusive and regex keys
for
regex_obj
in
as_info
[
"
namespaces
"
][
ns
]:
if
not
isinstance
(
regex_obj
,
dict
):
raise
ValueError
(
"
Expected namespace entry in %s to be an object,
"
"
but got %s
"
,
ns
,
regex_obj
)
if
not
isinstance
(
regex_obj
.
get
(
"
regex
"
),
basestring
):
raise
ValueError
(
"
Missing/bad type
'
regex
'
key in %s
"
,
regex_obj
)
if
not
isinstance
(
regex_obj
.
get
(
"
exclusive
"
),
bool
):
raise
ValueError
(
"
Missing/bad type
'
exclusive
'
key in %s
"
,
regex_obj
)
return
ApplicationService
(
token
=
as_info
[
"
as_token
"
],
url
=
as_info
[
"
url
"
],
namespaces
=
as_info
[
"
namespaces
"
],
hs_token
=
as_info
[
"
hs_token
"
],
sender
=
as_info
[
"
sender
"
]
)
for
service
in
services
:
def
_populate_appservice_cache
(
self
,
config_files
):
logger
.
info
(
"
Found application service: %s
"
,
service
)
"""
Populates a cache of Application Services from the config files.
"""
self
.
services_cache
.
append
(
service
)
for
config_file
in
config_files
:
try
:
with
open
(
config_file
,
'
r
'
)
as
f
:
as_info
=
yaml
.
load
(
f
)
appservice
=
self
.
_load_appservice
(
as_info
)
logger
.
info
(
"
Loaded application service: %s
"
,
appservice
)
self
.
services_cache
.
append
(
appservice
)
except
Exception
as
e
:
logger
.
error
(
"
Failed to load appservice from
'
%s
'"
,
config_file
)
logger
.
exception
(
e
)
class
ApplicationServiceTransactionStore
(
SQLBaseStore
):
class
ApplicationServiceTransactionStore
(
SQLBaseStore
):
...
...
This diff is collapsed.
Click to expand it.
tests/storage/test_appservice.py
+
0
−
39
View file @
d33ae65e
...
@@ -49,45 +49,6 @@ class ApplicationServiceStoreTestCase(unittest.TestCase):
...
@@ -49,45 +49,6 @@ class ApplicationServiceStoreTestCase(unittest.TestCase):
# must be done after inserts
# must be done after inserts
self
.
store
=
ApplicationServiceStore
(
hs
)
self
.
store
=
ApplicationServiceStore
(
hs
)
@defer.inlineCallbacks
def
test_update_and_retrieval_of_service
(
self
):
url
=
"
https://matrix.org/appservices/foobar
"
hs_token
=
"
hstok
"
user_regex
=
[
{
"
regex
"
:
"
@foobar_.*:matrix.org
"
,
"
exclusive
"
:
True
}
]
alias_regex
=
[
{
"
regex
"
:
"
#foobar_.*:matrix.org
"
,
"
exclusive
"
:
False
}
]
room_regex
=
[
]
service
=
ApplicationService
(
url
=
url
,
hs_token
=
hs_token
,
token
=
self
.
as_token
,
namespaces
=
{
ApplicationService
.
NS_USERS
:
user_regex
,
ApplicationService
.
NS_ALIASES
:
alias_regex
,
ApplicationService
.
NS_ROOMS
:
room_regex
})
yield
self
.
store
.
update_app_service
(
service
)
stored_service
=
yield
self
.
store
.
get_app_service_by_token
(
self
.
as_token
)
self
.
assertEquals
(
stored_service
.
token
,
self
.
as_token
)
self
.
assertEquals
(
stored_service
.
url
,
url
)
self
.
assertEquals
(
stored_service
.
namespaces
[
ApplicationService
.
NS_ALIASES
],
alias_regex
)
self
.
assertEquals
(
stored_service
.
namespaces
[
ApplicationService
.
NS_ROOMS
],
room_regex
)
self
.
assertEquals
(
stored_service
.
namespaces
[
ApplicationService
.
NS_USERS
],
user_regex
)
@defer.inlineCallbacks
@defer.inlineCallbacks
def
test_retrieve_unknown_service_token
(
self
):
def
test_retrieve_unknown_service_token
(
self
):
service
=
yield
self
.
store
.
get_app_service_by_token
(
"
invalid_token
"
)
service
=
yield
self
.
store
.
get_app_service_by_token
(
"
invalid_token
"
)
...
...
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