Просмотр исходного кода

Merge pull request #745 from sharelatex/ta-institution-upgrade-script

Institution Upgrade Script
Timothée Alby 8 лет назад
Родитель
Сommit
46f956bbeb

+ 14 - 5
services/web/app/coffee/Features/User/UserAffiliationsManager.coffee → services/web/app/coffee/Features/Institutions/InstitutionsAPI.coffee

@@ -3,12 +3,20 @@ metrics = require("metrics-sharelatex")
 settings = require "settings-sharelatex"
 request = require "request"
 
-module.exports = UserAffiliationsManager =
-	getAffiliations: (userId, callback = (error, body) ->) ->
+module.exports = InstitutionsAPI =
+	getInstitutionAffiliations: (institutionId, callback = (error, body) ->) ->
+		makeAffiliationRequest {
+			method: 'GET'
+			path: "/api/v2/institutions/#{institutionId.toString()}/affiliations"
+			defaultErrorMessage: "Couldn't get institution affiliations"
+		}, callback
+
+
+	getUserAffiliations: (userId, callback = (error, body) ->) ->
 		makeAffiliationRequest {
 			method: 'GET'
 			path: "/api/v2/users/#{userId.toString()}/affiliations"
-			defaultErrorMessage: "Couldn't get affiliations"
+			defaultErrorMessage: "Couldn't get user affiliations"
 		}, callback
 
 
@@ -77,10 +85,11 @@ makeAffiliationRequest = (requestOptions, callback = (error) ->) ->
 		callback(null, body)
 
 [
-	'getAffiliations',
+	'getInstitutionAffiliations'
+	'getUserAffiliations',
 	'addAffiliation',
 	'removeAffiliation',
 ].map (method) ->
 	metrics.timeAsyncMethod(
-		UserAffiliationsManager, method, 'mongo.UserAffiliationsManager', logger
+		InstitutionsAPI, method, 'mongo.InstitutionsAPI', logger
 	)

+ 17 - 0
services/web/app/coffee/Features/Institutions/InstitutionsManager.coffee

@@ -0,0 +1,17 @@
+logger = require 'logger-sharelatex'
+async = require 'async'
+db = require("../../infrastructure/mongojs").db
+ObjectId = require("../../infrastructure/mongojs").ObjectId
+{ getInstitutionAffiliations } = require('./InstitutionsAPI')
+FeaturesUpdater = require('../Subscription/FeaturesUpdater')
+
+ASYNC_LIMIT = 10
+module.exports = InstitutionsManager =
+	upgradeInstitutionUsers: (institutionId, callback = (error) ->) ->
+		getInstitutionAffiliations institutionId, (error, affiliations) ->
+			return callback(error) if error
+			async.eachLimit affiliations, ASYNC_LIMIT, refreshFeatures, callback
+
+refreshFeatures = (affiliation, callback) ->
+	userId = ObjectId(affiliation.user_id)
+	FeaturesUpdater.refreshFeatures(userId, true, callback)

+ 1 - 1
services/web/app/coffee/Features/User/UserCreator.coffee

@@ -1,7 +1,7 @@
 User = require("../../models/User").User
 logger = require("logger-sharelatex")
 metrics = require('metrics-sharelatex')
-{ addAffiliation } = require("./UserAffiliationsManager")
+{ addAffiliation } = require("../Institutions/InstitutionsAPI")
 
 
 module.exports = UserCreator =

+ 1 - 1
services/web/app/coffee/Features/User/UserDeleter.coffee

@@ -4,7 +4,7 @@ ProjectDeleter = require("../Project/ProjectDeleter")
 logger = require("logger-sharelatex")
 SubscriptionHandler = require("../Subscription/SubscriptionHandler")
 async = require("async")
-{ deleteAffiliations } = require("./UserAffiliationsManager")
+{ deleteAffiliations } = require("../Institutions/InstitutionsAPI")
 
 module.exports =
 

+ 1 - 1
services/web/app/coffee/Features/User/UserEmailsController.coffee

@@ -3,7 +3,7 @@ UserGetter = require("./UserGetter")
 UserUpdater = require("./UserUpdater")
 EmailHelper = require("../Helpers/EmailHelper")
 UserEmailsConfirmationHandler = require "./UserEmailsConfirmationHandler"
-{ endorseAffiliation } = require("./UserAffiliationsManager")
+{ endorseAffiliation } = require("../Institutions/InstitutionsAPI")
 logger = require("logger-sharelatex")
 Errors = require "../Errors/Errors"
 

+ 2 - 2
services/web/app/coffee/Features/User/UserGetter.coffee

@@ -3,7 +3,7 @@ metrics = require('metrics-sharelatex')
 logger = require('logger-sharelatex')
 db = mongojs.db
 ObjectId = mongojs.ObjectId
