From 77918059493fa0182efc89b4e561ac15c93a1132 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 21 Mar 2016 17:03:31 +0000 Subject: [PATCH] Allow admin access to projects --- .../Authorization/AuthorizationManager.coffee | 7 +++- .../AuthorizationManagerTests.coffee | 33 +++++++++++++++++++ .../coffee/AuthorizationTests.coffee | 29 +++++++++++++++- .../acceptance/coffee/helpers/User.coffee | 5 ++- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/services/web/app/coffee/Features/Authorization/AuthorizationManager.coffee b/services/web/app/coffee/Features/Authorization/AuthorizationManager.coffee index eb6f564fea..ded0b6f979 100644 --- a/services/web/app/coffee/Features/Authorization/AuthorizationManager.coffee +++ b/services/web/app/coffee/Features/Authorization/AuthorizationManager.coffee @@ -33,7 +33,12 @@ module.exports = AuthorizationManager = # The user has direct access callback null, privilegeLevel, false else - getPublicAccessLevel() + AuthorizationManager.isUserSiteAdmin user_id, (error, isAdmin) -> + return callback(error) if error? + if isAdmin + callback null, PrivilegeLevels.OWNER, false + else + getPublicAccessLevel() canUserReadProject: (user_id, project_id, callback = (error, canRead) ->) -> AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, (error, privilegeLevel) -> diff --git a/services/web/test/UnitTests/coffee/Authorization/AuthorizationManagerTests.coffee b/services/web/test/UnitTests/coffee/Authorization/AuthorizationManagerTests.coffee index 1e3b6b0ebe..fcacce5164 100644 --- a/services/web/test/UnitTests/coffee/Authorization/AuthorizationManagerTests.coffee +++ b/services/web/test/UnitTests/coffee/Authorization/AuthorizationManagerTests.coffee @@ -20,6 +20,7 @@ describe "AuthorizationManager", -> describe "getPrivilegeLevelForProject", -> beforeEach -> @Project.findOne = sinon.stub() + @AuthorizationManager.isUserSiteAdmin = sinon.stub() @CollaboratorsHandler.getMemberIdPrivilegeLevel = sinon.stub() describe "with a private project", -> @@ -30,6 +31,7 @@ describe "AuthorizationManager", -> describe "with a user_id with a privilege level", -> beforeEach -> + @AuthorizationManager.isUserSiteAdmin.withArgs(@user_id).yields(null, false) @CollaboratorsHandler.getMemberIdPrivilegeLevel .withArgs(@user_id, @project_id) .yields(null, "readOnly") @@ -40,6 +42,7 @@ describe "AuthorizationManager", -> describe "with a user_id with no privilege level", -> beforeEach -> + @AuthorizationManager.isUserSiteAdmin.withArgs(@user_id).yields(null, false) @CollaboratorsHandler.getMemberIdPrivilegeLevel .withArgs(@user_id, @project_id) .yields(null, false) @@ -48,6 +51,17 @@ describe "AuthorizationManager", -> it "should return false", -> @callback.calledWith(null, false, false).should.equal true + describe "with a user_id who is an admin", -> + beforeEach -> + @AuthorizationManager.isUserSiteAdmin.withArgs(@user_id).yields(null, true) + @CollaboratorsHandler.getMemberIdPrivilegeLevel + .withArgs(@user_id, @project_id) + .yields(null, false) + @AuthorizationManager.getPrivilegeLevelForProject @user_id, @project_id, @callback + + it "should return the user as an owner", -> + @callback.calledWith(null, "owner", false).should.equal true + describe "with no user (anonymous)", -> beforeEach -> @AuthorizationManager.getPrivilegeLevelForProject null, @project_id, @callback @@ -55,6 +69,9 @@ describe "AuthorizationManager", -> it "should not call CollaboratorsHandler.getMemberIdPrivilegeLevel", -> @CollaboratorsHandler.getMemberIdPrivilegeLevel.called.should.equal false + it "should not call AuthorizationManager.isUserSiteAdmin", -> + @AuthorizationManager.isUserSiteAdmin.called.should.equal false + it "should return false", -> @callback.calledWith(null, false, false).should.equal true @@ -66,6 +83,7 @@ describe "AuthorizationManager", -> describe "with a user_id with a privilege level", -> beforeEach -> + @AuthorizationManager.isUserSiteAdmin.withArgs(@user_id).yields(null, false) @CollaboratorsHandler.getMemberIdPrivilegeLevel .withArgs(@user_id, @project_id) .yields(null, "readOnly") @@ -76,6 +94,7 @@ describe "AuthorizationManager", -> describe "with a user_id with no privilege level", -> beforeEach -> + @AuthorizationManager.isUserSiteAdmin.withArgs(@user_id).yields(null, false) @CollaboratorsHandler.getMemberIdPrivilegeLevel .withArgs(@user_id, @project_id) .yields(null, false) @@ -84,6 +103,17 @@ describe "AuthorizationManager", -> it "should return the public privilege level", -> @callback.calledWith(null, "readAndWrite", true).should.equal true + describe "with a user_id who is an admin", -> + beforeEach -> + @AuthorizationManager.isUserSiteAdmin.withArgs(@user_id).yields(null, true) + @CollaboratorsHandler.getMemberIdPrivilegeLevel + .withArgs(@user_id, @project_id) + .yields(null, false) + @AuthorizationManager.getPrivilegeLevelForProject @user_id, @project_id, @callback + + it "should return the user as an owner", -> + @callback.calledWith(null, "owner", false).should.equal true + describe "with no user (anonymous)", -> beforeEach -> @AuthorizationManager.getPrivilegeLevelForProject null, @project_id, @callback @@ -91,6 +121,9 @@ describe "AuthorizationManager", -> it "should not call CollaboratorsHandler.getMemberIdPrivilegeLevel", -> @CollaboratorsHandler.getMemberIdPrivilegeLevel.called.should.equal false + it "should not call AuthorizationManager.isUserSiteAdmin", -> + @AuthorizationManager.isUserSiteAdmin.called.should.equal false + it "should return the public privilege level", -> @callback.calledWith(null, "readAndWrite", true).should.equal true diff --git a/services/web/test/acceptance/coffee/AuthorizationTests.coffee b/services/web/test/acceptance/coffee/AuthorizationTests.coffee index 5d54151483..177750c28d 100644 --- a/services/web/test/acceptance/coffee/AuthorizationTests.coffee +++ b/services/web/test/acceptance/coffee/AuthorizationTests.coffee @@ -134,11 +134,16 @@ describe "Authorization", -> @other1 = new User() @other2 = new User() @anon = new User() - async.series [ + @site_admin = new User({email: "admin@example.com"}) + async.parallel [ (cb) => @owner.login cb (cb) => @other1.login cb (cb) => @other2.login cb (cb) => @anon.getCsrfToken cb + (cb) => + @site_admin.login (err) => + return cb(err) if error? + @site_admin.ensure_admin cb ], done describe "private project", -> @@ -151,6 +156,9 @@ describe "Authorization", -> it "should allow the owner read access to it", (done) -> expect_read_access @owner, @project_id, done + it "should allow the owner write access to its content", (done) -> + expect_content_write_access @owner, @project_id, done + it "should allow the owner write access to its settings", (done) -> expect_settings_write_access @owner, @project_id, done @@ -160,6 +168,9 @@ describe "Authorization", -> it "should not allow another user read access to the project", (done) -> expect_no_read_access @other1, @project_id, redirect_to: "/restricted", done + it "should not allow another user write access to its content", (done) -> + expect_no_content_write_access @other1, @project_id, done + it "should not allow another user write access to its settings", (done) -> expect_no_settings_write_access @other1, @project_id, redirect_to: "/restricted", done @@ -169,11 +180,27 @@ describe "Authorization", -> it "should not allow anonymous user read access to it", (done) -> expect_no_read_access @anon, @project_id, redirect_to: "/restricted", done + it "should not allow anonymous user write access to its content", (done) -> + expect_no_content_write_access @anon, @project_id, done + it "should not allow anonymous user write access to its settings", (done) -> expect_no_settings_write_access @anon, @project_id, redirect_to: "/restricted", done it "should not allow anonymous user admin access to it", (done) -> expect_no_admin_access @anon, @project_id, redirect_to: "/restricted", done + + it "should allow site admin users read access to it", (done) -> + expect_read_access @site_admin, @project_id, done + + it "should allow site admin users write access to its content", (done) -> + expect_content_write_access @site_admin, @project_id, done + + it "should allow site admin users write access to its settings", (done) -> + expect_settings_write_access @site_admin, @project_id, done + + it "should allow site admin users admin access to it", (done) -> + expect_admin_access @site_admin, @project_id, done + describe "shared project", -> before (done) -> diff --git a/services/web/test/acceptance/coffee/helpers/User.coffee b/services/web/test/acceptance/coffee/helpers/User.coffee index f1c38029d7..c13a45499d 100644 --- a/services/web/test/acceptance/coffee/helpers/User.coffee +++ b/services/web/test/acceptance/coffee/helpers/User.coffee @@ -1,6 +1,6 @@ request = require("./request") settings = require("settings-sharelatex") -{db} = require("../../../../app/js/infrastructure/mongojs") +{db, ObjectId} = require("../../../../app/js/infrastructure/mongojs") count = 0 @@ -29,6 +29,9 @@ class User @id = user?._id?.toString() callback() + ensure_admin: (callback = (error) ->) -> + db.users.update {_id: ObjectId(@id)}, { $set: { isAdmin: true }}, callback + createProject: (name, callback = (error, project_id) ->) -> @request.post { url: "/project/new",