From b461a45f420471f931029898d97464ecc5039f49 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Sat, 22 Dec 2012 00:27:04 -0500 Subject: [PATCH] Do not pass null email address to PersonIdent --- src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java | 202 +++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 180 insertions(+), 22 deletions(-) diff --git a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java index b6ed890..4156cd1 100644 --- a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java +++ b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java @@ -15,12 +15,15 @@ */ package com.gitblit.wicket.panels; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxButton; @@ -28,16 +31,21 @@ 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.panel.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.OddEvenItem; import org.apache.wicket.markup.repeater.RefreshingView; import org.apache.wicket.markup.repeater.util.ModelIteratorAdapter; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; +import org.eclipse.jgit.lib.PersonIdent; import com.gitblit.Constants.AccessPermission; +import com.gitblit.Constants.PermissionType; import com.gitblit.Constants.RegistrantType; +import com.gitblit.GitBlit; import com.gitblit.models.RegistrantAccessPermission; +import com.gitblit.models.UserModel; import com.gitblit.utils.DeepCopier; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.WicketUtils; @@ -51,11 +59,42 @@ public class RegistrantPermissionsPanel extends BasePanel { private static final long serialVersionUID = 1L; - - public RegistrantPermissionsPanel(String wicketId, List<String> allRegistrants, final List<RegistrantAccessPermission> permissions, final Map<AccessPermission, String> translations) { - super(wicketId); + + public enum Show { + specified, mutable, effective; - // update existing permissions repeater + public boolean show(RegistrantAccessPermission ap) { + switch (this) { + case specified: + return ap.mutable || ap.isOwner(); + case mutable: + return ap.mutable; + case effective: + return true; + default: + return true; + } + } + } + + private Show activeState = Show.mutable; + + public RegistrantPermissionsPanel(String wicketId, RegistrantType registrantType, List<String> allRegistrants, final List<RegistrantAccessPermission> permissions, final Map<AccessPermission, String> translations) { + super(wicketId); + setOutputMarkupId(true); + + /* + * Permission view toggle buttons + */ + Form<Void> permissionToggleForm = new Form<Void>("permissionToggleForm"); + permissionToggleForm.add(new ShowStateButton("showSpecified", Show.specified)); + permissionToggleForm.add(new ShowStateButton("showMutable", Show.mutable)); + permissionToggleForm.add(new ShowStateButton("showEffective", Show.effective)); + add(permissionToggleForm); + + /* + * Permission repeating display + */ RefreshingView<RegistrantAccessPermission> dataView = new RefreshingView<RegistrantAccessPermission>("permissionRow") { private static final long serialVersionUID = 1L; @@ -80,23 +119,83 @@ public void populateItem(final Item<RegistrantAccessPermission> item) { final RegistrantAccessPermission entry = item.getModelObject(); - if (RegistrantType.REPOSITORY.equals(entry.type)) { - // repository, strip .git and show swatch + if (RegistrantType.REPOSITORY.equals(entry.registrantType)) { String repoName = StringUtils.stripDotGit(entry.registrant); - Label registrant = new Label("registrant", repoName); - WicketUtils.setCssClass(registrant, "repositorySwatch"); - WicketUtils.setCssBackground(registrant, repoName); - item.add(registrant); + if (!entry.isMissing() && StringUtils.findInvalidCharacter(repoName) == null) { + // repository, strip .git and show swatch + Fragment repositoryFragment = new Fragment("registrant", "repositoryRegistrant", RegistrantPermissionsPanel.this); + Component swatch = new Label("repositorySwatch", " ").setEscapeModelStrings(false); + WicketUtils.setCssBackground(swatch, entry.toString()); + repositoryFragment.add(swatch); + Label registrant = new Label("repositoryName", repoName); + repositoryFragment.add(registrant); + item.add(repositoryFragment); + } else { + // regex or missing + Label label = new Label("registrant", entry.registrant); + WicketUtils.setCssStyle(label, "font-weight: bold;"); + item.add(label); + } + } else if (RegistrantType.USER.equals(entry.registrantType)) { + // user + PersonIdent ident = new PersonIdent(entry.registrant, ""); + UserModel user = GitBlit.self().getUserModel(entry.registrant); + if (user != null) { + ident = new PersonIdent(user.getDisplayName(), user.emailAddress == null ? user.getDisplayName() : user.emailAddress); + } + + Fragment userFragment = new Fragment("registrant", "userRegistrant", RegistrantPermissionsPanel.this); + userFragment.add(new GravatarImage("userAvatar", ident, 20, false)); + userFragment.add(new Label("userName", entry.registrant)); + item.add(userFragment); } else { - item.add(new Label("registrant", entry.registrant)); + // team + Fragment teamFragment = new Fragment("registrant", "teamRegistrant", RegistrantPermissionsPanel.this); + teamFragment.add(new Label("teamName", entry.registrant)); + item.add(teamFragment); } - if (entry.isExplicit) { - item.add(new Label("regex", "").setVisible(false)); - } else { - Label regex = new Label("regex", "regex"); - WicketUtils.setHtmlTooltip(regex, getString("gb.regexPermission")); + switch (entry.permissionType) { + case ADMINISTRATOR: + Label administrator = new Label("pType", entry.source == null ? getString("gb.administrator") : entry.source); + WicketUtils.setHtmlTooltip(administrator, getString("gb.administratorPermission")); + WicketUtils.setCssClass(administrator, "label label-inverse"); + item.add(administrator); + break; + case OWNER: + Label owner = new Label("pType", getString("gb.owner")); + WicketUtils.setHtmlTooltip(owner, getString("gb.ownerPermission")); + WicketUtils.setCssClass(owner, "label label-info"); + item.add(owner); + break; + case TEAM: + Label team = new Label("pType", entry.source == null ? getString("gb.team") : entry.source); + WicketUtils.setHtmlTooltip(team, MessageFormat.format(getString("gb.teamPermission"), entry.source)); + WicketUtils.setCssClass(team, "label label-success"); + item.add(team); + break; + case REGEX: + Label regex = new Label("pType", "regex"); + if (!StringUtils.isEmpty(entry.source)) { + WicketUtils.setHtmlTooltip(regex, MessageFormat.format(getString("gb.regexPermission"), entry.source)); + } + WicketUtils.setCssClass(regex, "label"); item.add(regex); + break; + default: + if (entry.isMissing()) { + // repository is missing, this permission will be removed on save + Label missing = new Label("pType", getString("gb.missing")); + WicketUtils.setCssClass(missing, "label label-important"); + WicketUtils.setHtmlTooltip(missing, getString("gb.missingPermission")); + item.add(missing); + } else { + // standard permission + item.add(new Label("pType", "").setVisible(false)); + } + break; } + + item.setVisible(activeState.show(entry)); // use ajax to get immediate update of permission level change // otherwise we can lose it if they change levels and then add @@ -106,8 +205,9 @@ // only allow changing an explicitly defined permission // this is designed to prevent changing a regex permission in // a repository - permissionChoice.setEnabled(entry.isExplicit); - if (entry.isExplicit) { + permissionChoice.setEnabled(entry.mutable); + permissionChoice.setOutputMarkupId(true); + if (entry.mutable) { permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") { private static final long serialVersionUID = 1L; @@ -127,11 +227,23 @@ // filter out registrants we already have permissions for final List<String> registrants = new ArrayList<String>(allRegistrants); for (RegistrantAccessPermission rp : permissions) { - registrants.remove(rp.registrant); + if (rp.mutable) { + // remove editable duplicates + // this allows for specifying an explicit permission + registrants.remove(rp.registrant); + } else if (rp.isAdmin()) { + // administrators can not have their permission changed + registrants.remove(rp.registrant); + } else if (rp.isOwner()) { + // owners can not have their permission changed + registrants.remove(rp.registrant); + } } - // add new permission form - IModel<RegistrantAccessPermission> addPermissionModel = new CompoundPropertyModel<RegistrantAccessPermission>(new RegistrantAccessPermission()); + /* + * Add permission form + */ + IModel<RegistrantAccessPermission> addPermissionModel = new CompoundPropertyModel<RegistrantAccessPermission>(new RegistrantAccessPermission(registrantType)); Form<RegistrantAccessPermission> addPermissionForm = new Form<RegistrantAccessPermission>("addPermissionForm", addPermissionModel); addPermissionForm.add(new DropDownChoice<String>("registrant", registrants)); addPermissionForm.add(new DropDownChoice<AccessPermission>("permission", Arrays @@ -144,7 +256,18 @@ protected void onSubmit(AjaxRequestTarget target, Form<?> form) { // add permission to our list RegistrantAccessPermission rp = (RegistrantAccessPermission) form.getModel().getObject(); - permissions.add(DeepCopier.copy(rp)); + if (rp.permission == null) { + return; + } + RegistrantAccessPermission copy = DeepCopier.copy(rp); + if (StringUtils.findInvalidCharacter(copy.registrant) != null) { + copy.permissionType = PermissionType.REGEX; + copy.source = copy.registrant; + } + permissions.add(copy); + + // resort permissions after insert to convey idea of eval order + Collections.sort(permissions); // remove registrant from available choices registrants.remove(rp.registrant); @@ -158,6 +281,12 @@ // only show add permission form if we have a registrant choice add(addPermissionForm.setVisible(registrants.size() > 0)); } + + protected boolean getStatelessHint() + { + return false; + } + private class AccessPermissionRenderer implements IChoiceRenderer<AccessPermission> { @@ -179,4 +308,33 @@ return Integer.toString(index); } } + + private class ShowStateButton extends AjaxButton { + private static final long serialVersionUID = 1L; + + Show buttonState; + + public ShowStateButton(String wicketId, Show state) { + super(wicketId); + this.buttonState = state; + setOutputMarkupId(true); + } + + @Override + protected void onBeforeRender() + { + String cssClass = "btn"; + if (buttonState.equals(RegistrantPermissionsPanel.this.activeState)) { + cssClass = "btn btn-info active"; + } + WicketUtils.setCssClass(this, cssClass); + super.onBeforeRender(); + } + + @Override + protected void onSubmit(AjaxRequestTarget target, Form<?> form) { + RegistrantPermissionsPanel.this.activeState = buttonState; + target.addComponent(RegistrantPermissionsPanel.this); + } + }; } -- Gitblit v1.9.1