-{ getAffiliations } = require("./UserAffiliationsManager")
+{ getUserAffiliations } = require("../Institutions/InstitutionsAPI")
 Errors = require("../Errors/Errors")
 
 module.exports = UserGetter =
@@ -32,7 +32,7 @@ module.exports = UserGetter =
 			return callback error if error?
 			return callback new Error('User not Found') unless user
 
-			getAffiliations userId, (error, affiliationsData) ->
+			getUserAffiliations userId, (error, affiliationsData) ->
 				return callback error if error?
 				callback null, decorateFullEmails(user.email, user.emails, affiliationsData)
 

+ 1 - 1
services/web/app/coffee/Features/User/UserUpdater.coffee

@@ -5,7 +5,7 @@ db = mongojs.db
 async = require("async")
 ObjectId = mongojs.ObjectId
 UserGetter = require("./UserGetter")
-{ addAffiliation, removeAffiliation } = require("./UserAffiliationsManager")
+{ addAffiliation, removeAffiliation } = require("../Institutions/InstitutionsAPI")
 FeaturesUpdater = require("../Subscription/FeaturesUpdater")
 EmailHelper = require "../Helpers/EmailHelper"
 Errors = require "../Errors/Errors"

+ 16 - 0
services/web/scripts/upgrade_institution_users.js

@@ -0,0 +1,16 @@
+const InstitutionsManager = require(
+  '../app/js/Features/Institutions/InstitutionsManager'
+)
+
+const institutionId = parseInt(process.argv[2])
+if (isNaN(institutionId)) throw new Error('No institution id')
+console.log('Upgrading users of institution', institutionId)
+
+InstitutionsManager.upgradeInstitutionUsers(institutionId, function (error) {
+  if (error) {
+    console.log(error)
+  } else {
+    console.log('DONE 👌')
+  }
+  process.exit()
+})

+ 29 - 13
services/web/test/unit/coffee/User/UserAffiliationsManagerTests.coffee → services/web/test/unit/coffee/Institutions/InstitutionsAPITests.coffee

@@ -4,16 +4,16 @@ SandboxedModule = require('sandboxed-module')
 assert = require('assert')
 path = require('path')
 sinon = require('sinon')
-modulePath = path.join __dirname, "../../../../app/js/Features/User/UserAffiliationsManager"
+modulePath = path.join __dirname, "../../../../app/js/Features/Institutions/InstitutionsAPI"
 expect = require("chai").expect
 
-describe "UserAffiliationsManager", ->
+describe "InstitutionsAPI", ->
 
 	beforeEach ->
 		@logger = err: sinon.stub(), log: ->
 		settings = apis: { v1: { url: 'v1.url', user: '', pass: '' } }
 		@request = sinon.stub()
-		@UserAffiliationsManager = SandboxedModule.require modulePath, requires:
+		@InstitutionsAPI = SandboxedModule.require modulePath, requires:
 			"logger-sharelatex": @logger
 			"metrics-sharelatex": timeAsyncMethod: sinon.stub()
 			'settings-sharelatex': settings
@@ -25,11 +25,27 @@ describe "UserAffiliationsManager", ->
 			email:"hello@world.com"
 		@newEmail = "bob@bob.com"
 
-	describe 'getAffiliations', ->
+	describe 'getInstitutionAffiliations', ->
+		it 'get affiliations', (done)->
+			@institutionId = 123
+			responseBody = ['123abc', '456def']
+			@request.yields(null, { statusCode: 200 }, responseBody)
+			@InstitutionsAPI.getInstitutionAffiliations @institutionId, (err, body) =>
+				should.not.exist(err)
+				@request.calledOnce.should.equal true
+				requestOptions = @request.lastCall.args[0]
+				expectedUrl = "v1.url/api/v2/institutions/#{@institutionId}/affiliations"
+				requestOptions.url.should.equal expectedUrl
+				requestOptions.method.should.equal 'GET'
+				should.not.exist(requestOptions.body)
+				body.should.equal responseBody
+				done()
+
+	describe 'getUserAffiliations', ->
 		it 'get affiliations', (done)->
 			responseBody = [{ foo: 'bar' }]
 			@request.callsArgWith(1, null, { statusCode: 201 }, responseBody)
-			@UserAffiliationsManager.getAffiliations @stubbedUser._id, (err, body) =>
+			@InstitutionsAPI.getUserAffiliations @stubbedUser._id, (err, body) =>
 				should.not.exist(err)
 				@request.calledOnce.should.equal true
 				requestOptions = @request.lastCall.args[0]
@@ -43,7 +59,7 @@ describe "UserAffiliationsManager", ->
 		it 'handle error', (done)->
 			body = errors: 'affiliation error message'
 			@request.callsArgWith(1, null, { statusCode: 503 }, body)
