Shane Kilkelly 8 лет назад
Родитель
Сommit
b32c9be8ca

+ 28 - 6
services/web/app/coffee/Features/LinkedFiles/LinkedFilesController.coffee

@@ -6,7 +6,6 @@ logger = require 'logger-sharelatex'
 _ = require 'underscore'
 LinkedFilesHandler = require './LinkedFilesHandler'
 {
-
 	UrlFetchFailedError,
 	InvalidUrlError,
 	OutputFileFetchFailedError,
@@ -16,16 +15,23 @@ LinkedFilesHandler = require './LinkedFilesHandler'
 	ProjectNotFoundError,
 	V1ProjectNotFoundError,
 	SourceFileNotFoundError,
+	NotOriginalImporterError,
+	FeatureNotAvailableError,
+	RemoteServiceError
 } = require './LinkedFilesErrors'
+Modules = require '../../infrastructure/Modules'
 
 
 module.exports = LinkedFilesController = {
 
-	Agents: {
-		url: require('./UrlAgent'),
-		project_file: require('./ProjectFileAgent'),
-		project_output_file: require('./ProjectOutputFileAgent')
-	}
+	Agents: _.extend(
+		{
+			url: require('./UrlAgent'),
+			project_file: require('./ProjectFileAgent'),
+			project_output_file: require('./ProjectOutputFileAgent'),
+		},
+		Modules.linkedFileAgentsIncludes()
+	)
 
 	_getAgent: (provider) ->
 		if !LinkedFilesController.Agents.hasOwnProperty(provider)
@@ -117,6 +123,22 @@ module.exports = LinkedFilesController = {
 				"Your URL is not valid. Please check it and try again."
 			)
 
+		else if error instanceof NotOriginalImporterError
+			res.status(400).send(
+				"You are not the user who originally imported this file"
+			)
+
+		else if error instanceof FeatureNotAvailableError
+			res.status(400).send(
+				"This feature is not enabled on your account"
+			)
+
+		else if error instanceof RemoteServiceError
+			res.status(502).send(
+				"The remote service produced an error"
+			)
+
+
 		else
 			next(error)
 }

+ 27 - 0
services/web/app/coffee/Features/LinkedFiles/LinkedFilesErrors.coffee

@@ -70,6 +70,30 @@ SourceFileNotFoundError = (message) ->
 SourceFileNotFoundError.prototype.__proto__ = Error.prototype
 
 
