123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /*
- * Copyright 2012 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.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;
- import org.apache.wicket.markup.html.basic.Label;
- 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.models.RegistrantAccessPermission;
- import com.gitblit.models.UserModel;
- import com.gitblit.utils.DeepCopier;
- import com.gitblit.utils.StringUtils;
- import com.gitblit.wicket.WicketUtils;
-
- /**
- * Allows user to manipulate registrant access permissions.
- *
- * @author James Moger
- *
- */
- 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);
-
- /*
- * 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;
-
- @Override
- protected Iterator<IModel<RegistrantAccessPermission>> getItemModels() {
- // the iterator returns RepositoryPermission objects, but we need it to
- // return models
- return new ModelIteratorAdapter<RegistrantAccessPermission>(permissions.iterator()) {
- @Override
- protected IModel<RegistrantAccessPermission> model(RegistrantAccessPermission permission) {
- return new CompoundPropertyModel<RegistrantAccessPermission>(permission);
- }
- };
- }
-
- @Override
- protected Item<RegistrantAccessPermission> newItem(String id, int index, IModel<RegistrantAccessPermission> model) {
- // this item sets markup class attribute to either 'odd' or
- // 'even' for decoration
- return new OddEvenItem<RegistrantAccessPermission>(id, index, model);
- }
-
- @Override
- public void populateItem(final Item<RegistrantAccessPermission> item) {
- final RegistrantAccessPermission entry = item.getModelObject();
- if (RegistrantType.REPOSITORY.equals(entry.registrantType)) {
- String repoName = StringUtils.stripDotGit(entry.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 = app().users().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));
- userFragment.add(new Label("userName", entry.registrant));
- item.add(userFragment);
- } else {
- // team
- Fragment teamFragment = new Fragment("registrant", "teamRegistrant", RegistrantPermissionsPanel.this);
- teamFragment.add(new Label("teamName", entry.registrant));
- 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", 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
- // a new repository permission
- final DropDownChoice<AccessPermission> permissionChoice = new DropDownChoice<AccessPermission>(
- "permission", Arrays.asList(AccessPermission.values()), new AccessPermissionRenderer(translations));
- // only allow changing an explicitly defined permission
- // this is designed to prevent changing a regex permission in
- // a repository
- permissionChoice.setEnabled(entry.mutable);
- permissionChoice.setOutputMarkupId(true);
- if (entry.mutable) {
- permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- protected void onUpdate(AjaxRequestTarget target) {
- target.addComponent(permissionChoice);
- }
- });
- }
-
- item.add(permissionChoice);
- }
- };
- add(dataView);
- setOutputMarkupId(true);
-
- // filter out registrants we already have permissions for
- final List<String> registrants = new ArrayList<String>(allRegistrants);
- for (RegistrantAccessPermission rp : permissions) {
- 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 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
- .asList(AccessPermission.NEWPERMISSIONS), new AccessPermissionRenderer(translations)));
- AjaxButton button = new AjaxButton("addPermissionButton", addPermissionForm) {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
- // add permission to our list
- RegistrantAccessPermission rp = (RegistrantAccessPermission) form.getModel().getObject();
- if (rp.permission == null) {
- return;
- }
- if (rp.registrant == 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);
-
- // force the panel to refresh
- target.addComponent(RegistrantPermissionsPanel.this);
- }
- };
- addPermissionForm.add(button);
-
- // only show add permission form if we have a registrant choice
- add(addPermissionForm.setVisible(registrants.size() > 0));
- }
-
- @Override
- protected boolean getStatelessHint()
- {
- return false;
- }
-
-
- private class AccessPermissionRenderer implements IChoiceRenderer<AccessPermission> {
-
- private static final long serialVersionUID = 1L;
-
- private final Map<AccessPermission, String> map;
-
- public AccessPermissionRenderer(Map<AccessPermission, String> map) {
- this.map = map;
- }
-
- @Override
- public String getDisplayValue(AccessPermission type) {
- return map.get(type);
- }
-
- @Override
- public String getIdValue(AccessPermission type, int index) {
- 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);
- }
- };
- }
|