-			@UserAffiliationsManager.getAffiliations @stubbedUser._id, (err) =>
+			@InstitutionsAPI.getUserAffiliations @stubbedUser._id, (err) =>
 				should.exist(err)
 				err.message.should.have.string 503
 				err.message.should.have.string body.errors
@@ -58,7 +74,7 @@ describe "UserAffiliationsManager", ->
 				university: { id: 1 }
 				role: 'Prof'
 				department: 'Math'
-			@UserAffiliationsManager.addAffiliation @stubbedUser._id, @newEmail, affiliationOptions, (err)=>
+			@InstitutionsAPI.addAffiliation @stubbedUser._id, @newEmail, affiliationOptions, (err)=>
 				should.not.exist(err)
 				@request.calledOnce.should.equal true
 				requestOptions = @request.lastCall.args[0]
@@ -77,7 +93,7 @@ describe "UserAffiliationsManager", ->
 		it 'handle error', (done)->
 			body = errors: 'affiliation error message'
 			@request.callsArgWith(1, null, { statusCode: 422 }, body)
-			@UserAffiliationsManager.addAffiliation @stubbedUser._id, @newEmail, {}, (err)=>
+			@InstitutionsAPI.addAffiliation @stubbedUser._id, @newEmail, {}, (err)=>
 				should.exist(err)
 				err.message.should.have.string 422
 				err.message.should.have.string body.errors
@@ -88,7 +104,7 @@ describe "UserAffiliationsManager", ->
 			@request.callsArgWith(1, null, { statusCode: 404 })
 
 		it 'remove affiliation', (done)->
-			@UserAffiliationsManager.removeAffiliation @stubbedUser._id, @newEmail, (err)=>
+			@InstitutionsAPI.removeAffiliation @stubbedUser._id, @newEmail, (err)=>
 				should.not.exist(err)
 				@request.calledOnce.should.equal true
 				requestOptions = @request.lastCall.args[0]
@@ -100,7 +116,7 @@ describe "UserAffiliationsManager", ->
 
 		it 'handle error', (done)->
 			@request.callsArgWith(1, null, { statusCode: 500 })
-			@UserAffiliationsManager.removeAffiliation @stubbedUser._id, @newEmail, (err)=>
+			@InstitutionsAPI.removeAffiliation @stubbedUser._id, @newEmail, (err)=>
 				should.exist(err)
 				err.message.should.exist
 				done()
@@ -108,7 +124,7 @@ describe "UserAffiliationsManager", ->
 	describe 'deleteAffiliations', ->
 		it 'delete affiliations', (done)->
 			@request.callsArgWith(1, null, { statusCode: 200 })
-			@UserAffiliationsManager.deleteAffiliations @stubbedUser._id, (err) =>
+			@InstitutionsAPI.deleteAffiliations @stubbedUser._id, (err) =>
 				should.not.exist(err)
 				@request.calledOnce.should.equal true
 				requestOptions = @request.lastCall.args[0]
@@ -120,7 +136,7 @@ describe "UserAffiliationsManager", ->
 		it 'handle error', (done)->
 			body = errors: 'affiliation error message'
 			@request.callsArgWith(1, null, { statusCode: 518 }, body)
-			@UserAffiliationsManager.deleteAffiliations @stubbedUser._id, (err) =>
+			@InstitutionsAPI.deleteAffiliations @stubbedUser._id, (err) =>
 				should.exist(err)
 				err.message.should.have.string 518
 				err.message.should.have.string body.errors
@@ -131,7 +147,7 @@ describe "UserAffiliationsManager", ->
 			@request.callsArgWith(1, null, { statusCode: 204 })
 
 		it 'endorse affiliation', (done)->
-			@UserAffiliationsManager.endorseAffiliation @stubbedUser._id, @newEmail, 'Student','Physics', (err)=>
+			@InstitutionsAPI.endorseAffiliation @stubbedUser._id, @newEmail, 'Student','Physics', (err)=>
 				should.not.exist(err)
 				@request.calledOnce.should.equal true
 				requestOptions = @request.lastCall.args[0]

+ 30 - 0
services/web/test/unit/coffee/Institutions/InstitutionsManagerTests.coffee

