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

Merge pull request #509 from sharelatex/ja-remove-holding-accounts

Add migration to remove holding accounts
Shane Kilkelly 9 лет назад
Родитель
Сommit
1f30aa535f
2 измененных файлов с 95 добавлено и 2 удалено
  1. 86 0
      migrations/5_remove_holding_accounts.coffee
  2. 9 2
      migrations/about_migrations.md

+ 86 - 0
migrations/5_remove_holding_accounts.coffee

@@ -0,0 +1,86 @@
+Settings = require "settings-sharelatex"
+mongojs = require("mongojs")
+ObjectId = mongojs.ObjectId
+db = mongojs(Settings.mongo.url, ['users', 'projects'])
+async = require "async"
+
+module.exports = HoldingAccountMigration = 
+	DRY_RUN: true
+
+	findHoldingAccounts: (callback = (error, users) ->) ->
+		db.users.find({holdingAccount: true, hashedPassword: { $exists: false }}, {holdingAccount: 1, email: 1}, callback)
+
+	deleteUserProjects: (user_id, callback = (error) ->) ->
+		# Holding accounts can't own projects, so only remove from 
+		# collaberator_refs and readOnly_refs
+		console.log "[Removing user from projects]", user_id
+		db.projects.find {
+			$or: [
+				{collaberator_refs: user_id},
+				{readOnly_refs: user_id}
+			]
+		}, { collaberator_refs: 1, readOnly_refs: 1 }, (error, projects = []) ->
+			return callback(error) if error?
+			jobs = projects.map (project) ->
+				(cb) ->
+					console.log "[Removing user from project]", user_id, JSON.stringify(project)
+					if !project?._id?
+						throw new Error("no project id")
+				
+					if !HoldingAccountMigration.DRY_RUN
+						db.projects.update {
+							_id: project._id
+						}, {
+							$pull: {
+								collaberator_refs: user_id,
+								readOnly_refs: user_id
+							}
+						}, (error, result) ->
+							return cb(error) if error?
+							console.log "[Removed user from project]", user_id, project._id, result
+							cb()
+					else
+						console.log "[Would have removed user from project]", user_id, project._id
+						cb()
+						
+			async.series jobs, callback
+
+	deleteUser: (user_id, callback = (error) ->) ->
+		if !user_id?
+			throw new Error("must have user_id")
+		if !HoldingAccountMigration.DRY_RUN
+			db.users.remove {_id: user_id, holdingAccount: true}, (error, result) ->
+				return callback(error) if error?
+				console.log "[Removed user]", user_id, result
+				if result.n != 1
+					return callback(new Error("failed to remove user as expected"))
+				callback()
+		else
+			console.log "[Would have removed user]", user_id
+			callback()
+
+	run: (done = () ->) ->
+		console.log "[Getting list of holding accounts]"
+		HoldingAccountMigration.findHoldingAccounts (error, users) ->
+			throw error if error?
+			console.log "[Got #{users.length} holding accounts]"
+			i = 0
+			jobs = users.map (u) ->
+				(cb) ->
+					console.log "[Removing user #{i++}/#{users.length}]"
+					HoldingAccountMigration.deleteUser u._id, (error) ->
+						return cb(error) if error?
+						HoldingAccountMigration.deleteUserProjects u._id, (error) ->
+							return cb(error) if error?
+							setTimeout cb, 50 # Small delay to not hammer DB
+			async.series jobs, (error) ->
+				throw error if error?
+				console.log "[FINISHED]"
+				done()
+
+	migrate: (client, done=()->) ->
+		HoldingAccountMigration.DRY_RUN = false
+		HoldingAccountMigration.run(done)
+				
+	rollback: (client, done) ->
+		done()

+ 9 - 2
migrations/about_migrations.md

@@ -1,2 +1,9 @@
-* if migration is stopped mid way it will start at the beginging next time
-* to see the run migrations do db.getCollection('_migrations').find() you can't do db._migrations.find()
+If migration is stopped mid way it will start at the beginging next time
+
+To see the run migrations do db.getCollection('_migrations').find() you can't do db._migrations.find()
+
+When testing, to roll back a migration run:
+
+```
+./node_modules/east/bin/east rollback 5 --adapter east-mongo --url mongodb://localhost:27017/sharelatex
+```