Details
diff --git a/azkaban-common/src/main/java/azkaban/user/Permission.java b/azkaban-common/src/main/java/azkaban/user/Permission.java
index 834a2c1..9fa44b8 100644
--- a/azkaban-common/src/main/java/azkaban/user/Permission.java
+++ b/azkaban-common/src/main/java/azkaban/user/Permission.java
@@ -191,6 +191,9 @@ public class Permission {
SCHEDULE(0x0000008),
METRICS(0x0000010),
CREATEPROJECTS(0x40000000), // Only used for roles
+ // Users with this permission can upload projects when the property "lockdown.upload.projects"
+ // is turned on
+ UPLOADPROJECTS(0x0008000),
ADMIN(0x8000000);
private final int numVal;
diff --git a/azkaban-common/src/main/java/azkaban/user/UserUtils.java b/azkaban-common/src/main/java/azkaban/user/UserUtils.java
new file mode 100644
index 0000000..687bcda
--- /dev/null
+++ b/azkaban-common/src/main/java/azkaban/user/UserUtils.java
@@ -0,0 +1,24 @@
+package azkaban.user;
+
+public final class UserUtils {
+ private UserUtils() {
+
+ }
+
+ /**
+ * @return - Returns true if the given user is an ADMIN, or if user has the required permission
+ * for the action requested.
+ */
+ public static boolean hasPermissionforAction(final UserManager userManager, final User user,
+ final Permission.Type type) {
+ for (final String roleName : user.getRoles()) {
+ final Role role = userManager.getRole(roleName);
+ final Permission perm = role.getPermission();
+ if (perm.isPermissionSet(Permission.Type.ADMIN) || perm.isPermissionSet(type)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/azkaban-common/src/test/java/azkaban/user/PermissionTest.java b/azkaban-common/src/test/java/azkaban/user/PermissionTest.java
index 07497b3..0ee4cab 100644
--- a/azkaban-common/src/test/java/azkaban/user/PermissionTest.java
+++ b/azkaban-common/src/test/java/azkaban/user/PermissionTest.java
@@ -16,7 +16,7 @@
package azkaban.user;
-import static org.junit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
import azkaban.user.Permission.Type;
import org.junit.After;
@@ -47,7 +47,7 @@ public class PermissionTest {
final Permission perm2 = new Permission();
perm2.addPermission(Type.READ);
info("Compare " + perm1.toString() + " and " + perm2.toString());
- assertTrue(perm1.equals(perm2));
+ assertThat(perm1.equals(perm2)).isTrue();
}
@Test
@@ -58,7 +58,7 @@ public class PermissionTest {
final Permission perm2 = new Permission();
perm2.addPermission(new Type[]{Type.EXECUTE, Type.READ});
info("Compare " + perm1.toString() + " and " + perm2.toString());
- assertTrue(perm1.equals(perm2));
+ assertThat(perm1.equals(perm2)).isTrue();
}
@Test
@@ -70,7 +70,7 @@ public class PermissionTest {
final Permission perm2 = new Permission();
perm2.addPermission(new Type[]{Type.READ, Type.WRITE});
info("Compare " + perm1.toString() + " and " + perm2.toString());
- assertTrue(perm1.equals(perm2));
+ assertThat(perm1.equals(perm2)).isTrue();
}
@Test
@@ -82,7 +82,7 @@ public class PermissionTest {
final Permission perm2 = new Permission();
perm2.addPermission(new Type[]{Type.READ, Type.WRITE});
info("Compare " + perm1.toString() + " and " + perm2.toString());
- assertTrue(perm1.equals(perm2));
+ assertThat(perm1.equals(perm2)).isTrue();
}
@Test
@@ -94,7 +94,7 @@ public class PermissionTest {
final String[] array = permission.toStringArray();
final Permission permission2 = new Permission();
permission2.addPermissionsByName(array);
- assertTrue(permission.equals(permission2));
+ assertThat(permission.equals(permission2)).isTrue();
}
@Test
@@ -105,10 +105,32 @@ public class PermissionTest {
final int flags = permission.toFlags();
final Permission permission2 = new Permission(flags);
- assertTrue(permission2.isPermissionSet(Type.READ));
- assertTrue(permission2.isPermissionSet(Type.WRITE));
+ assertThat(permission2.isPermissionSet(Type.READ)).isTrue();
+ assertThat(permission2.isPermissionSet(Type.WRITE)).isTrue();
- assertTrue(permission.equals(permission2));
+ assertThat(permission.equals(permission2)).isTrue();
+ }
+
+ /**
+ * Verify that the binary bit for UPLOADPROJECTS is not turned on
+ * by setting the other permissions.
+ */
+ @Test
+ public void testUploadProjectFlag() throws Exception {
+ final Permission permission = new Permission();
+ permission.addPermission(new Type[]{Type.UPLOADPROJECTS});
+
+ final int flags = permission.toFlags();
+ final Permission permission2 = new Permission(flags);
+ assertThat(permission2.isPermissionSet(Type.UPLOADPROJECTS)).isTrue();
+ assertThat(permission.equals(permission2)).isTrue();
+
+ permission.removePermissions(new Type[]{Type.UPLOADPROJECTS});
+ final Type[] allPermissions = new Type[]{
+ Type.READ, Type.WRITE, Type.EXECUTE, Type.METRICS, Type.SCHEDULE, Type.CREATEPROJECTS
+ };
+ permission.addPermission(allPermissions);
+ assertThat(permission.isPermissionSet(Type.UPLOADPROJECTS)).isFalse();
}
/**
diff --git a/azkaban-common/src/test/java/azkaban/user/UserUtilsTest.java b/azkaban-common/src/test/java/azkaban/user/UserUtilsTest.java
new file mode 100644
index 0000000..c087a88
--- /dev/null
+++ b/azkaban-common/src/test/java/azkaban/user/UserUtilsTest.java
@@ -0,0 +1,31 @@
+package azkaban.user;
+
+import static azkaban.user.Permission.Type.UPLOADPROJECTS;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import azkaban.utils.TestUtils;
+import org.junit.Test;
+
+
+public class UserUtilsTest {
+ @Test
+ public void testAdminUserCanUploadProject() throws UserManagerException {
+ final UserManager userManager = TestUtils.createTestXmlUserManager();
+ final User testAdmin = userManager.getUser("testAdmin", "testAdmin");
+ assertThat(UserUtils.hasPermissionforAction(userManager, testAdmin, UPLOADPROJECTS)).isTrue();
+ }
+
+ @Test
+ public void testRegularUserCantUploadProject() {
+ final UserManager userManager = TestUtils.createTestXmlUserManager();
+ final User user = TestUtils.getTestUser();
+ assertThat(UserUtils.hasPermissionforAction(userManager, user, UPLOADPROJECTS)).isFalse();
+ }
+
+ @Test
+ public void testUserWithPermissionsCanUploadProject() throws UserManagerException {
+ final UserManager userManager = TestUtils.createTestXmlUserManager();
+ final User testUpload = userManager.getUser("testUpload", "testUpload");
+ assertThat(UserUtils.hasPermissionforAction(userManager, testUpload, UPLOADPROJECTS)).isTrue();
+ }
+}
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/PageUtils.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/PageUtils.java
new file mode 100644
index 0000000..f3a7f51
--- /dev/null
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/PageUtils.java
@@ -0,0 +1,30 @@
+package azkaban.webapp.servlet;
+
+import azkaban.server.session.Session;
+import azkaban.user.Permission;
+import azkaban.user.User;
+import azkaban.user.UserManager;
+import azkaban.user.UserUtils;
+
+
+public final class PageUtils {
+
+ private PageUtils() {
+
+ }
+
+ /**
+ * Method hides the upload button for regular users from relevant pages when the property
+ * "lockdown.upload.projects" is set. The button is displayed for admin users and users with
+ * upload permissions.
+ */
+ public static void hideUploadButtonWhenNeeded(final Page page, final Session session, final UserManager userManager,
+ final Boolean lockdownUploadProjects) {
+ final User user = session.getUser();
+
+ if (lockdownUploadProjects && !UserUtils.hasPermissionforAction(userManager, user,
+ Permission.Type.UPLOADPROJECTS)) {
+ page.add("hideUploadProject", true);
+ }
+ }
+}
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 9e7106f..4e05945 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -42,6 +42,7 @@ import azkaban.user.Permission.Type;
import azkaban.user.Role;
import azkaban.user.User;
import azkaban.user.UserManager;
+import azkaban.user.UserUtils;
import azkaban.utils.JSONUtils;
import azkaban.utils.Pair;
import azkaban.utils.Props;
@@ -1077,6 +1078,8 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
final String projectName = getParam(req, "project");
final User user = session.getUser();
+ PageUtils
+ .hideUploadButtonWhenNeeded(page, session, this.userManager, this.lockdownUploadProjects);
Project project = null;
try {
project = this.projectManager.getProject(projectName);
@@ -1234,7 +1237,8 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
"azkaban/webapp/servlet/velocity/permissionspage.vm");
final String projectName = getParam(req, "project");
final User user = session.getUser();
-
+ PageUtils
+ .hideUploadButtonWhenNeeded(page, session, this.userManager, this.lockdownUploadProjects);
Project project = null;
try {
project = this.projectManager.getProject(projectName);
@@ -1538,6 +1542,8 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
final String projectName = getParam(req, "project");
final User user = session.getUser();
+ PageUtils
+ .hideUploadButtonWhenNeeded(page, session, this.userManager, this.lockdownUploadProjects);
Project project = null;
try {
project = this.projectManager.getProject(projectName);
@@ -1606,7 +1612,8 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
String message = null;
HashMap<String, Object> params = null;
- if (this.lockdownCreateProjects && !hasPermissionToCreateProject(user)) {
+ if (this.lockdownCreateProjects &&
+ !UserUtils.hasPermissionforAction(this.userManager, user, Type.CREATEPROJECTS)) {
message =
"User " + user.getUserId()
+ " doesn't have permission to create projects.";
@@ -1655,8 +1662,13 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
props.put(ValidatorConfigs.CUSTOM_AUTO_FIX_FLAG_PARAM, "true");
}
- if (this.lockdownUploadProjects) {
- registerError(ret, "Project uploading is locked out", resp, 400);
+ if (this.lockdownUploadProjects && !UserUtils
+ .hasPermissionforAction(this.userManager, user, Type.UPLOADPROJECTS)) {
+ final String message =
+ "Project uploading is locked out. Only admin users and users with special permissions can upload projects. "
+ + "User " + user.getUserId() + " doesn't have permission to upload project.";
+ logger.info(message);
+ registerError(ret, message, resp, 403);
} else if (projectName == null || projectName.isEmpty()) {
registerError(ret, "No project name found.", resp, 400);
} else if (project == null) {
@@ -1796,19 +1808,6 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
return perm;
}
- private boolean hasPermissionToCreateProject(final User user) {
- for (final String roleName : user.getRoles()) {
- final Role role = this.userManager.getRole(roleName);
- final Permission perm = role.getPermission();
- if (perm.isPermissionSet(Permission.Type.ADMIN)
- || perm.isPermissionSet(Permission.Type.CREATEPROJECTS)) {
- return true;
- }
- }
-
- return false;
- }
-
private void handleReloadProjectWhitelist(final HttpServletRequest req,
final HttpServletResponse resp, final Session session) throws IOException {
final HashMap<String, Object> ret = new HashMap<>();
diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectServlet.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectServlet.java
index 5e01bb3..76cb901 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectServlet.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectServlet.java
@@ -20,9 +20,9 @@ import azkaban.project.Project;
import azkaban.project.ProjectManager;
import azkaban.server.session.Session;
import azkaban.user.Permission;
-import azkaban.user.Role;
import azkaban.user.User;
import azkaban.user.UserManager;
+import azkaban.user.UserUtils;
import azkaban.utils.Pair;
import azkaban.webapp.AzkabanWebServer;
import java.io.IOException;
@@ -160,7 +160,8 @@ public class ProjectServlet extends LoginAbstractAzkabanServlet {
final Page page =
newPage(req, resp, session, "azkaban/webapp/servlet/velocity/index.vm");
- if (this.lockdownCreateProjects && !hasPermissionToCreateProject(user)) {
+ if (this.lockdownCreateProjects &&
+ !UserUtils.hasPermissionforAction(this.userManager, user, Permission.Type.CREATEPROJECTS)) {
page.add("hideCreateProject", true);
}
@@ -220,19 +221,6 @@ public class ProjectServlet extends LoginAbstractAzkabanServlet {
// TODO Auto-generated method stub
}
- private boolean hasPermissionToCreateProject(final User user) {
- for (final String roleName : user.getRoles()) {
- final Role role = this.userManager.getRole(roleName);
- final Permission perm = role.getPermission();
- if (perm.isPermissionSet(Permission.Type.ADMIN)
- || perm.isPermissionSet(Permission.Type.CREATEPROJECTS)) {
- return true;
- }
- }
-
- return false;
- }
-
/**
* This class is used to represent a simplified project, which can be returned
* to end users via REST API. This is done in consideration that the API
diff --git a/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/projectpageheader.vm b/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/projectpageheader.vm
index ba9bf38..fe2636d 100644
--- a/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/projectpageheader.vm
+++ b/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/projectpageheader.vm
@@ -25,9 +25,11 @@
<button id="project-delete-btn" class="btn btn-sm btn-danger">
<span class="glyphicon glyphicon-trash"></span> Delete Project
</button>
+#if (!$hideUploadProject)
<button id="project-upload-btn" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-upload"></span> Upload
</button>
+#end
<a class="btn btn-sm btn-info" href="${context}/manager?project=${project.name}&download=true">
<span class="glyphicon glyphicon-download"></span> Download
</a>
diff --git a/azkaban-web-server/src/test/java/azkaban/fixture/VelocityTemplateTestUtil.java b/azkaban-web-server/src/test/java/azkaban/fixture/VelocityTemplateTestUtil.java
index 3a95cf5..afd8465 100644
--- a/azkaban-web-server/src/test/java/azkaban/fixture/VelocityTemplateTestUtil.java
+++ b/azkaban-web-server/src/test/java/azkaban/fixture/VelocityTemplateTestUtil.java
@@ -6,7 +6,7 @@ import org.apache.velocity.app.VelocityEngine;
/**
- * Test utility to render a template.
+ * Test utility to render a template and other helper methods.
*/
public class VelocityTemplateTestUtil {
@@ -27,4 +27,17 @@ public class VelocityTemplateTestUtil {
engine.mergeTemplate(TEMPLATE_BASE_DIR + templateName + ".vm", "UTF-8", context, stringWriter);
return stringWriter.getBuffer().toString();
}
+
+ /**
+ *
+ * @param source the rendered template as a String
+ * @param target the String fragment within the template
+ * @return - boolean
+ */
+ public static boolean ignoreCaseContains(final String source, final String target) {
+ final String sourceNoSpace = source.replaceAll("\\s+", "");
+ final String targetNoSpace = target.replaceAll("\\s+", "");
+ return sourceNoSpace.contains(targetNoSpace);
+ }
+
}
diff --git a/azkaban-web-server/src/test/java/azkaban/webapp/servlet/ExecutionFlowViewTest.java b/azkaban-web-server/src/test/java/azkaban/webapp/servlet/ExecutionFlowViewTest.java
index 7717717..2771c33 100644
--- a/azkaban-web-server/src/test/java/azkaban/webapp/servlet/ExecutionFlowViewTest.java
+++ b/azkaban-web-server/src/test/java/azkaban/webapp/servlet/ExecutionFlowViewTest.java
@@ -17,12 +17,6 @@ public class ExecutionFlowViewTest {
+ "class=\"btn btn-info btn-sm\" type=\"button\" target=\"_blank\" "
+ "title=\"Analyze job in Dr. Elephant\">Dr. Elephant</a></li>";
- private static boolean ignoreCaseContains(final String source, final String target) {
- final String sourceNoSpace = source.replaceAll("\\s+", "");
- final String targetNoSpace = target.replaceAll("\\s+", "");
- return sourceNoSpace.contains(targetNoSpace);
- }
-
/**
* Test aims to check that the external analyzer button is displayed
* in the page.
@@ -42,6 +36,7 @@ public class ExecutionFlowViewTest {
final String result =
VelocityTemplateTestUtil.renderTemplate("executingflowpage", context);
- assertTrue(ignoreCaseContains(result, EXTERNAL_ANALYZER_ELEMENT));
+ assertTrue(VelocityTemplateTestUtil.
+ ignoreCaseContains(result, EXTERNAL_ANALYZER_ELEMENT));
}
}
diff --git a/azkaban-web-server/src/test/java/azkaban/webapp/servlet/PageUtilsTest.java b/azkaban-web-server/src/test/java/azkaban/webapp/servlet/PageUtilsTest.java
new file mode 100644
index 0000000..94c1f5b
--- /dev/null
+++ b/azkaban-web-server/src/test/java/azkaban/webapp/servlet/PageUtilsTest.java
@@ -0,0 +1,88 @@
+package azkaban.webapp.servlet;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+import azkaban.server.session.Session;
+import azkaban.user.User;
+import azkaban.user.UserManager;
+import azkaban.user.UserManagerException;
+import azkaban.utils.TestUtils;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+
+public class PageUtilsTest {
+ @Test
+ public void testUploadButtonisHiddenWhenGlobalPropertyIsSet()
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException,
+ ClassNotFoundException, InstantiationException, IOException {
+ final HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
+ final HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
+ final User user = TestUtils.getTestUser();
+ final Session session = new Session("fake-session-id", user, "127.0.0.1");
+
+ final VelocityEngine velocityEngine = new VelocityEngine();
+ velocityEngine.init("src/test/resources/velocity.properties");
+ final Page page = new Page(httpServletRequest, httpServletResponse, velocityEngine,
+ "azkaban/webapp/servlet/velocity/permissionspage.vm");
+
+ final UserManager userManager = TestUtils.createTestXmlUserManager();
+ PageUtils.hideUploadButtonWhenNeeded(page, session, userManager, true);
+
+ final Field velocityContextField = Page.class.getDeclaredField("context");
+ velocityContextField.setAccessible(true);
+ final VelocityContext velocityContext = (VelocityContext) velocityContextField.get(page);
+ assertThat((boolean) velocityContext.get("hideUploadProject")).isTrue();
+ }
+
+ @Test
+ public void testUploadButtonIsVisibleToAllWhenGlobalPropertyIsNotSet()
+ throws NoSuchFieldException, IllegalAccessException {
+ final HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
+ final HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
+ final User user = TestUtils.getTestUser();
+ final Session session = new Session("fake-session-id", user, "127.0.0.1");
+
+ final VelocityEngine velocityEngine = new VelocityEngine();
+ velocityEngine.init("src/test/resources/velocity.properties");
+ final Page page = new Page(httpServletRequest, httpServletResponse, velocityEngine,
+ "azkaban/webapp/servlet/velocity/permissionspage.vm");
+
+ final UserManager userManager = TestUtils.createTestXmlUserManager();
+ PageUtils.hideUploadButtonWhenNeeded(page, session, userManager, false);
+
+ final Field velocityContextField = Page.class.getDeclaredField("context");
+ velocityContextField.setAccessible(true);
+ final VelocityContext velocityContext = (VelocityContext) velocityContextField.get(page);
+ assertThat(velocityContext.containsKey("hideUploadProject")).isFalse();
+ }
+
+ @Test
+ public void testUploadButtonIsEnabledForAdminUser()
+ throws NoSuchFieldException, IllegalAccessException, UserManagerException {
+ final HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
+ final HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
+ final UserManager userManager = TestUtils.createTestXmlUserManager();
+ final User testAdmin = userManager.getUser("testAdmin", "testAdmin");
+ final Session session = new Session("fake-session-id", testAdmin, "127.0.0.1");
+
+ final VelocityEngine velocityEngine = new VelocityEngine();
+ velocityEngine.init("src/test/resources/velocity.properties");
+ final Page page = new Page(httpServletRequest, httpServletResponse, velocityEngine,
+ "azkaban/webapp/servlet/velocity/permissionspage.vm");
+
+ PageUtils.hideUploadButtonWhenNeeded(page, session, userManager, false);
+
+ final Field velocityContextField = Page.class.getDeclaredField("context");
+ velocityContextField.setAccessible(true);
+ final VelocityContext velocityContext = (VelocityContext) velocityContextField.get(page);
+ assertThat(velocityContext.get("hideUploadProject")).isNull();
+ }
+}
diff --git a/azkaban-web-server/src/test/java/azkaban/webapp/servlet/ProjectPageHeaderTest.java b/azkaban-web-server/src/test/java/azkaban/webapp/servlet/ProjectPageHeaderTest.java
new file mode 100644
index 0000000..e4e8cbf
--- /dev/null
+++ b/azkaban-web-server/src/test/java/azkaban/webapp/servlet/ProjectPageHeaderTest.java
@@ -0,0 +1,37 @@
+package azkaban.webapp.servlet;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import azkaban.fixture.VelocityContextTestUtil;
+import azkaban.fixture.VelocityTemplateTestUtil;
+import org.apache.velocity.VelocityContext;
+import org.junit.Test;
+
+/**
+ * Test validates the enable/disable feature of the 'Upload' button
+ */
+public class ProjectPageHeaderTest {
+ private static final String UPLOAD_BUTTON
+ = "<button id=\"project-upload-btn\" class=\"btn btn-sm btn-primary\">"
+ + "<span class=\"glyphicon glyphicon-upload\"></span> Upload </button>";
+
+ @Test
+ public void testUploadButtonIsPresent() {
+ final VelocityContext context = VelocityContextTestUtil.getInstance();
+ context.put("hideUploadProject", false);
+
+ final String result =
+ VelocityTemplateTestUtil.renderTemplate("projectpageheader", context);
+ assertThat(VelocityTemplateTestUtil.ignoreCaseContains(result, UPLOAD_BUTTON)).isTrue();
+ }
+
+ @Test
+ public void testUploadButtonIsNotPresent() {
+ final VelocityContext context = VelocityContextTestUtil.getInstance();
+ context.put("hideUploadProject", true);
+
+ final String result =
+ VelocityTemplateTestUtil.renderTemplate("projectpageheader", context);
+ assertThat(VelocityTemplateTestUtil.ignoreCaseContains(result, UPLOAD_BUTTON)).isFalse();
+ }
+}
diff --git a/test/src/test/resources/azkaban/test/azkaban-users.xml b/test/src/test/resources/azkaban/test/azkaban-users.xml
index 75f2d0f..0aa6e34 100644
--- a/test/src/test/resources/azkaban/test/azkaban-users.xml
+++ b/test/src/test/resources/azkaban/test/azkaban-users.xml
@@ -1,5 +1,7 @@
<azkaban-users>
<user groups="azkaban" password="testAdmin" roles="admin" username="testAdmin"/>
+ <user password="testUpload" roles="upload" username="testUpload"/>
<user password="testUser" username="testUser"/>
<role name="admin" permissions="ADMIN"/>
+ <role name="upload" permissions="UPLOADPROJECTS"/>
</azkaban-users>