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.

This commit is contained in:
Kegan Dougal 2014-08-18 15:50:55 +01:00
parent a18b1a649c
commit 35da1bf4a3
4 changed files with 62 additions and 31 deletions

View File

@ -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

View File

@ -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):

View File

@ -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,19 +29,17 @@ 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);
}).
error(function(data, status, headers, config) {
console.log(" -> Failed to upload " + file.name); console.log(" -> Failed to upload " + file.name);
deferred.reject(); deferred.reject(error);
}); }
);
return deferred.promise; return deferred.promise;
}; };

View File

@ -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";