| | |
| | | */ |
| | | 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; |
| | |
| | | public class RegistrantPermissionsPanel extends BasePanel { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | |
| | | public enum Show { |
| | | specified, mutable, effective; |
| | | |
| | | 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); |
| | | |
| | | // update existing permissions repeater |
| | | |
| | | /* |
| | | * 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; |
| | | |
| | |
| | | final RegistrantAccessPermission entry = item.getModelObject(); |
| | | if (RegistrantType.REPOSITORY.equals(entry.registrantType)) { |
| | | String repoName = StringUtils.stripDotGit(entry.registrant); |
| | | if (StringUtils.findInvalidCharacter(repoName) == null) { |
| | | if (!entry.isMissing() && StringUtils.findInvalidCharacter(repoName) == null) { |
| | | // repository, strip .git and show swatch |
| | | Label registrant = new Label("registrant", repoName); |
| | | WicketUtils.setCssClass(registrant, "repositorySwatch"); |
| | | WicketUtils.setCssBackground(registrant, repoName); |
| | | item.add(registrant); |
| | | 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 { |
| | | // likely a regex |
| | | // 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, null); |
| | | PersonIdent ident = new PersonIdent(entry.registrant, ""); |
| | | UserModel user = GitBlit.self().getUserModel(entry.registrant); |
| | | if (user != null) { |
| | | ident = new PersonIdent(user.getDisplayName(), user.emailAddress); |
| | | 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, 16, false)); |
| | | userFragment.add(new GravatarImage("userAvatar", ident, 20, false)); |
| | | userFragment.add(new Label("userName", entry.registrant)); |
| | | item.add(userFragment); |
| | | } else { |
| | |
| | | item.add(teamFragment); |
| | | } |
| | | 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", "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"); |
| | | WicketUtils.setHtmlTooltip(regex, getString("gb.regexPermission")); |
| | | if (!StringUtils.isEmpty(entry.source)) { |
| | | WicketUtils.setHtmlTooltip(regex, MessageFormat.format(getString("gb.regexPermission"), entry.source)); |
| | | } |
| | | WicketUtils.setCssClass(regex, "label"); |
| | | item.add(regex); |
| | | break; |
| | | default: |
| | | item.add(new Label("pType", "").setVisible(false)); |
| | | 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 |
| | |
| | | // only allow changing an explicitly defined permission |
| | | // this is designed to prevent changing a regex permission in |
| | | // a repository |
| | | permissionChoice.setEnabled(entry.isEditable); |
| | | permissionChoice.setEnabled(entry.mutable); |
| | | permissionChoice.setOutputMarkupId(true); |
| | | if (entry.isEditable) { |
| | | if (entry.mutable) { |
| | | permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | |
| | | // filter out registrants we already have permissions for |
| | | final List<String> registrants = new ArrayList<String>(allRegistrants); |
| | | for (RegistrantAccessPermission rp : permissions) { |
| | | if (rp.isEditable) { |
| | | // only remove editable duplicates |
| | | 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 |
| | | /* |
| | | * 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)); |
| | |
| | | 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); |
| | |
| | | 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); |
| | | } |
| | | }; |
| | | } |