+NotOriginalImporterError = (message) ->
+	error = new Error(message)
+	error.name = 'NotOriginalImporter'
+	error.__proto__ = NotOriginalImporterError.prototype
+	return error
+NotOriginalImporterError.prototype.__proto__ = Error.prototype
+
+
+FeatureNotAvailableError = (message) ->
+	error = new Error(message)
+	error.name = 'FeatureNotAvailable'
+	error.__proto__ = FeatureNotAvailableError.prototype
+	return error
+FeatureNotAvailableError.prototype.__proto__ = Error.prototype
+
+
+RemoteServiceError = (message) ->
+	error = new Error(message)
+	error.name = 'RemoteService'
+	error.__proto__ = RemoteServiceError.prototype
+	return error
+RemoteServiceError.prototype.__proto__ = Error.prototype
+
+
 module.exports = {
 
 	UrlFetchFailedError,
@@ -81,4 +105,7 @@ module.exports = {
 	ProjectNotFoundError,
 	V1ProjectNotFoundError,
 	SourceFileNotFoundError,
+	NotOriginalImporterError,
+	FeatureNotAvailableError,
+	RemoteServiceError
 }

+ 13 - 6
services/web/app/coffee/infrastructure/Modules.coffee

@@ -23,7 +23,7 @@ module.exports = Modules =
 		for module in @modules
 			module.nonCsrfRouter?.apply(webRouter, privateApiRouter, publicApiRouter)
 			module.router?.applyNonCsrfRouter?(webRouter, privateApiRouter, publicApiRouter)
-			
+
 	viewIncludes: {}
 	loadViewIncludes: (app) ->
 		@viewIncludes = {}
@@ -32,7 +32,7 @@ module.exports = Modules =
 				@viewIncludes[view] ||= []
 				filePath = Path.join(MODULE_BASE_PATH, module.name, "app/views", partial + ".pug")
 				@viewIncludes[view].push pug.compileFile(filePath, doctype: "html")
-			
+
 	moduleIncludes: (view, locals) ->
 		compiledPartials = Modules.viewIncludes[view] or []
 		html = ""
@@ -43,7 +43,7 @@ module.exports = Modules =
 
 	moduleIncludesAvailable: (view) ->
 		return (Modules.viewIncludes[view] or []).length > 0
-	
+
 	moduleAssetFiles: (pathPrefix) ->
 		assetFiles = []
 		for module in @modules
@@ -51,18 +51,25 @@ module.exports = Modules =
 				assetFiles.push "#{pathPrefix}#{assetFile}"
 		return assetFiles
 
+	linkedFileAgentsIncludes: () ->
+		agents = {}
+		for module in @modules
+			for name, agentFunction of module.linkedFileAgents
+				agents[name] = agentFunction()
+		return agents
+
 	attachHooks: () ->
 		for module in @modules
 			if module.hooks?
 				for hook, method of module.hooks
 					Modules.hooks.attach hook, method
-			
+
 	hooks:
 		_hooks: {}
 		attach: (name, method) ->
 			@_hooks[name] ?= []
 			@_hooks[name].push method
-			
+
 		fire: (name, args..., callback) ->
 			methods = @_hooks[name] or []
 			call_methods = methods.map (method) ->
@@ -70,5 +77,5 @@ module.exports = Modules =
 			async.series call_methods, (error, results) ->
 				return callback(error) if error?
 				return callback null, results
-		
+
 Modules.loadModules()

+ 6 - 1
services/web/app/views/project/editor/binary-file.pug

@@ -78,6 +78,8 @@ div.binary-file.full-size(
 				|
 				| at {{ openFile.created | formatDate:'h:mm a' }} {{ openFile.created | relativeDate }}
 
+		!= moduleIncludes("binaryFile:linkedFileInfo", locals)
+
 		// Bottom Controls
 		span(ng-if="openFile.linkedFileData.provider")
 			button.btn.btn-success(
@@ -95,7 +97,10 @@ div.binary-file.full-size(
 			i.fa.fa-fw.fa-download
 			|
 			| #{translate("download")}
-		div(ng-if="refreshError")
+
+		// Refresh Error
+		div(ng-if="refreshError").row
 			br
 			.alert.alert-danger.col-md-6.col-md-offset-3
 				| Error: {{ refreshError}}
+				!= moduleIncludes("binaryFile:linkedFileRefreshError", locals)

+ 5 - 0
services/web/app/views/project/editor/new-file-modal.pug

@@ -26,6 +26,8 @@ script(type='text/ng-template', id='newFileModalTemplate')
 								i.fa.fa-fw.fa-globe
 								|
 								| From External URL
+						!= moduleIncludes("newFileModal:selector", locals)
+
 				td(class="modal-new-file--body modal-new-file--body-{{type}}")
 					div(ng-if="type == 'doc'", ng-controller="NewDocModalController")
 						form(novalidate, name="newDocForm")
@@ -175,6 +177,9 @@ script(type='text/ng-template', id='newFileModalTemplate')
 							div(ng-switch="error")
 								span(ng-switch-when="already exists") #{translate("file_already_exists")}
 								span(ng-switch-default) {{error}}
+
+					!= moduleIncludes("newFileModal:panel", locals)
+
 	.modal-footer
 		button.btn.btn-default(
 			ng-disabled="state.inflight"

+ 1 - 1
services/web/docker-compose.yml

@@ -17,7 +17,7 @@ services:
       PROJECT_HISTORY_ENABLED: 'true'
       ENABLED_LINKED_FILE_TYPES: 'url'
       LINKED_URL_PROXY: 'http://localhost:6543'
-      ENABLED_LINKED_FILE_TYPES: 'url,project_file,project_output_file'
+      ENABLED_LINKED_FILE_TYPES: 'url,project_file,project_output_file,mendeley'
       SHARELATEX_CONFIG: /app/test/acceptance/config/settings.test.coffee
     depends_on:
       - redis

+ 10 - 13
services/web/public/stylesheets/app/editor.less

@@ -606,19 +606,16 @@ CodeMirror
 }
 
 .referencesImportModal {
-	.referencesImportPreview {
-		margin-top: 15px;
-		.referencesImportPreviewScroller {
-			font-family: monospace;
-			font-size: 0.8em;
-			max-height: 360px;
-			overflow: scroll;
-			white-space: pre;
-			padding: 8px 12px;
-			margin-bottom: 15px;
-			border: 1px solid @gray-lighter;
-			background-color: @gray-lightest;
-		}
+	.referencesImportPreviewScroller {
+		font-family: monospace;
+		font-size: 0.8em;
+		max-height: 360px;
+		overflow: scroll;
+		white-space: pre;
+		padding: 8px 12px;
+		margin-bottom: 15px;
+		border: 1px solid @gray-lighter;
+		background-color: @gray-lightest;
 	}
 }
 

+ 2 - 0
services/web/test/acceptance/coffee/LinkedFilesTests.coffee

@@ -107,6 +107,7 @@ describe "LinkedFiles", ->
 						source_project_id: @project_two_id,
 						source_entity_path: "/#{@source_doc_name}",
 			}, (error, response, body) =>
+				expect(response.statusCode).to.equal 200
 				new_file_id = body.new_file_id
 				@existing_file_id = new_file_id
 				expect(new_file_id).to.exist
@@ -127,6 +128,7 @@ describe "LinkedFiles", ->
 				url: "/project/#{@project_one_id}/linked_file/#{@existing_file_id}/refresh",
 				json: true
 			}, (error, response, body) =>
+				expect(response.statusCode).to.equal 200
 				new_file_id = body.new_file_id
 				expect(new_file_id).to.exist
 				expect(new_file_id).to.not.equal @existing_file_id

+ 3 - 0
services/web/test/acceptance/coffee/helpers/User.coffee

@@ -32,6 +32,9 @@ class User
 	get: (callback = (error, user)->) ->
 		db.users.findOne { _id: ObjectId(@_id) }, callback
 
+	mongoUpdate: (updateOp, callback=(error)->) ->
+		db.users.update {_id: ObjectId(@_id)}, updateOp, callback
+
 	register: (callback = (error, user) ->) ->
 		return callback(new Error('User already registered')) if @_id?
 		@getCsrfToken (error) =>