return;\r
} else {\r
// check user access for request\r
- if (user.canAdmin || canAccess(model, user, urlRequestType)) {\r
+ if (user.canAdmin() || canAccess(model, user, urlRequestType)) {\r
// authenticated request permitted.\r
// pass processing to the restricted servlet.\r
newSession(authenticatedRequest, httpResponse);\r
@Override\r
public boolean isUserInRole(String role) {\r
if (role.equals(Constants.ADMIN_ROLE)) {\r
- return user.canAdmin;\r
+ return user.canAdmin();\r
}\r
// Gitblit does not currently use actual roles in the traditional\r
// servlet container sense. That is the reason this is marked\r
\r
// write teams\r
for (TeamModel model : teams.values()) {\r
+ // team roles\r
+ List<String> roles = new ArrayList<String>();\r
+ if (model.canAdmin) {\r
+ roles.add(Constants.ADMIN_ROLE);\r
+ }\r
+ if (model.canFork) {\r
+ roles.add(Constants.FORK_ROLE);\r
+ }\r
+ if (model.canCreate) {\r
+ roles.add(Constants.CREATE_ROLE);\r
+ }\r
+ if (roles.size() == 0) {\r
+ // we do this to ensure that team record is written.\r
+ // Otherwise, StoredConfig might optimizes that record away.\r
+ roles.add(Constants.NO_ROLE);\r
+ }\r
+ config.setStringList(TEAM, model.name, ROLE, roles);\r
+ \r
if (model.permissions == null) {\r
// null check on "final" repositories because JSON-sourced TeamModel\r
// can have a null repositories object\r
Set<String> teamnames = config.getSubsections(TEAM);\r
for (String teamname : teamnames) {\r
TeamModel team = new TeamModel(teamname);\r
+ Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList(\r
+ TEAM, teamname, ROLE)));\r
+ team.canAdmin = roles.contains(Constants.ADMIN_ROLE);\r
+ team.canFork = roles.contains(Constants.FORK_ROLE);\r
+ team.canCreate = roles.contains(Constants.CREATE_ROLE);\r
+ \r
team.addRepositoryPermissions(Arrays.asList(config.getStringList(TEAM, teamname,\r
REPOSITORY)));\r
team.addUsers(Arrays.asList(config.getStringList(TEAM, teamname, USER)));\r
} else if (role.charAt(0) == '%') {\r
postReceive.add(role.substring(1));\r
} else {\r
+ switch (role.charAt(0)) {\r
+ case '#':\r
+ // Permissions\r
+ if (role.equalsIgnoreCase(Constants.ADMIN_ROLE)) {\r
+ team.canAdmin = true;\r
+ } else if (role.equalsIgnoreCase(Constants.FORK_ROLE)) {\r
+ team.canFork = true;\r
+ } else if (role.equalsIgnoreCase(Constants.CREATE_ROLE)) {\r
+ team.canCreate = true;\r
+ }\r
+ break;\r
+ default:\r
+ repositories.add(role);\r
+ }\r
repositories.add(role);\r
}\r
}\r
}\r
}\r
\r
+ // Permissions\r
+ if (model.canAdmin) {\r
+ roles.add(Constants.ADMIN_ROLE);\r
+ }\r
+ if (model.canFork) {\r
+ roles.add(Constants.FORK_ROLE);\r
+ }\r
+ if (model.canCreate) {\r
+ roles.add(Constants.CREATE_ROLE);\r
+ }\r
+\r
for (String role : roles) {\r
sb.append(role);\r
sb.append(',');\r
return;\r
} else {\r
// check user access for request\r
- if (user.canAdmin || canAccess(user, requestType)) {\r
+ if (user.canAdmin() || canAccess(user, requestType)) {\r
// authenticated request permitted.\r
// pass processing to the restricted servlet.\r
newSession(authenticatedRequest, httpResponse);\r
case LIST_REPOSITORIES:\r
return true;\r
default:\r
- return user.canAdmin;\r
+ return user.canAdmin();\r
}\r
}\r
}
\ No newline at end of file
\r
UserModel user = (UserModel) request.getUserPrincipal();\r
\r
- boolean allowManagement = user != null && user.canAdmin\r
+ boolean allowManagement = user != null && user.canAdmin()\r
&& GitBlit.getBoolean(Keys.web.enableRpcManagement, false);\r
\r
- boolean allowAdmin = user != null && user.canAdmin\r
+ boolean allowAdmin = user != null && user.canAdmin()\r
&& GitBlit.getBoolean(Keys.web.enableRpcAdministration, false);\r
\r
Object result = null;\r
case Display_Name:\r
return model.displayName;\r
case AccessLevel:\r
- if (model.canAdmin) {\r
+ if (model.canAdmin()) {\r
return "administrator";\r
}\r
return "";\r
\r
// field names are reflectively mapped in EditTeam page\r
public String name;\r
+ public boolean canAdmin;\r
+ public boolean canFork;\r
+ public boolean canCreate;\r
public final Set<String> users = new HashSet<String>();\r
// retained for backwards-compatibility with RPC clients\r
@Deprecated\r
import com.gitblit.Constants.AccessRestrictionType;\r
import com.gitblit.Constants.AuthorizationControl;\r
import com.gitblit.Constants.Unused;\r
+import com.gitblit.utils.ArrayUtils;\r
import com.gitblit.utils.StringUtils;\r
\r
/**\r
*/\r
@Deprecated\r
public boolean canAccessRepository(String repositoryName) {\r
- return canAdmin || repositories.contains(repositoryName.toLowerCase())\r
+ return canAdmin() || repositories.contains(repositoryName.toLowerCase())\r
|| hasTeamAccess(repositoryName);\r
}\r
\r
boolean isOwner = !StringUtils.isEmpty(repository.owner)\r
&& repository.owner.equals(username);\r
boolean allowAuthenticated = isAuthenticated && AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl);\r
- return canAdmin || isOwner || repositories.contains(repository.name.toLowerCase())\r
+ return canAdmin() || isOwner || repositories.contains(repository.name.toLowerCase())\r
|| hasTeamAccess(repository.name) || allowAuthenticated;\r
}\r
\r
}\r
\r
public AccessPermission getRepositoryPermission(RepositoryModel repository) {\r
- if (canAdmin || repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {\r
+ if (canAdmin() || repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {\r
return AccessPermission.REWIND;\r
}\r
if (AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl) && isAuthenticated) {\r
// can not fork your own repository\r
return false;\r
}\r
- if (canAdmin || repository.isOwner(username)) {\r
+ if (canAdmin() || repository.isOwner(username)) {\r
return true;\r
}\r
if (!repository.allowForks) {\r
return false;\r
}\r
- if (!isAuthenticated || !canFork) {\r
+ if (!isAuthenticated || !canFork()) {\r
return false;\r
}\r
return canClone(repository);\r
}\r
\r
public boolean canDelete(RepositoryModel model) {\r
- return canAdmin || model.isUsersPersonalRepository(username);\r
+ return canAdmin() || model.isUsersPersonalRepository(username);\r
}\r
\r
public boolean canEdit(RepositoryModel model) {\r
- return canAdmin || model.isUsersPersonalRepository(username) || model.isOwner(username);\r
+ return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username);\r
+ }\r
+ \r
+ /**\r
+ * This returns true if the user has fork privileges or the user has fork\r
+ * privileges because of a team membership.\r
+ * \r
+ * @return true if the user can fork\r
+ */\r
+ public boolean canFork() {\r
+ if (canFork) {\r
+ return true;\r
+ }\r
+ if (!ArrayUtils.isEmpty(teams)) {\r
+ for (TeamModel team : teams) {\r
+ if (team.canFork) {\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * This returns true if the user has admin privileges or the user has admin\r
+ * privileges because of a team membership.\r
+ * \r
+ * @return true if the user can admin\r
+ */\r
+ public boolean canAdmin() {\r
+ if (canAdmin) {\r
+ return true;\r
+ }\r
+ if (!ArrayUtils.isEmpty(teams)) {\r
+ for (TeamModel team : teams) {\r
+ if (team.canAdmin) {\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * This returns true if the user has create privileges or the user has create\r
+ * privileges because of a team membership.\r
+ * \r
+ * @return true if the user can admin\r
+ */\r
+ public boolean canCreate() {\r
+ if (canCreate) {\r
+ return true;\r
+ }\r
+ if (!ArrayUtils.isEmpty(teams)) {\r
+ for (TeamModel team : teams) {\r
+ if (team.canCreate) {\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
}\r
\r
public boolean isTeamMember(String teamname) {\r
if (authenticateAdmin) {\r
// authenticate admin\r
if (user != null) {\r
- return user.canAdmin;\r
+ return user.canAdmin();\r
}\r
return false;\r
} else {\r
gb.allowForksDescription = allow authorized users to fork this repository\r
gb.forkedFrom = forked from\r
gb.canFork = can fork\r
-gb.canForkDescription = user is permitted to fork authorized repositories\r
+gb.canForkDescription = can fork authorized repositories to a personal repository\r
gb.myFork = view my fork\r
gb.forksProhibited = forks prohibited\r
gb.forksProhibitedWarning = this repository forbids forks\r
if (user == null) {\r
return false;\r
}\r
- return user.canAdmin;\r
+ return user.canAdmin();\r
}\r
\r
public String getUsername() {\r
\r
GitBlitWebSession session = GitBlitWebSession.get();\r
UserModel user = session.getUser();\r
- if (user != null && user.canCreate && !user.canAdmin) {\r
+ if (user != null && user.canCreate() && !user.canAdmin()) {\r
// personal create permissions, inject personal repository path\r
model.name = user.getPersonalPath() + "/";\r
model.projectPath = user.getPersonalPath();\r
final UserModel user = session.getUser() == null ? UserModel.ANONYMOUS : session.getUser();\r
\r
if (isCreate) {\r
- if (user.canAdmin) {\r
+ if (user.canAdmin()) {\r
super.setupPage(getString("gb.newRepository"), "");\r
} else {\r
super.setupPage(getString("gb.newRepository"), user.getDisplayName());\r
return;\r
}\r
\r
- if (user.canCreate && !user.canAdmin) {\r
+ if (user.canCreate() && !user.canAdmin()) {\r
// ensure repository name begins with the user's path\r
if (!repositoryModel.name.startsWith(user.getPersonalPath())) {\r
error(MessageFormat.format(getString("gb.illegalPersonalRepositoryLocation"),\r
}\r
if (isCreate) {\r
// Create Repository\r
- if (!user.canCreate && !user.canAdmin) {\r
+ if (!user.canCreate() && !user.canAdmin()) {\r
// Only administrators or permitted users may create\r
error(getString("gb.errorOnlyAdminMayCreateRepository"), true);\r
}\r
} else {\r
// Edit Repository\r
- if (user.canAdmin) {\r
+ if (user.canAdmin()) {\r
// Admins can edit everything\r
isAdmin = true;\r
return;\r
<tbody class="settings">\r
<tr><td colspan="2"><h3><wicket:message key="gb.general"></wicket:message> <small><wicket:message key="gb.generalDescription"></wicket:message></small></h3></td></tr>\r
<tr><th><wicket:message key="gb.teamName"></wicket:message></th><td class="edit"><input type="text" wicket:id="name" id="name" size="30" tabindex="1" /></td></tr>\r
- <tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="mailingLists" size="40" tabindex="2" /></td></tr>\r
+ <tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canAdmin" tabindex="2" /> <span class="help-inline"><wicket:message key="gb.canAdminDescription"></wicket:message></span></label></td></tr> \r
+ <tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="3" /> <span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr> \r
+ <tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="4" /> <span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr> \r
+ <tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="mailingLists" size="40" tabindex="5" /></td></tr>\r
<tr><td colspan="2" style="padding-top:15px;"><h3><wicket:message key="gb.accessPermissions"></wicket:message> <small><wicket:message key="gb.accessPermissionsForTeamDescription"></wicket:message></small></h3></td></tr> \r
<tr><th style="vertical-align: top;"><wicket:message key="gb.teamMembers"></wicket:message></th><td style="padding:2px;"><span wicket:id="users"></span></td></tr>\r
<tr><td colspan="2"><hr></hr></td></tr>\r
<tr><td colspan="2" style="padding-top:10px;"><h3><wicket:message key="gb.hookScripts"></wicket:message> <small><wicket:message key="gb.hookScriptsDescription"></wicket:message></small></h3></td></tr> \r
<tr><th style="vertical-align: top;"><wicket:message key="gb.preReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPreReceive"></span></th><td style="padding:2px;"><span wicket:id="preReceiveScripts"></span></td></tr>\r
<tr><th style="vertical-align: top;"><wicket:message key="gb.postReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPostReceive"></span></th><td style="padding:2px;"><span wicket:id="postReceiveScripts"></span></td></tr>\r
- <tr><td colspan='2'><div class="form-actions"><input class="btn btn-primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="3" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="4" /></div></td></tr>\r
+ <tr><td colspan='2'><div class="form-actions"><input class="btn btn-primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="6" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="7" /></div></td></tr>\r
</tbody>\r
</table>\r
</form> \r
import org.apache.wicket.behavior.SimpleAttributeModifier;\r
import org.apache.wicket.extensions.markup.html.form.palette.Palette;\r
import org.apache.wicket.markup.html.form.Button;\r
+import org.apache.wicket.markup.html.form.CheckBox;\r
import org.apache.wicket.markup.html.form.Form;\r
import org.apache.wicket.markup.html.form.TextField;\r
import org.apache.wicket.model.CompoundPropertyModel;\r
\r
// field names reflective match TeamModel fields\r
form.add(new TextField<String>("name"));\r
+ form.add(new CheckBox("canAdmin"));\r
+ form.add(new CheckBox("canFork"));\r
+ form.add(new CheckBox("canCreate"));\r
form.add(users.setEnabled(editMemberships));\r
mailingLists = new Model<String>(teamModel.mailingLists == null ? ""\r
: StringUtils.flattenStrings(teamModel.mailingLists, " "));\r
<tr><th><wicket:message key="gb.displayName"></wicket:message></th><td class="edit"><input type="text" wicket:id="displayName" size="30" tabindex="4" /></td></tr>\r
<tr><th><wicket:message key="gb.emailAddress"></wicket:message></th><td class="edit"><input type="text" wicket:id="emailAddress" size="30" tabindex="5" /></td></tr>\r
<tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canAdmin" tabindex="6" /> <span class="help-inline"><wicket:message key="gb.canAdminDescription"></wicket:message></span></label></td></tr> \r
- <tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="7" /> <span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr> \r
- <tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="8" /> <span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr> \r
+ <tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="7" /> <span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr> \r
+ <tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="8" /> <span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr> \r
<tr><th><wicket:message key="gb.excludeFromFederation"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="excludeFromFederation" tabindex="9" /> <span class="help-inline"><wicket:message key="gb.excludeFromFederationDescription"></wicket:message></span></label></td></tr> \r
<tr><td colspan="2" style="padding-top:15px;"><h3><wicket:message key="gb.accessPermissions"></wicket:message> <small><wicket:message key="gb.accessPermissionsForUserDescription"></wicket:message></small></h3></td></tr> \r
<tr><th style="vertical-align: top;"><wicket:message key="gb.teamMemberships"></wicket:message></th><td style="padding:2px;"><span wicket:id="teams"></span></td></tr>\r
// user not allowed to fork or fork already exists or repo forbids forking\r
add(new ExternalLink("forkLink", "").setVisible(false));\r
\r
- if (user.canFork && !model.allowForks) {\r
+ if (user.canFork() && !model.allowForks) {\r
// show forks prohibited indicator\r
Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this);\r
Label lbl = new Label("forksProhibited", getString("gb.forksProhibited"));\r
add(new GravatarImage("gravatar", person, 210));\r
\r
UserModel sessionUser = GitBlitWebSession.get().getUser();\r
- if (sessionUser != null && user.canCreate && sessionUser.equals(user)) {\r
+ if (sessionUser != null && user.canCreate() && sessionUser.equals(user)) {\r
// user can create personal repositories\r
add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
} else {\r
}.setVisible(GitBlit.getBoolean(Keys.git.cacheRepositoryList, true)));\r
managementLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
add(managementLinks);\r
- } else if (showManagement && user != null && user.canCreate) {\r
+ } else if (showManagement && user != null && user.canCreate()) {\r
// user can create personal repositories\r
managementLinks = new Fragment("managementPanel", "personalLinks", this);\r
managementLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
item.add(editLink);\r
}\r
\r
- item.add(new Label("accesslevel", entry.canAdmin ? "administrator" : ""));\r
+ item.add(new Label("accesslevel", entry.canAdmin() ? "administrator" : ""));\r
item.add(new Label("teams", entry.teams.size() > 0 ? ("" + entry.teams.size()) : ""));\r
item.add(new Label("repositories",\r
entry.repositories.size() > 0 ? ("" + entry.repositories.size()) : ""));\r
role = "#admin"
role = "#notfederated"
[team "admins"]
+ role = "#none"
user = admin
assertFalse("user CAN delete!", user.canDelete(repository));
assertFalse("user CAN edit!", user.canEdit(repository));
+ }
+
+ @Test
+ public void testAdminTeamInheritance() throws Exception {
+ UserModel user = new UserModel("test");
+ TeamModel team = new TeamModel("team");
+ team.canAdmin = true;
+ user.teams.add(team);
+ assertTrue("User did not inherit admin privileges", user.canAdmin());
+ }
+
+ @Test
+ public void testForkTeamInheritance() throws Exception {
+ UserModel user = new UserModel("test");
+ TeamModel team = new TeamModel("team");
+ team.canFork = true;
+ user.teams.add(team);
+ assertTrue("User did not inherit fork privileges", user.canFork());
+ }
+ @Test
+ public void testCreateTeamInheritance() throws Exception {
+ UserModel user = new UserModel("test");
+ TeamModel team = new TeamModel("team");
+ team.canCreate= true;
+ user.teams.add(team);
+ assertTrue("User did not inherit create privileges", user.canCreate());
}
+
}