Hey Daniel,
Thanks for the replies! What I am trying to do is actually expose the servlet for any authenticated user. Right now I get
AbstractAccessDecisionManager.accessDenied
errors when attempting to access the plugin servlet. Even if I add code to my servlet or servlet filter, I get a feeling this error will still occur because the check happens before any code is executed (that is my hunch).
EDIT: Got it using the SecurityService class. Updated code below:
package com.atlassian.bitbucket.plugin.servlet;
import com.atlassian.soy.renderer.SoyTemplateRenderer;
import com.atlassian.bitbucket.project.Project;
import com.atlassian.bitbucket.project.ProjectService;
import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.bitbucket.permission.PermissionAdminService;
import com.atlassian.bitbucket.permission.SetPermissionRequest;
import com.atlassian.bitbucket.user.UserService;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.permission.PermittedUser;
import com.atlassian.bitbucket.permission.PermittedGroup;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageRequest;
import com.atlassian.bitbucket.util.PageRequestImpl;
import com.atlassian.bitbucket.user.SecurityService;
import com.atlassian.bitbucket.user.EscalatedSecurityContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Base64;
public class ProjectServlet extends AbstractExampleServlet {
private final ProjectService projectService;
private final PermissionAdminService permissionAdminService;
private final SecurityService securityService;
public ProjectServlet(SoyTemplateRenderer soyTemplateRenderer, ProjectService projectService, PermissionAdminService permissionAdminService, SecurityService securityService) {
super(soyTemplateRenderer);
this.projectService = projectService;
this.permissionAdminService = permissionAdminService;
this.securityService = securityService;
}
public class Admin {
public String name;
public String email;
public Admin(String _name, String _email) {
name = _name;
email = _email;
}
public String getName(){
return name;
}
public String getEmail(){
return email;
}
}
public class ExtendedProject {
public String key;
public String name;
public ArrayList<Admin> adminList;
public int listSize;
public ExtendedProject(String _key, String _name, ArrayList<Admin> _adminList){
key = _key;
name = _name;
adminList = _adminList;
listSize = adminList.size();
}
public String getKey(){
return key;
}
public String getName(){
return name;
}
public ArrayList<Admin> getAdminList(){
return adminList;
}
public int getListSize(){
return listSize;
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get projectKey from path
String pathInfo = req.getContextPath();
EscalatedSecurityContext esc = securityService.withPermission(Permission.ADMIN,"Accessing Admin List page."); //Create an Escalated Context
esc.applyToRequest(); //apply the context to this request for this authenticated user.
PageRequestImpl pageReq = new PageRequestImpl(0,5000);
PageRequestImpl adminPageReq = new PageRequestImpl(0,5000);
PageRequestImpl groupPageReq = new PageRequestImpl(0,5000);
String[] components = pathInfo.split("/");
Project[] projectList;
projectList = projectService.findAll(pageReq).getOrdinalIndexedValues().values().toArray(new Project[0]);
PermittedUser[] projectAdmins;
ArrayList<ExtendedProject> fullProjectList = new ArrayList<ExtendedProject>();
//PermittedGroup[] projectAdminGroups;
for(int i=0;i<projectList.length;i++){
Project project = projectList[i];
ArrayList<Admin> adminList = new ArrayList<Admin>();
projectAdmins = permissionAdminService.findUsersWithProjectPermission(project,"",adminPageReq).getOrdinalIndexedValues().values().toArray(new PermittedUser[0]);
for(int k=0;k<projectAdmins.length;k++){
if(projectAdmins[k].getPermission() == Permission.PROJECT_ADMIN){ //If the user is a project admin
if(projectAdmins[k].getUser().getDisplayName().indexOf("_") != 0) {//If the user is not a service account
String adminName=projectAdmins[k].getUser().getDisplayName();
String adminEmail=projectAdmins[k].getUser().getEmailAddress();
Admin newAdmin = new Admin(adminName,adminEmail);
adminList.add(newAdmin);
}
}
}
ExtendedProject eProject = new ExtendedProject(project.getKey(),project.getName(),adminList);
fullProjectList.add(eProject);
}
//projectAdminGroups = permissionAdminService.findGroupsWithProjectPermission(project,"",groupPageReq).getOrdinalIndexedValues().values().toArray(new PermittedGroup[0]);
boolean isSettings = false;
if (components.length == 3 && "settings".equalsIgnoreCase(components[2])) {
isSettings = true;
}
String template = isSettings ? "plugin.example.projectSettings" : "plugin.example.project";
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("fullProjectList",fullProjectList);
render(resp, template, data);
}
}
atlassian-plugin.xml:
<?xml version="1.0" encoding="UTF-8"?>
<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="3">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}"/>
<permissions>
<permission>execute_java</permission>
</permissions>
</plugin-info>
<!-- Servlets -->
<servlet-filter name="Project Servlet Filter" key="project-servlet-filter" class="com.atlassian.bitbucket.plugin.filter.ProjectServletFilter" location="before-dispatch">
<description>Adds Service account headers.</description>
<url-pattern>/plugins/servlet/administration-list/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</servlet-filter>
<servlet name="Project Servlet" key="project-servlet" class="com.atlassian.bitbucket.plugin.servlet.ProjectServlet">
<description key="project-servlet.description">Administration list</description>
<url-pattern>/administration-list/*</url-pattern>
</servlet>
<!-- Client web resources -->
<client-resource key="example-soy" name="Example Soy Templates">
<directory location="/templates/"/>
</client-resource>
<web-resource key="adminstyle" name="Admin Style">
<context>atl.general</context>
<resource type="download" name="admin-list-style.css" location="includes/admin-list-style.css"/>
</web-resource>
<web-resource key="pluginstyle" name="Plugin Style">
<context>atl.general</context>
<resource type="download" name="plugin-page-style.css" location="includes/plugin-page-style.css"/>
</web-resource>
<web-resource key="pluginscript" name="Plugin Script">
<context>atl.general</context>
<resource type="download" name="admin-list-script.js" location="includes/admin-list-script.js"/>
</web-resource>
<!-- Web items -->
<web-item key="project-plugin-tab" name="Project navigation tab" section="bitbucket.project.list.sidebar.items" weight="1">
<label>Need Access?</label>
<link>/plugins/servlet/administration-list/list</link>
<tooltip>Find Admins for the project you need access to.</tooltip>
<!-- optional style for the icon: see https://design.atlassian.com/2.0/product/foundations/iconography for a list of available images -->
<styleClass>admin-list-main</styleClass>
</web-item>
</atlassian-plugin>
I’m unsure of an easy way to verify the filter is in fact in front of the servlet.