@@ -0,0 +1,30 @@
+should = require('chai').should()
+SandboxedModule = require('sandboxed-module')
+path = require('path')
+sinon = require('sinon')
+modulePath = path.join __dirname, "../../../../app/js/Features/Institutions/InstitutionsManager"
+
+describe "InstitutionsManager", ->
+	beforeEach ->
+		@institutionId = 123
+		@logger = log: ->
+		@getInstitutionAffiliations = sinon.stub()
+		@refreshFeatures = sinon.stub().yields()
+		@InstitutionsManager = SandboxedModule.require modulePath, requires:
+			'logger-sharelatex': @logger
+			'./InstitutionsAPI':
+				getInstitutionAffiliations: @getInstitutionAffiliations
+			'../Subscription/FeaturesUpdater':
+				refreshFeatures: @refreshFeatures
+
+	describe 'upgradeInstitutionUsers', ->
+		it 'refresh all users Features', (done) ->
+			affiliations = [
+				{ user_id: '123abc123abc123abc123abc' }
+				{ user_id: '456def456def456def456def' }
+			]
+			@getInstitutionAffiliations.yields(null, affiliations)
+			@InstitutionsManager.upgradeInstitutionUsers @institutionId, (error) =>
+				should.not.exist(error)
+				sinon.assert.calledTwice(@refreshFeatures)
+				done()

+ 1 - 1
services/web/test/unit/coffee/User/UserCreatorTests.coffee

@@ -22,7 +22,7 @@ describe "UserCreator", ->
 			"../../models/User": User:@UserModel
 			"logger-sharelatex":{log:->}
 			'metrics-sharelatex': {timeAsyncMethod: ()->}
-			"./UserAffiliationsManager": addAffiliation: @addAffiliation
+			"../Institutions/InstitutionsAPI": addAffiliation: @addAffiliation
 
 		@email = "bob.oswald@gmail.com"
 

+ 1 - 1
services/web/test/unit/coffee/User/UserDeleterTests.coffee

@@ -31,7 +31,7 @@ describe "UserDeleter", ->
 			"../Newsletter/NewsletterManager":  @NewsletterManager
 			"../Subscription/SubscriptionHandler": @SubscriptionHandler
 			"../Project/ProjectDeleter": @ProjectDeleter
-			"./UserAffiliationsManager":
+			"../Institutions/InstitutionsAPI":
 				deleteAffiliations: @deleteAffiliations
 			"logger-sharelatex": @logger = { log: sinon.stub() }
 

+ 1 - 1
services/web/test/unit/coffee/User/UserEmailsControllerTests.coffee

@@ -34,7 +34,7 @@ describe "UserEmailsController", ->
 			"./UserUpdater": @UserUpdater
 			"../Helpers/EmailHelper": @EmailHelper
 			"./UserEmailsConfirmationHandler": @UserEmailsConfirmationHandler = {}
-			"./UserAffiliationsManager": endorseAffiliation: @endorseAffiliation
+			"../Institutions/InstitutionsAPI": endorseAffiliation: @endorseAffiliation
 			"../Errors/Errors": Errors
 			"logger-sharelatex":
 				log: -> console.log(arguments)

+ 4 - 4
services/web/test/unit/coffee/User/UserGetterTests.coffee

@@ -22,15 +22,15 @@ describe "UserGetter", ->
 			db: users: findOne: @findOne
 			ObjectId: (id) -> return id
 		settings = apis: { v1: { url: 'v1.url', user: '', pass: '' } }
-		@getAffiliations = sinon.stub().callsArgWith(1, null, [])
+		@getUserAffiliations = sinon.stub().callsArgWith(1, null, [])
 
 		@UserGetter = SandboxedModule.require modulePath, requires:
 			"logger-sharelatex": log:->
 			"../../infrastructure/mongojs": @Mongo
 			"metrics-sharelatex": timeAsyncMethod: sinon.stub()
 			'settings-sharelatex': settings
-			'./UserAffiliationsManager':
-				getAffiliations: @getAffiliations
+			'../Institutions/InstitutionsAPI':
+				getUserAffiliations: @getUserAffiliations
 			"../Errors/Errors": Errors
 
 	describe "getUser", ->
@@ -77,7 +77,7 @@ describe "UserGetter", ->
 					institution: { name: 'University Name', isUniversity: true }
 				}
 			]
-			@getAffiliations.callsArgWith(1, null, affiliationsData)
+			@getUserAffiliations.callsArgWith(1, null, affiliationsData)
 			@UserGetter.getUserFullEmails @fakeUser._id, (error, fullEmails) =>
 				assert.deepEqual fullEmails, [
 					{

+ 1 - 1
services/web/test/unit/coffee/User/UserUpdaterTests.coffee

@@ -25,7 +25,7 @@ describe "UserUpdater", ->
 		@UserUpdater = SandboxedModule.require modulePath, requires:
 			"logger-sharelatex": @logger
 			"./UserGetter": @UserGetter
-			'./UserAffiliationsManager':
+			'../Institutions/InstitutionsAPI':
 				addAffiliation: @addAffiliation
 				removeAffiliation: @removeAffiliation
 			'../Subscription/FeaturesUpdater': refreshFeatures: @refreshFeatures