/* | |
* Copyright 2011 gitblit.com. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.gitblit.wicket.pages; | |
import java.text.MessageFormat; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.LinkedHashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
import org.apache.wicket.PageParameters; | |
import org.apache.wicket.ajax.AjaxRequestTarget; | |
import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior; | |
import org.apache.wicket.behavior.SimpleAttributeModifier; | |
import org.apache.wicket.extensions.markup.html.form.palette.Palette; | |
import org.apache.wicket.markup.html.WebMarkupContainer; | |
import org.apache.wicket.markup.html.basic.Label; | |
import org.apache.wicket.markup.html.form.Button; | |
import org.apache.wicket.markup.html.form.CheckBox; | |
import org.apache.wicket.markup.html.form.ChoiceRenderer; | |
import org.apache.wicket.markup.html.form.DropDownChoice; | |
import org.apache.wicket.markup.html.form.Form; | |
import org.apache.wicket.markup.html.form.IChoiceRenderer; | |
import org.apache.wicket.markup.html.form.TextField; | |
import org.apache.wicket.markup.html.link.Link; | |
import org.apache.wicket.markup.html.list.ListItem; | |
import org.apache.wicket.markup.html.list.ListView; | |
import org.apache.wicket.model.CompoundPropertyModel; | |
import org.apache.wicket.model.IModel; | |
import org.apache.wicket.model.Model; | |
import org.apache.wicket.model.PropertyModel; | |
import org.apache.wicket.model.util.CollectionModel; | |
import org.apache.wicket.model.util.ListModel; | |
import org.eclipse.jgit.lib.Repository; | |
import com.gitblit.Constants; | |
import com.gitblit.Constants.AccessRestrictionType; | |
import com.gitblit.Constants.AuthorizationControl; | |
import com.gitblit.Constants.CommitMessageRenderer; | |
import com.gitblit.Constants.FederationStrategy; | |
import com.gitblit.Constants.RegistrantType; | |
import com.gitblit.GitBlitException; | |
import com.gitblit.Keys; | |
import com.gitblit.models.RegistrantAccessPermission; | |
import com.gitblit.models.RepositoryModel; | |
import com.gitblit.models.UserChoice; | |
import com.gitblit.models.UserModel; | |
import com.gitblit.utils.ArrayUtils; | |
import com.gitblit.utils.StringUtils; | |
import com.gitblit.wicket.GitBlitWebSession; | |
import com.gitblit.wicket.StringChoiceRenderer; | |
import com.gitblit.wicket.WicketUtils; | |
import com.gitblit.wicket.panels.AccessPolicyPanel; | |
import com.gitblit.wicket.panels.BasePanel.JavascriptEventConfirmation; | |
import com.gitblit.wicket.panels.BooleanOption; | |
import com.gitblit.wicket.panels.BulletListPanel; | |
import com.gitblit.wicket.panels.ChoiceOption; | |
import com.gitblit.wicket.panels.RegistrantPermissionsPanel; | |
import com.gitblit.wicket.panels.RepositoryNamePanel; | |
import com.gitblit.wicket.panels.TextOption; | |
public class EditRepositoryPage extends RootSubPage { | |
private final boolean isCreate; | |
RepositoryNamePanel namePanel; | |
AccessPolicyPanel accessPolicyPanel; | |
private boolean isAdmin; | |
RepositoryModel repositoryModel; | |
private IModel<String> metricAuthorExclusions; | |
private IModel<String> mailingLists; | |
public EditRepositoryPage() { | |
// create constructor | |
super(); | |
isCreate = true; | |
RepositoryModel model = new RepositoryModel(); | |
String restriction = app().settings().getString(Keys.git.defaultAccessRestriction, "PUSH"); | |
model.accessRestriction = AccessRestrictionType.fromName(restriction); | |
String authorization = app().settings().getString(Keys.git.defaultAuthorizationControl, null); | |
model.authorizationControl = AuthorizationControl.fromName(authorization); | |
GitBlitWebSession session = GitBlitWebSession.get(); | |
UserModel user = session.getUser(); | |
if (user != null && user.canCreate() && !user.canAdmin()) { | |
// personal create permissions, inject personal repository path | |
model.name = user.getPersonalPath() + "/"; | |
model.projectPath = user.getPersonalPath(); | |
model.addOwner(user.username); | |
// personal repositories are private by default | |
model.accessRestriction = AccessRestrictionType.VIEW; | |
model.authorizationControl = AuthorizationControl.NAMED; | |
} | |
setupPage(model); | |
setStatelessHint(false); | |
setOutputMarkupId(true); | |
} | |
public EditRepositoryPage(PageParameters params) { | |
// edit constructor | |
super(params); | |
isCreate = false; | |
String name = WicketUtils.getRepositoryName(params); | |
RepositoryModel model = app().repositories().getRepositoryModel(name); | |
setupPage(model); | |
setStatelessHint(false); | |
setOutputMarkupId(true); | |
} | |
@Override | |
protected boolean requiresPageMap() { | |
return true; | |
} | |
@Override | |
protected Class<? extends BasePage> getRootNavPageClass() { | |
return RepositoriesPage.class; | |
} | |
protected void setupPage(RepositoryModel model) { | |
this.repositoryModel = model; | |
// ensure this user can create or edit this repository | |
checkPermissions(repositoryModel); | |
List<String> indexedBranches = new ArrayList<String>(); | |
List<String> federationSets = new ArrayList<String>(); | |
final List<RegistrantAccessPermission> repositoryUsers = new ArrayList<RegistrantAccessPermission>(); | |
final List<RegistrantAccessPermission> repositoryTeams = new ArrayList<RegistrantAccessPermission>(); | |
List<String> preReceiveScripts = new ArrayList<String>(); | |
List<String> postReceiveScripts = new ArrayList<String>(); | |
GitBlitWebSession session = GitBlitWebSession.get(); | |
final UserModel user = session.getUser() == null ? UserModel.ANONYMOUS : session.getUser(); | |
final boolean allowEditName = isCreate || isAdmin || repositoryModel.isUsersPersonalRepository(user.username); | |
if (isCreate) { | |
if (user.canAdmin()) { | |
super.setupPage(getString("gb.newRepository"), ""); | |
} else { | |
super.setupPage(getString("gb.newRepository"), user.getDisplayName()); | |
} | |
} else { | |
super.setupPage(getString("gb.edit"), repositoryModel.name); | |
repositoryUsers.addAll(app().repositories().getUserAccessPermissions(repositoryModel)); | |
repositoryTeams.addAll(app().repositories().getTeamAccessPermissions(repositoryModel)); | |
Collections.sort(repositoryUsers); | |
Collections.sort(repositoryTeams); | |
federationSets.addAll(repositoryModel.federationSets); | |
if (!ArrayUtils.isEmpty(repositoryModel.indexedBranches)) { | |
indexedBranches.addAll(repositoryModel.indexedBranches); | |
} | |
} | |
final String oldName = repositoryModel.name; | |
final RegistrantPermissionsPanel usersPalette = new RegistrantPermissionsPanel("users", | |
RegistrantType.USER, app().users().getAllUsernames(), repositoryUsers, getAccessPermissions()); | |
final RegistrantPermissionsPanel teamsPalette = new RegistrantPermissionsPanel("teams", | |
RegistrantType.TEAM, app().users().getAllTeamNames(), repositoryTeams, getAccessPermissions()); | |
// owners palette | |
List<UserChoice> owners = new ArrayList<UserChoice>(); | |
List<UserChoice> persons = new ArrayList<UserChoice>(); | |
for (String owner : repositoryModel.owners) { | |
UserModel o = app().users().getUserModel(owner); | |
if (o != null) { | |
owners.add(new UserChoice(o.getDisplayName(), o.username, o.emailAddress)); | |
} else { | |
UserChoice userChoice = new UserChoice(owner); | |
owners.add(userChoice); | |
persons.add(userChoice); | |
} | |
} | |
for (String person : app().users().getAllUsernames()) { | |
UserModel o = app().users().getUserModel(person); | |
if (o != null) { | |
persons.add(new UserChoice(o.getDisplayName(), o.username, o.emailAddress)); | |
} else { | |
persons.add(new UserChoice(person)); | |
} | |
} | |
final Palette<UserChoice> ownersPalette = new Palette<UserChoice>("owners", new ListModel<UserChoice>(owners), new CollectionModel<UserChoice>( | |
persons), new ChoiceRenderer<UserChoice>(null, "userId"), 12, false); | |
// indexed local branches palette | |
List<String> allLocalBranches = new ArrayList<String>(); | |
allLocalBranches.add(Constants.DEFAULT_BRANCH); | |
allLocalBranches.addAll(repositoryModel.getLocalBranches()); | |
boolean luceneEnabled = app().settings().getBoolean(Keys.web.allowLuceneIndexing, true); | |
final Palette<String> indexedBranchesPalette = new Palette<String>("indexedBranches", new ListModel<String>( | |
indexedBranches), new CollectionModel<String>(allLocalBranches), | |
new StringChoiceRenderer(), 8, false); | |
indexedBranchesPalette.setEnabled(luceneEnabled); | |
// federation sets palette | |
List<String> sets = app().settings().getStrings(Keys.federation.sets); | |
final Palette<String> federationSetsPalette = new Palette<String>("federationSets", | |
new ListModel<String>(federationSets), new CollectionModel<String>(sets), | |
new StringChoiceRenderer(), 8, false); | |
// pre-receive palette | |
if (!ArrayUtils.isEmpty(repositoryModel.preReceiveScripts)) { | |
preReceiveScripts.addAll(repositoryModel.preReceiveScripts); | |
} | |
final Palette<String> preReceivePalette = new Palette<String>("preReceiveScripts", | |
new ListModel<String>(preReceiveScripts), new CollectionModel<String>(app().repositories() | |
.getPreReceiveScriptsUnused(repositoryModel)), | |
new StringChoiceRenderer(), 12, true); | |
// post-receive palette | |
if (!ArrayUtils.isEmpty(repositoryModel.postReceiveScripts)) { | |
postReceiveScripts.addAll(repositoryModel.postReceiveScripts); | |
} | |
final Palette<String> postReceivePalette = new Palette<String>("postReceiveScripts", | |
new ListModel<String>(postReceiveScripts), new CollectionModel<String>(app().repositories() | |
.getPostReceiveScriptsUnused(repositoryModel)), | |
new StringChoiceRenderer(), 12, true); | |
// custom fields | |
final Map<String, String> customFieldsMap = app().settings().getMap(Keys.groovy.customFields); | |
List<String> customKeys = new ArrayList<String>(customFieldsMap.keySet()); | |
final ListView<String> customFieldsListView = new ListView<String>("customFieldsListView", customKeys) { | |
private static final long serialVersionUID = 1L; | |
@Override | |
protected void populateItem(ListItem<String> item) { | |
String key = item.getModelObject(); | |
item.add(new Label("customFieldLabel", customFieldsMap.get(key))); | |
String value = ""; | |
if (repositoryModel.customFields != null && repositoryModel.customFields.containsKey(key)) { | |
value = repositoryModel.customFields.get(key); | |
} | |
TextField<String> field = new TextField<String>("customFieldValue", new Model<String>(value)); | |
item.add(field); | |
} | |
}; | |
customFieldsListView.setReuseItems(true); | |
CompoundPropertyModel<RepositoryModel> rModel = new CompoundPropertyModel<RepositoryModel>( | |
repositoryModel); | |
Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", rModel) { | |
private static final long serialVersionUID = 1L; | |
@Override | |
protected void onSubmit() { | |
try { | |
if (!namePanel.updateModel(repositoryModel)) { | |
return; | |
} | |
// confirm access restriction selection | |
if (repositoryModel.accessRestriction == null) { | |
error(getString("gb.selectAccessRestriction")); | |
return; | |
} | |
// confirm federation strategy selection | |
if (repositoryModel.federationStrategy == null) { | |
error(getString("gb.selectFederationStrategy")); | |
return; | |
} | |
// save federation set preferences | |
if (repositoryModel.federationStrategy.exceeds(FederationStrategy.EXCLUDE)) { | |
repositoryModel.federationSets.clear(); | |
Iterator<String> sets = federationSetsPalette.getSelectedChoices(); | |
while (sets.hasNext()) { | |
repositoryModel.federationSets.add(sets.next()); | |
} | |
} | |
// set author metric exclusions | |
String ax = metricAuthorExclusions.getObject(); | |
if (StringUtils.isEmpty(ax)) { | |
repositoryModel.metricAuthorExclusions = new ArrayList<String>(); | |
} else { | |
Set<String> list = new HashSet<String>(); | |
for (String exclusion : StringUtils.getStringsFromValue(ax, " ")) { | |
if (StringUtils.isEmpty(exclusion)) { | |
continue; | |
} | |
if (exclusion.indexOf(' ') > -1) { | |
list.add("\"" + exclusion + "\""); | |
} else { | |
list.add(exclusion); | |
} | |
} | |
repositoryModel.metricAuthorExclusions = new ArrayList<String>(list); | |
} | |
// set mailing lists | |
String ml = mailingLists.getObject(); | |
if (StringUtils.isEmpty(ml)) { | |
repositoryModel.mailingLists = new ArrayList<String>(); | |
} else { | |
Set<String> list = new HashSet<String>(); | |
for (String address : ml.split("(,|\\s)")) { | |
if (StringUtils.isEmpty(address)) { | |
continue; | |
} | |
list.add(address.toLowerCase()); | |
} | |
repositoryModel.mailingLists = new ArrayList<String>(list); | |
} | |
// indexed branches | |
List<String> indexedBranches = new ArrayList<String>(); | |
Iterator<String> branches = indexedBranchesPalette.getSelectedChoices(); | |
while (branches.hasNext()) { | |
indexedBranches.add(branches.next()); | |
} | |
repositoryModel.indexedBranches = indexedBranches; | |
// owners | |
repositoryModel.owners.clear(); | |
Iterator<UserChoice> owners = ownersPalette.getSelectedChoices(); | |
while (owners.hasNext()) { | |
repositoryModel.addOwner(owners.next().getUserId()); | |
} | |
// pre-receive scripts | |
List<String> preReceiveScripts = new ArrayList<String>(); | |
Iterator<String> pres = preReceivePalette.getSelectedChoices(); | |
while (pres.hasNext()) { | |
preReceiveScripts.add(pres.next()); | |
} | |
repositoryModel.preReceiveScripts = preReceiveScripts; | |
// post-receive scripts | |
List<String> postReceiveScripts = new ArrayList<String>(); | |
Iterator<String> post = postReceivePalette.getSelectedChoices(); | |
while (post.hasNext()) { | |
postReceiveScripts.add(post.next()); | |
} | |
repositoryModel.postReceiveScripts = postReceiveScripts; | |
// custom fields | |
repositoryModel.customFields = new LinkedHashMap<String, String>(); | |
for (int i = 0; i < customFieldsListView.size(); i++) { | |
ListItem<String> child = (ListItem<String>) customFieldsListView.get(i); | |
String key = child.getModelObject(); | |
TextField<String> field = (TextField<String>) child.get("customFieldValue"); | |
String value = field.getValue(); | |
repositoryModel.customFields.put(key, value); | |
} | |
// save the repository | |
app().gitblit().updateRepositoryModel(oldName, repositoryModel, isCreate); | |
// repository access permissions | |
if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) { | |
app().gitblit().setUserAccessPermissions(repositoryModel, repositoryUsers); | |
app().gitblit().setTeamAccessPermissions(repositoryModel, repositoryTeams); | |
} | |
} catch (GitBlitException e) { | |
error(e.getMessage()); | |
return; | |
} | |
setRedirect(false); | |
setResponsePage(SummaryPage.class, WicketUtils.newRepositoryParameter(repositoryModel.name)); | |
} | |
}; | |
// Determine available refs & branches | |
List<String> availableRefs = new ArrayList<String>(); | |
List<String> availableBranches = new ArrayList<String>(); | |
if (!ArrayUtils.isEmpty(repositoryModel.availableRefs)) { | |
for (String ref : repositoryModel.availableRefs) { | |
if (!ref.startsWith(Constants.R_TICKET)) { | |
availableRefs.add(ref); | |
if (ref.startsWith(Constants.R_HEADS)) { | |
availableBranches.add(Repository.shortenRefName(ref)); | |
} | |
} | |
} | |
} | |
// do not let the browser pre-populate these fields | |
form.add(new SimpleAttributeModifier("autocomplete", "off")); | |
// | |
// | |
// GENERAL | |
// | |
namePanel = new RepositoryNamePanel("namePanel", repositoryModel); | |
namePanel.setEditable(allowEditName); | |
form.add(namePanel); | |
// XXX AccessPolicyPanel is defined later. | |
form.add(new ChoiceOption<String>("head", | |
getString("gb.headRef"), | |
getString("gb.headRefDescription"), | |
new PropertyModel<String>(repositoryModel, "HEAD"), | |
availableRefs)); | |
// | |
// PERMISSIONS | |
// | |
form.add(ownersPalette); | |
form.add(usersPalette); | |
form.add(teamsPalette); | |
// | |
// TICKETS | |
// | |
form.add(new BooleanOption("acceptNewPatchsets", | |
getString("gb.acceptNewPatchsets"), | |
getString("gb.acceptNewPatchsetsDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "acceptNewPatchsets"))); | |
form.add(new BooleanOption("acceptNewTickets", | |
getString("gb.acceptNewTickets"), | |
getString("gb.acceptNewTicketsDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "acceptNewPatchsets"))); | |
form.add(new BooleanOption("requireApproval", | |
getString("gb.requireApproval"), | |
getString("gb.requireApprovalDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "requireApproval"))); | |
form.add(new ChoiceOption<String>("mergeTo", | |
getString("gb.mergeTo"), | |
getString("gb.mergeToDescription"), | |
new PropertyModel<String>(repositoryModel, "mergeTo"), | |
availableBranches)); | |
// | |
// RECEIVE | |
// | |
form.add(new BooleanOption("isFrozen", | |
getString("gb.isFrozen"), | |
getString("gb.isFrozenDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "isFrozen"))); | |
form.add(new BooleanOption("incrementalPushTags", | |
getString("gb.enableIncrementalPushTags"), | |
getString("gb.useIncrementalPushTagsDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "useIncrementalPushTags"))); | |
final CheckBox verifyCommitter = new CheckBox("checkbox", new PropertyModel<Boolean>(repositoryModel, "verifyCommitter")); | |
verifyCommitter.setOutputMarkupId(true); | |
form.add(new BooleanOption("verifyCommitter", | |
getString("gb.verifyCommitter"), | |
getString("gb.verifyCommitterDescription") + "<br/>" + getString("gb.verifyCommitterNote"), | |
verifyCommitter).setIsHtmlDescription(true)); | |
form.add(preReceivePalette); | |
form.add(new BulletListPanel("inheritedPreReceive", getString("gb.inherited"), app().repositories() | |
.getPreReceiveScriptsInherited(repositoryModel))); | |
form.add(postReceivePalette); | |
form.add(new BulletListPanel("inheritedPostReceive", getString("gb.inherited"), app().repositories() | |
.getPostReceiveScriptsInherited(repositoryModel))); | |
WebMarkupContainer customFieldsSection = new WebMarkupContainer("customFieldsSection"); | |
customFieldsSection.add(customFieldsListView); | |
form.add(customFieldsSection.setVisible(!app().settings().getString(Keys.groovy.customFields, "").isEmpty())); | |
// | |
// FEDERATION | |
// | |
List<FederationStrategy> federationStrategies = new ArrayList<FederationStrategy>( | |
Arrays.asList(FederationStrategy.values())); | |
// federation strategies - remove ORIGIN choice if this repository has no origin. | |
if (StringUtils.isEmpty(repositoryModel.origin)) { | |
federationStrategies.remove(FederationStrategy.FEDERATE_ORIGIN); | |
} | |
form.add(new ChoiceOption<FederationStrategy>("federationStrategy", | |
getString("gb.federationStrategy"), | |
getString("gb.federationStrategyDescription"), | |
new DropDownChoice<FederationStrategy>( | |
"choice", | |
new PropertyModel<FederationStrategy>(repositoryModel, "federationStrategy"), | |
federationStrategies, | |
new FederationTypeRenderer()))); | |
form.add(federationSetsPalette); | |
// | |
// SEARCH | |
// | |
form.add(indexedBranchesPalette); | |
// | |
// GARBAGE COLLECTION | |
// | |
boolean gcEnabled = app().settings().getBoolean(Keys.git.enableGarbageCollection, false); | |
int defaultGcPeriod = app().settings().getInteger(Keys.git.defaultGarbageCollectionPeriod, 7); | |
if (repositoryModel.gcPeriod == 0) { | |
repositoryModel.gcPeriod = defaultGcPeriod; | |
} | |
List<Integer> gcPeriods = Arrays.asList(1, 2, 3, 4, 5, 7, 10, 14 ); | |
form.add(new ChoiceOption<Integer>("gcPeriod", | |
getString("gb.gcPeriod"), | |
getString("gb.gcPeriodDescription"), | |
new DropDownChoice<Integer>("choice", | |
new PropertyModel<Integer>(repositoryModel, "gcPeriod"), | |
gcPeriods, | |
new GCPeriodRenderer())).setEnabled(gcEnabled)); | |
form.add(new TextOption("gcThreshold", | |
getString("gb.gcThreshold"), | |
getString("gb.gcThresholdDescription"), | |
"span1", | |
new PropertyModel<String>(repositoryModel, "gcThreshold")).setEnabled(gcEnabled)); | |
// | |
// MISCELLANEOUS | |
// | |
form.add(new TextOption("origin", | |
getString("gb.origin"), | |
getString("gb.originDescription"), | |
"span6", | |
new PropertyModel<String>(repositoryModel, "origin")).setEnabled(false)); | |
form.add(new BooleanOption("showRemoteBranches", | |
getString("gb.showRemoteBranches"), | |
getString("gb.showRemoteBranchesDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "showRemoteBranches"))); | |
form.add(new BooleanOption("skipSizeCalculation", | |
getString("gb.skipSizeCalculation"), | |
getString("gb.skipSizeCalculationDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "skipSizeCalculation"))); | |
form.add(new BooleanOption("skipSummaryMetrics", | |
getString("gb.skipSummaryMetrics"), | |
getString("gb.skipSummaryMetricsDescription"), | |
new PropertyModel<Boolean>(repositoryModel, "skipSummaryMetrics"))); | |
List<Integer> maxActivityCommits = Arrays.asList(-1, 0, 25, 50, 75, 100, 150, 200, 250, 500); | |
form.add(new ChoiceOption<Integer>("maxActivityCommits", | |
getString("gb.maxActivityCommits"), | |
getString("gb.maxActivityCommitsDescription"), | |
new DropDownChoice<Integer>("choice", | |
new PropertyModel<Integer>(repositoryModel, "maxActivityCommits"), | |
maxActivityCommits, | |
new MaxActivityCommitsRenderer()))); | |
List<CommitMessageRenderer> renderers = Arrays.asList(CommitMessageRenderer.values()); | |
form.add(new ChoiceOption<CommitMessageRenderer>("commitMessageRenderer", | |
getString("gb.commitMessageRenderer"), | |
getString("gb.commitMessageRendererDescription"), | |
new DropDownChoice<CommitMessageRenderer>("choice", | |
new PropertyModel<CommitMessageRenderer>(repositoryModel, "commitMessageRenderer"), | |
renderers))); | |
metricAuthorExclusions = new Model<String>(ArrayUtils.isEmpty(repositoryModel.metricAuthorExclusions) ? "" | |
: StringUtils.flattenStrings(repositoryModel.metricAuthorExclusions, " ")); | |
form.add(new TextOption("metricAuthorExclusions", | |
getString("gb.metricAuthorExclusions"), | |
getString("gb.metricAuthorExclusions"), | |
"span6", | |
metricAuthorExclusions)); | |
mailingLists = new Model<String>(ArrayUtils.isEmpty(repositoryModel.mailingLists) ? "" | |
: StringUtils.flattenStrings(repositoryModel.mailingLists, " ")); | |
form.add(new TextOption("mailingLists", | |
getString("gb.mailingLists"), | |
getString("gb.mailingLists"), | |
"span6", | |
mailingLists)); | |
// initial enable/disable of permission controls | |
if (repositoryModel.accessRestriction.equals(AccessRestrictionType.NONE)) { | |
// anonymous everything, disable all controls | |
usersPalette.setEnabled(false); | |
teamsPalette.setEnabled(false); | |
verifyCommitter.setEnabled(false); | |
} else { | |
// authenticated something | |
// enable authorization controls | |
verifyCommitter.setEnabled(true); | |
boolean allowFineGrainedControls = repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED); | |
usersPalette.setEnabled(allowFineGrainedControls); | |
teamsPalette.setEnabled(allowFineGrainedControls); | |
} | |
// | |
// ACCESS POLICY PANEL (GENERAL) | |
// | |
AjaxFormChoiceComponentUpdatingBehavior callback = new AjaxFormChoiceComponentUpdatingBehavior() { | |
private static final long serialVersionUID = 1L; | |
@Override | |
protected void onUpdate(AjaxRequestTarget target) { | |
accessPolicyPanel.updateModel(repositoryModel); | |
boolean allowAuthorizationControl = repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE); | |
verifyCommitter.setEnabled(allowAuthorizationControl); | |
boolean allowFineGrainedControls = allowAuthorizationControl && repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED); | |
usersPalette.setEnabled(allowFineGrainedControls); | |
teamsPalette.setEnabled(allowFineGrainedControls); | |
if (allowFineGrainedControls) { | |
repositoryModel.authorizationControl = AuthorizationControl.NAMED; | |
} | |
target.addComponent(verifyCommitter); | |
target.addComponent(usersPalette); | |
target.addComponent(teamsPalette); | |
} | |
}; | |
accessPolicyPanel = new AccessPolicyPanel("accessPolicyPanel", repositoryModel, callback); | |
form.add(accessPolicyPanel); | |
// | |
// FORM CONTROLS | |
// | |
form.add(new Button("save")); | |
Button cancel = new Button("cancel") { | |
private static final long serialVersionUID = 1L; | |
@Override | |
public void onSubmit() { | |
if (isCreate) { | |
setResponsePage(RepositoriesPage.class); | |
} else { | |
setResponsePage(SummaryPage.class, WicketUtils.newRepositoryParameter(repositoryModel.name)); | |
} | |
} | |
}; | |
cancel.setDefaultFormProcessing(false); | |
form.add(cancel); | |
// the user can delete if deletions are allowed AND the user is an admin or the personal owner | |
// assigned ownership is not sufficient to allow deletion | |
boolean canDelete = !isCreate && app().repositories().canDelete(repositoryModel) | |
&& (user.canAdmin() || user.isMyPersonalRepository(repositoryModel.name)); | |
Link<Void> delete = new Link<Void>("delete") { | |
private static final long serialVersionUID = 1L; | |
@Override | |
public void onClick() { | |
RepositoryModel latestModel = app().repositories().getRepositoryModel(repositoryModel.name); | |
boolean canDelete = app().repositories().canDelete(latestModel); | |
if (canDelete) { | |
if (app().gitblit().deleteRepositoryModel(latestModel)) { | |
info(MessageFormat.format(getString("gb.repositoryDeleted"), latestModel)); | |
if (latestModel.isPersonalRepository()) { | |
// redirect to user's profile page | |
String prefix = app().settings().getString(Keys.git.userRepositoryPrefix, "~"); | |
String username = latestModel.projectPath.substring(prefix.length()); | |
setResponsePage(UserPage.class, WicketUtils.newUsernameParameter(username)); | |
} else { | |
// redirect to server repositories page | |
setResponsePage(RepositoriesPage.class); | |
} | |
} else { | |
error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), latestModel)); | |
} | |
} else { | |
error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), latestModel)); | |
} | |
} | |
}; | |
if (canDelete) { | |
delete.add(new JavascriptEventConfirmation("onclick", MessageFormat.format( | |
getString("gb.deleteRepository"), repositoryModel))); | |
} | |
form.add(delete.setVisible(canDelete)); | |
add(form); | |
} | |
/** | |
* Unfortunately must repeat part of AuthorizaitonStrategy here because that | |
* mechanism does not take PageParameters into consideration, only page | |
* instantiation. | |
* | |
* Repository Owners should be able to edit their repository. | |
*/ | |
private void checkPermissions(RepositoryModel model) { | |
boolean authenticateAdmin = app().settings().getBoolean(Keys.web.authenticateAdminPages, true); | |
boolean allowAdmin = app().settings().getBoolean(Keys.web.allowAdministration, true); | |
GitBlitWebSession session = GitBlitWebSession.get(); | |
UserModel user = session.getUser(); | |
if (allowAdmin) { | |
if (authenticateAdmin) { | |
if (user == null) { | |
// No Login Available | |
error(getString("gb.errorAdminLoginRequired"), true); | |
} | |
if (isCreate) { | |
// Create Repository | |
if (!user.canCreate() && !user.canAdmin()) { | |
// Only administrators or permitted users may create | |
error(getString("gb.errorOnlyAdminMayCreateRepository"), true); | |
} | |
} else { | |
// Edit Repository | |
if (user.canAdmin()) { | |
// Admins can edit everything | |
isAdmin = true; | |
return; | |
} else { | |
if (!model.isOwner(user.username)) { | |
// User is not an Admin nor Owner | |
error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true); | |
} | |
} | |
} | |
} | |
} else { | |
// No Administration Permitted | |
error(getString("gb.errorAdministrationDisabled"), true); | |
} | |
} | |
private class FederationTypeRenderer implements IChoiceRenderer<FederationStrategy> { | |
private static final long serialVersionUID = 1L; | |
private final Map<FederationStrategy, String> map; | |
public FederationTypeRenderer() { | |
map = getFederationTypes(); | |
} | |
@Override | |
public String getDisplayValue(FederationStrategy type) { | |
return map.get(type); | |
} | |
@Override | |
public String getIdValue(FederationStrategy type, int index) { | |
return Integer.toString(index); | |
} | |
} | |
private class GCPeriodRenderer implements IChoiceRenderer<Integer> { | |
private static final long serialVersionUID = 1L; | |
public GCPeriodRenderer() { | |
} | |
@Override | |
public String getDisplayValue(Integer value) { | |
if (value == 1) { | |
return getString("gb.duration.oneDay"); | |
} else { | |
return MessageFormat.format(getString("gb.duration.days"), value); | |
} | |
} | |
@Override | |
public String getIdValue(Integer value, int index) { | |
return Integer.toString(index); | |
} | |
} | |
private class MaxActivityCommitsRenderer implements IChoiceRenderer<Integer> { | |
private static final long serialVersionUID = 1L; | |
public MaxActivityCommitsRenderer() { | |
} | |
@Override | |
public String getDisplayValue(Integer value) { | |
if (value == -1) { | |
return getString("gb.excludeFromActivity"); | |
} else if (value == 0) { | |
return getString("gb.noMaximum"); | |
} else { | |
return value + " " + getString("gb.commits"); | |
} | |
} | |
@Override | |
public String getIdValue(Integer value, int index) { | |
return Integer.toString(index); | |
} | |
} | |
} |