Auth content uploads. Added a mapping function from request > filename. Added exception handling for content uploads. webclient: Only prefix the client API path on doRequest, not doBaseRequest (this would've broken the identity server auth too). Added matrixService.uploadContent. May not require mFileUpload anymore.
parent
a18b1a649c
commit
35da1bf4a3
|
@ -56,7 +56,7 @@ class SynapseHomeServer(HomeServer):
|
||||||
return File("webclient") # TODO configurable?
|
return File("webclient") # TODO configurable?
|
||||||
|
|
||||||
def build_resource_for_content_repo(self):
|
def build_resource_for_content_repo(self):
|
||||||
return FileUploadResource("uploads")
|
return FileUploadResource("uploads", self.auth)
|
||||||
|
|
||||||
def build_db_pool(self):
|
def build_db_pool(self):
|
||||||
""" Set up all the dbs. Since all the *.sql have IF NOT EXISTS, so we
|
""" Set up all the dbs. Since all the *.sql have IF NOT EXISTS, so we
|
||||||
|
|
|
@ -180,28 +180,48 @@ class RootRedirect(resource.Resource):
|
||||||
class FileUploadResource(resource.Resource):
|
class FileUploadResource(resource.Resource):
|
||||||
isLeaf = True
|
isLeaf = True
|
||||||
|
|
||||||
def __init__(self, directory):
|
def __init__(self, directory, auth, file_map_func=None):
|
||||||
resource.Resource.__init__(self)
|
resource.Resource.__init__(self)
|
||||||
self.directory = directory
|
self.directory = directory
|
||||||
|
self.auth = auth
|
||||||
|
if not file_map_func:
|
||||||
|
file_map_func = self.map_request_to_name
|
||||||
|
self.get_name_for_request = file_map_func
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def map_request_to_name(self, request):
|
||||||
|
# auth the user
|
||||||
|
auth_user = yield self.auth.get_user_by_req(request)
|
||||||
|
logger.info("User %s is uploading a file.", auth_user)
|
||||||
|
defer.returnValue("boo2.png")
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
self._async_render(request)
|
self._async_render(request)
|
||||||
return server.NOT_DONE_YET
|
return server.NOT_DONE_YET
|
||||||
|
|
||||||
# @defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def _async_render(self, request):
|
def _async_render(self, request):
|
||||||
request.setResponseCode(200)
|
try:
|
||||||
request.setHeader(b"Content-Type", b"application/json")
|
fname = yield self.get_name_for_request(request)
|
||||||
|
|
||||||
request.setHeader("Access-Control-Allow-Origin", "*")
|
with open(fname, "wb") as f:
|
||||||
request.setHeader("Access-Control-Allow-Methods",
|
f.write(request.content.read())
|
||||||
"GET, POST, PUT, DELETE, OPTIONS")
|
|
||||||
request.setHeader("Access-Control-Allow-Headers",
|
|
||||||
"Origin, X-Requested-With, Content-Type, Accept")
|
|
||||||
|
|
||||||
request.write(json.dumps({"url": "not_implemented"}))
|
respond_with_json_bytes(request, 200,
|
||||||
request.finish()
|
json.dumps({"url": "not_implemented2"}),
|
||||||
defer.succeed("not implemented")
|
send_cors=True)
|
||||||
|
|
||||||
|
except CodeMessageException as e:
|
||||||
|
logger.exception(e)
|
||||||
|
respond_with_json_bytes(request, e.code,
|
||||||
|
json.dumps(cs_exception(e)))
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Failed to store file: %s" % e)
|
||||||
|
respond_with_json_bytes(
|
||||||
|
request,
|
||||||
|
500,
|
||||||
|
json.dumps({"error": "Internal server error"}),
|
||||||
|
send_cors=True)
|
||||||
|
|
||||||
|
|
||||||
def respond_with_json_bytes(request, code, json_bytes, send_cors=False):
|
def respond_with_json_bytes(request, code, json_bytes, send_cors=False):
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
// TODO determine if this is really required as a separate service to matrixService.
|
||||||
/*
|
/*
|
||||||
* Upload an HTML5 file to a server
|
* Upload an HTML5 file to a server
|
||||||
*/
|
*/
|
||||||
angular.module('mFileUpload', [])
|
angular.module('mFileUpload', [])
|
||||||
.service('mFileUpload', ['$http', '$q', function ($http, $q) {
|
.service('mFileUpload', ['matrixService', '$q', function (matrixService, $q) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Upload an HTML5 file to a server and returned a promise
|
* Upload an HTML5 file to a server and returned a promise
|
||||||
|
@ -28,20 +29,18 @@ angular.module('mFileUpload', [])
|
||||||
*/
|
*/
|
||||||
this.uploadFile = function(file) {
|
this.uploadFile = function(file) {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
console.log("Uploading " + file.name + "... to /matrix/content");
|
||||||
// @TODO: This service runs with the do_POST hacky implementation of /synapse/demos/webserver.py.
|
matrixService.uploadContent(file).then(
|
||||||
// This is temporary until we have a true file upload service
|
function(response) {
|
||||||
console.log("Uploading " + file.name + "...");
|
console.log(" -> Successfully uploaded! Available at " + location.origin + response.data.url);
|
||||||
$http.post(file.name, file)
|
deferred.resolve(location.origin + response.data.url);
|
||||||
.success(function(data, status, headers, config) {
|
},
|
||||||
deferred.resolve(location.origin + data.url);
|
function(error) {
|
||||||
console.log(" -> Successfully uploaded! Available at " + location.origin + data.url);
|
console.log(" -> Failed to upload " + file.name);
|
||||||
}).
|
deferred.reject(error);
|
||||||
error(function(data, status, headers, config) {
|
}
|
||||||
console.log(" -> Failed to upload" + file.name);
|
);
|
||||||
deferred.reject();
|
|
||||||
});
|
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -54,13 +54,14 @@ angular.module('matrixService', [])
|
||||||
|
|
||||||
params.access_token = config.access_token;
|
params.access_token = config.access_token;
|
||||||
|
|
||||||
|
if (path.indexOf(prefixPath) !== 0) {
|
||||||
|
path = prefixPath + path;
|
||||||
|
}
|
||||||
|
|
||||||
return doBaseRequest(config.homeserver, method, path, params, data, undefined);
|
return doBaseRequest(config.homeserver, method, path, params, data, undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
var doBaseRequest = function(baseUrl, method, path, params, data, headers) {
|
var doBaseRequest = function(baseUrl, method, path, params, data, headers) {
|
||||||
if (path.indexOf(prefixPath) !== 0) {
|
|
||||||
path = prefixPath + path;
|
|
||||||
}
|
|
||||||
return $http({
|
return $http({
|
||||||
method: method,
|
method: method,
|
||||||
url: baseUrl + path,
|
url: baseUrl + path,
|
||||||
|
@ -319,6 +320,17 @@ angular.module('matrixService', [])
|
||||||
return doBaseRequest(config.identityServer, "POST", path, {}, data, headers);
|
return doBaseRequest(config.identityServer, "POST", path, {}, data, headers);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
uploadContent: function(file) {
|
||||||
|
var path = "/matrix/content";
|
||||||
|
var headers = {
|
||||||
|
"Content-Type": undefined // undefined means angular will figure it out
|
||||||
|
};
|
||||||
|
var params = {
|
||||||
|
access_token: config.access_token
|
||||||
|
};
|
||||||
|
return doBaseRequest(config.homeserver, "POST", path, params, file, headers);
|
||||||
|
},
|
||||||
|
|
||||||
// start listening on /events
|
// start listening on /events
|
||||||
getEventStream: function(from, timeout) {
|
getEventStream: function(from, timeout) {
|
||||||
var path = "/events";
|
var path = "/events";
|
||||||
|
|
Loading…
Reference in New Issue