mirror of
https://github.com/element-hq/synapse
synced 2024-10-06 12:22:40 +00:00
Move QR code to client API
This commit is contained in:
parent
24b8c58fb2
commit
64afabd0bf
3 changed files with 2 additions and 110 deletions
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
room, events, register, login, profile, presence, initial_sync, directory,
|
room, events, register, login, profile, presence, initial_sync, directory,
|
||||||
voip, admin, pusher, push_rule
|
voip, admin, pusher, push_rule, login_qr
|
||||||
)
|
)
|
||||||
|
|
||||||
from synapse.http.server import JsonResource
|
from synapse.http.server import JsonResource
|
||||||
|
@ -42,3 +42,4 @@ class ClientV1RestResource(JsonResource):
|
||||||
admin.register_servlets(hs, client_resource)
|
admin.register_servlets(hs, client_resource)
|
||||||
pusher.register_servlets(hs, client_resource)
|
pusher.register_servlets(hs, client_resource)
|
||||||
push_rule.register_servlets(hs, client_resource)
|
push_rule.register_servlets(hs, client_resource)
|
||||||
|
login_qr.register_servlets(hs, client_resource)
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
# Copyright 2015 OpenMarket Ltd
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
from twisted.web.resource import Resource
|
|
||||||
from twisted.web.server import NOT_DONE_YET
|
|
||||||
from twisted.internet import defer, threads
|
|
||||||
|
|
||||||
from synapse.api.errors import CodeMessageException
|
|
||||||
from synapse.util.stringutils import random_string
|
|
||||||
|
|
||||||
import simplejson
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from unpaddedbase64 import encode_base64
|
|
||||||
from hashlib import sha256
|
|
||||||
from OpenSSL import crypto
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class LoginQRResource(Resource):
|
|
||||||
isLeaf = True
|
|
||||||
|
|
||||||
def __init__(self, hs):
|
|
||||||
Resource.__init__(self)
|
|
||||||
self.hs = hs
|
|
||||||
self.auth = hs.get_auth()
|
|
||||||
self.handlers = hs.get_handlers()
|
|
||||||
self.config = hs.get_config()
|
|
||||||
|
|
||||||
def render_GET(self, request):
|
|
||||||
self._async_render_GET(request)
|
|
||||||
return NOT_DONE_YET
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
|
||||||
def _async_render_GET(self, request):
|
|
||||||
try:
|
|
||||||
auth_user, _ = yield self.auth.get_user_by_req(request)
|
|
||||||
|
|
||||||
nonce = request.path.split("/")[-1]
|
|
||||||
|
|
||||||
if not nonce:
|
|
||||||
nonce = random_string(10)
|
|
||||||
|
|
||||||
image = yield self.make_short_term_qr_code(
|
|
||||||
auth_user.to_string(), nonce
|
|
||||||
)
|
|
||||||
|
|
||||||
request.setHeader(b"Content-Type", b"image/png")
|
|
||||||
|
|
||||||
image.save(request)
|
|
||||||
request.finish()
|
|
||||||
except CodeMessageException as e:
|
|
||||||
logger.info("Returning: %s", e)
|
|
||||||
request.setResponseCode(e.code)
|
|
||||||
request.write("%s: %s" % (e.code, e.message))
|
|
||||||
request.finish()
|
|
||||||
except Exception:
|
|
||||||
logger.exception("Exception while generating token")
|
|
||||||
request.setResponseCode(500)
|
|
||||||
request.write("Internal server error")
|
|
||||||
request.finish()
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
|
||||||
def make_short_term_qr_code(self, user_id, nonce):
|
|
||||||
h = self.handlers.auth_handler
|
|
||||||
token = h.make_short_term_token(user_id, nonce)
|
|
||||||
|
|
||||||
x509_certificate_bytes = crypto.dump_certificate(
|
|
||||||
crypto.FILETYPE_ASN1,
|
|
||||||
self.config.tls_certificate
|
|
||||||
)
|
|
||||||
|
|
||||||
sha256_fingerprint = sha256(x509_certificate_bytes).digest()
|
|
||||||
|
|
||||||
def gen():
|
|
||||||
import qrcode
|
|
||||||
qr = qrcode.QRCode(
|
|
||||||
version=1,
|
|
||||||
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
|
||||||
box_size=5,
|
|
||||||
)
|
|
||||||
qr.add_data(simplejson.dumps({
|
|
||||||
"user_id": user_id,
|
|
||||||
"token": token,
|
|
||||||
"homeserver_url": self.config.client_addr,
|
|
||||||
"fingerprints": [{
|
|
||||||
"hash_type": "SHA256",
|
|
||||||
"bytes": encode_base64(sha256_fingerprint),
|
|
||||||
}],
|
|
||||||
}))
|
|
||||||
qr.make(fit=True)
|
|
||||||
return qr.make_image()
|
|
||||||
|
|
||||||
res = yield threads.deferToThread(gen)
|
|
||||||
defer.returnValue(res)
|
|
|
@ -17,7 +17,6 @@ from .upload_resource import UploadResource
|
||||||
from .download_resource import DownloadResource
|
from .download_resource import DownloadResource
|
||||||
from .thumbnail_resource import ThumbnailResource
|
from .thumbnail_resource import ThumbnailResource
|
||||||
from .identicon_resource import IdenticonResource
|
from .identicon_resource import IdenticonResource
|
||||||
from .login_qr_resource import LoginQRResource
|
|
||||||
from .filepath import MediaFilePaths
|
from .filepath import MediaFilePaths
|
||||||
|
|
||||||
from twisted.web.resource import Resource
|
from twisted.web.resource import Resource
|
||||||
|
@ -79,4 +78,3 @@ class MediaRepositoryResource(Resource):
|
||||||
self.putChild("download", DownloadResource(hs, filepaths))
|
self.putChild("download", DownloadResource(hs, filepaths))
|
||||||
self.putChild("thumbnail", ThumbnailResource(hs, filepaths))
|
self.putChild("thumbnail", ThumbnailResource(hs, filepaths))
|
||||||
self.putChild("identicon", IdenticonResource())
|
self.putChild("identicon", IdenticonResource())
|
||||||
self.putChild("login_qr", LoginQRResource(hs))
|
|
||||||
|
|
Loading…
Reference in a new issue