001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ui.dialogs.permissions; 029 030import org.opencms.security.CmsPrincipal; 031import org.opencms.security.CmsRole; 032import org.opencms.security.I_CmsPrincipal; 033import org.opencms.ui.A_CmsUI; 034import org.opencms.ui.CmsVaadinUtils; 035import org.opencms.ui.components.CmsBasicDialog; 036import org.opencms.ui.components.CmsBasicDialog.DialogWidth; 037import org.opencms.ui.components.OpenCmsTheme; 038 039import java.util.Arrays; 040import java.util.Collection; 041import java.util.Collections; 042import java.util.HashSet; 043import java.util.LinkedHashMap; 044import java.util.Map; 045import java.util.Objects; 046import java.util.Set; 047 048import com.vaadin.server.FontAwesome; 049import com.vaadin.ui.Button; 050import com.vaadin.ui.Button.ClickEvent; 051import com.vaadin.ui.Button.ClickListener; 052import com.vaadin.ui.CustomComponent; 053import com.vaadin.ui.Window; 054import com.vaadin.v7.data.Item; 055import com.vaadin.v7.data.Property; 056import com.vaadin.v7.data.Validator; 057import com.vaadin.v7.data.Validator.InvalidValueException; 058import com.vaadin.v7.ui.ComboBox; 059import com.vaadin.v7.ui.Field; 060import com.vaadin.v7.ui.HorizontalLayout; 061import com.vaadin.v7.ui.TextField; 062 063/** 064 * The principal select widget.<p> 065 */ 066public class CmsPrincipalSelect extends CustomComponent implements Field<String>, I_CmsPrincipalSelect { 067 068 /** 069 * Handles the principal selection.<p> 070 */ 071 public interface I_PrincipalSelectHandler { 072 073 /** 074 * Called to select a principal.<p> 075 * 076 * @param principalType the principal type 077 * @param principalName the principal name 078 */ 079 void onPrincipalSelect(String principalType, String principalName); 080 } 081 082 /** Type of principal. */ 083 public static enum PrincipalType { 084 /** Groups. */ 085 group, 086 087 /** Users. */ 088 user, 089 090 /** Roles. */ 091 role; 092 } 093 094 /** The widget types. */ 095 public static enum WidgetType { 096 097 /** Select groups only. */ 098 groupwidget(PrincipalType.group), 099 /** Select any principal. */ 100 principalwidget(PrincipalType.group, PrincipalType.user, PrincipalType.role), 101 /** Select users only. */ 102 userwidget(PrincipalType.user); 103 104 private Set<PrincipalType> m_principalTypes; 105 106 private WidgetType(PrincipalType... principalTypes) { 107 108 m_principalTypes = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(principalTypes))); 109 } 110 111 public Set<PrincipalType> getPrincipalTypes() { 112 113 return m_principalTypes; 114 } 115 116 } 117 118 /** The serial version id. */ 119 private static final long serialVersionUID = 6944968889428174262L; 120 121 /** The add button. */ 122 private Button m_addPermissionSetButton; 123 124 /** The principal name text field. */ 125 private TextField m_principalName; 126 127 /** The type select box. */ 128 private ComboBox m_principalTypeSelect; 129 130 /** The principal select handler. */ 131 private I_PrincipalSelectHandler m_selectHandler; 132 133 /** The open principal select dialog button. */ 134 private Button m_selectPrincipalButton; 135 136 /** The widget type. */ 137 private WidgetType m_widgetType; 138 139 /** The principal select dialog window. */ 140 private Window m_window; 141 142 /** The main layout. */ 143 private HorizontalLayout m_main; 144 145 /**Indicates if web ous should be included. */ 146 private boolean m_includeWebOus = true; 147 148 /** Controls whether only real users/groups or also pseudo-principals like ALL_OTHERS should be shown. */ 149 private boolean m_realOnly; 150 151 /**Ou. */ 152 private String m_ou; 153 154 /** Is ou change enabled?*/ 155 private boolean m_ouChangeEnabled = true; 156 157 /** True if role selection should be allowed. */ 158 private boolean m_roleSelectionAllowed; 159 160 /** 161 * Constructor.<p> 162 */ 163 public CmsPrincipalSelect() { 164 165 m_main = new HorizontalLayout(); 166 m_main.setSpacing(true); 167 m_main.setWidth("100%"); 168 setCompositionRoot(m_main); 169 170 m_widgetType = WidgetType.principalwidget; 171 172 ComboBox principalTypeSelect = new ComboBox(); 173 principalTypeSelect.setWidth("150px"); 174 Map<String, String> principalTypes = new LinkedHashMap<String, String>(); 175 principalTypes.put( 176 I_CmsPrincipal.PRINCIPAL_USER, 177 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_LABEL_USER_0)); 178 principalTypes.put( 179 I_CmsPrincipal.PRINCIPAL_GROUP, 180 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_LABEL_GROUP_0)); 181 CmsVaadinUtils.prepareComboBox(principalTypeSelect, principalTypes); 182 183 principalTypeSelect.setNewItemsAllowed(false); 184 principalTypeSelect.setNullSelectionAllowed(false); 185 principalTypeSelect.select(I_CmsPrincipal.PRINCIPAL_USER); 186 m_main.addComponent(principalTypeSelect); 187 m_principalTypeSelect = principalTypeSelect; 188 189 m_principalName = new TextField(); 190 m_principalName.setWidth("100%"); 191 m_main.addComponent(m_principalName); 192 m_main.setExpandRatio(m_principalName, 2); 193 194 m_selectPrincipalButton = new Button(FontAwesome.USER); 195 m_selectPrincipalButton.addStyleName(OpenCmsTheme.BUTTON_ICON); 196 m_selectPrincipalButton.addClickListener(new ClickListener() { 197 198 private static final long serialVersionUID = 1L; 199 200 public void buttonClick(ClickEvent event) { 201 202 openPrincipalSelect(); 203 } 204 }); 205 m_main.addComponent(m_selectPrincipalButton); 206 } 207 208 /** 209 * @see com.vaadin.v7.data.Property.ValueChangeNotifier#addListener(com.vaadin.v7.data.Property.ValueChangeListener) 210 */ 211 @SuppressWarnings({"deprecation", "javadoc"}) 212 public void addListener(com.vaadin.v7.data.Property.ValueChangeListener listener) { 213 214 m_principalName.addListener(listener); 215 } 216 217 /** 218 * @see com.vaadin.data.Validatable#addValidator(com.vaadin.data.Validator) 219 */ 220 public void addValidator(Validator validator) { 221 222 m_principalName.addValidator(validator); 223 } 224 225 /** 226 * @see com.vaadin.v7.data.Property.ValueChangeNotifier#addValueChangeListener(com.vaadin.v7.data.Property.ValueChangeListener) 227 */ 228 public void addValueChangeListener(com.vaadin.v7.data.Property.ValueChangeListener listener) { 229 230 m_principalName.addValueChangeListener(listener); 231 } 232 233 /** 234 * @see com.vaadin.v7.ui.Field#clear() 235 */ 236 public void clear() { 237 238 m_principalName.clear(); 239 } 240 241 /** 242 * @see com.vaadin.v7.data.Buffered#commit() 243 */ 244 public void commit() throws SourceException, InvalidValueException { 245 246 m_principalName.commit(); 247 } 248 249 /** 250 * @see com.vaadin.v7.data.Buffered#discard() 251 */ 252 public void discard() throws SourceException { 253 254 m_principalName.discard(); 255 } 256 257 /** 258 * @see com.vaadin.ui.AbstractComponent#focus() 259 */ 260 @Override 261 public void focus() { 262 263 m_principalName.focus(); 264 } 265 266 /** 267 * @see com.vaadin.v7.data.Property.Viewer#getPropertyDataSource() 268 */ 269 public Property getPropertyDataSource() { 270 271 return m_principalName.getPropertyDataSource(); 272 } 273 274 /** 275 * @see com.vaadin.v7.ui.Field#getRequiredError() 276 */ 277 public String getRequiredError() { 278 279 return m_principalName.getRequiredError(); 280 } 281 282 /** 283 * @see com.vaadin.ui.Component.Focusable#getTabIndex() 284 */ 285 public int getTabIndex() { 286 287 return m_principalName.getTabIndex(); 288 } 289 290 /** 291 * @see com.vaadin.v7.data.Property#getType() 292 */ 293 public Class<? extends String> getType() { 294 295 return m_principalName.getType(); 296 } 297 298 /** 299 * @see com.vaadin.data.Validatable#getValidators() 300 */ 301 public Collection<Validator> getValidators() { 302 303 return m_principalName.getValidators(); 304 } 305 306 /** 307 * @see com.vaadin.v7.data.Property#getValue() 308 */ 309 public String getValue() { 310 311 return m_principalName.getValue(); 312 } 313 314 /** 315 * @see org.opencms.ui.dialogs.permissions.I_CmsPrincipalSelect#handlePrincipal(org.opencms.security.I_CmsPrincipal) 316 */ 317 public void handlePrincipal(I_CmsPrincipal principal) { 318 319 if ((principal != null) && !Objects.equals(CmsPrincipal.getType(principal), m_principalTypeSelect.getValue())) { 320 m_principalTypeSelect.setValue(CmsPrincipal.getType(principal)); 321 } 322 setValue(principal.getName()); 323 324 } 325 326 /** 327 * @see com.vaadin.v7.data.Buffered#isBuffered() 328 */ 329 public boolean isBuffered() { 330 331 return m_principalName.isBuffered(); 332 } 333 334 /** 335 * @see com.vaadin.v7.ui.Field#isEmpty() 336 */ 337 public boolean isEmpty() { 338 339 return m_principalName.isEmpty(); 340 } 341 342 /** 343 * @see com.vaadin.data.Validatable#isInvalidAllowed() 344 */ 345 public boolean isInvalidAllowed() { 346 347 return m_principalName.isInvalidAllowed(); 348 } 349 350 /** 351 * @see com.vaadin.v7.data.BufferedValidatable#isInvalidCommitted() 352 */ 353 public boolean isInvalidCommitted() { 354 355 return m_principalName.isInvalidCommitted(); 356 } 357 358 /** 359 * @see com.vaadin.v7.data.Buffered#isModified() 360 */ 361 public boolean isModified() { 362 363 return m_principalName.isModified(); 364 } 365 366 public boolean isReadOnly() { 367 368 return super.isReadOnly(); 369 } 370 371 /** 372 * @see com.vaadin.v7.ui.Field#isRequired() 373 */ 374 public boolean isRequired() { 375 376 return m_principalName.isRequired(); 377 } 378 379 /** 380 * @see com.vaadin.data.Validatable#isValid() 381 */ 382 public boolean isValid() { 383 384 return m_principalName.isValid(); 385 } 386 387 /** 388 * @see com.vaadin.data.Validatable#removeAllValidators() 389 */ 390 public void removeAllValidators() { 391 392 m_principalName.removeAllValidators(); 393 } 394 395 /** 396 * @see com.vaadin.v7.data.Property.ValueChangeNotifier#removeListener(com.vaadin.v7.data.Property.ValueChangeListener) 397 */ 398 @SuppressWarnings({"deprecation", "javadoc"}) 399 public void removeListener(com.vaadin.v7.data.Property.ValueChangeListener listener) { 400 401 m_principalName.removeListener(listener); 402 } 403 404 /** 405 * @see com.vaadin.data.Validatable#removeValidator(com.vaadin.data.Validator) 406 */ 407 public void removeValidator(Validator validator) { 408 409 m_principalName.removeValidator(validator); 410 } 411 412 /** 413 * @see com.vaadin.v7.data.Property.ValueChangeNotifier#removeValueChangeListener(com.vaadin.v7.data.Property.ValueChangeListener) 414 */ 415 public void removeValueChangeListener(com.vaadin.v7.data.Property.ValueChangeListener listener) { 416 417 m_principalName.removeValueChangeListener(listener); 418 } 419 420 /** 421 * @see com.vaadin.v7.data.Buffered#setBuffered(boolean) 422 */ 423 public void setBuffered(boolean buffered) { 424 425 m_principalName.setBuffered(buffered); 426 } 427 428 /** 429 * Set if web Ous should be included. Default behavior is true.<p> 430 * 431 * @param include boolean 432 */ 433 public void setIncludeWebOus(boolean include) { 434 435 m_includeWebOus = include; 436 } 437 438 /** 439 * @see com.vaadin.data.Validatable#setInvalidAllowed(boolean) 440 */ 441 public void setInvalidAllowed(boolean invalidValueAllowed) throws UnsupportedOperationException { 442 443 m_principalName.setInvalidAllowed(invalidValueAllowed); 444 } 445 446 /** 447 * @see com.vaadin.data.BufferedValidatable#setInvalidCommitted(boolean) 448 */ 449 public void setInvalidCommitted(boolean isCommitted) { 450 451 m_principalName.setInvalidCommitted(isCommitted); 452 } 453 454 /** 455 * Enable layout margins. Affects all four sides of the layout. 456 * This will tell the client-side implementation to leave extra space around the layout. 457 * The client-side implementation decides the actual amount, and it can vary between themes.<p> 458 * 459 * @param enabled <code>true</code> if margins should be enabled on all sides, false to disable all margins 460 */ 461 public void setMargin(boolean enabled) { 462 463 ((HorizontalLayout)getCompositionRoot()).setMargin(enabled); 464 } 465 466 /** 467 * Set the ou. 468 * 469 * @param ou to choose principals for 470 */ 471 public void setOU(String ou) { 472 473 m_ou = ou; 474 } 475 476 public void setOuChangeEnabled(boolean enabled) { 477 478 m_ouChangeEnabled = enabled; 479 } 480 481 /** 482 * Sets the principal type and clears the name.<p> 483 * 484 * @param type the principal type 485 */ 486 public void setPrincipalType(String type) { 487 488 m_principalTypeSelect.setValue(type); 489 } 490 491 /** 492 * @see com.vaadin.v7.data.Property.Viewer#setPropertyDataSource(com.vaadin.v7.data.Property) 493 */ 494 public void setPropertyDataSource(Property newDataSource) { 495 496 m_principalName.setPropertyDataSource(newDataSource); 497 } 498 499 public void setReadOnly(boolean readOnly) { 500 501 super.setReadOnly(readOnly); 502 } 503 504 /** 505 * Controls whether only real users/groups or also pseudo-principals like ALL_OTHERS should be shown. 506 * 507 * @param realOnly if true, only real users / groups will be shown 508 */ 509 public void setRealPrincipalsOnly(boolean realOnly) { 510 511 m_realOnly = realOnly; 512 } 513 514 /** 515 * @see com.vaadin.v7.ui.Field#setRequired(boolean) 516 */ 517 public void setRequired(boolean required) { 518 519 m_principalName.setRequired(required); 520 } 521 522 /** 523 * @see com.vaadin.v7.ui.Field#setRequiredError(java.lang.String) 524 */ 525 public void setRequiredError(String requiredMessage) { 526 527 m_principalName.setRequiredError(requiredMessage); 528 } 529 530 /** 531 * Enables/disables selection of the 'Roles' prinipal type.<p> 532 * 533 * @param editRoles true if the user should be allowed to select roles 534 */ 535 public void setRoleSelectionAllowed(boolean editRoles) { 536 537 m_principalTypeSelect.removeItem(CmsRole.PRINCIPAL_ROLE); 538 if (editRoles) { 539 Item item = m_principalTypeSelect.addItem(CmsRole.PRINCIPAL_ROLE); 540 String roleText = CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_LABEL_ROLE_0); 541 item.getItemProperty(CmsVaadinUtils.PROPERTY_LABEL).setValue(roleText); 542 } 543 m_roleSelectionAllowed = editRoles; 544 m_principalTypeSelect.setNewItemsAllowed(!editRoles); 545 546 } 547 548 /** 549 * Sets the principal select handler.<p> 550 * 551 * @param selectHandler the principal select handler 552 */ 553 public void setSelectHandler(I_PrincipalSelectHandler selectHandler) { 554 555 m_selectHandler = selectHandler; 556 enableSetButton(m_selectHandler != null); 557 } 558 559 /** 560 * @see com.vaadin.ui.Component.Focusable#setTabIndex(int) 561 */ 562 public void setTabIndex(int tabIndex) { 563 564 m_principalName.setTabIndex(tabIndex); 565 } 566 567 /** 568 * @see com.vaadin.v7.data.Property#setValue(java.lang.Object) 569 */ 570 public void setValue(String newValue) throws com.vaadin.v7.data.Property.ReadOnlyException { 571 572 m_principalName.setValue(newValue); 573 } 574 575 /** 576 * Sets the widget type.<p> 577 * 578 * @param type the widget type 579 */ 580 public void setWidgetType(WidgetType type) { 581 582 m_widgetType = type; 583 m_principalTypeSelect.setVisible(m_widgetType.equals(WidgetType.principalwidget)); 584 m_principalTypeSelect.setValue( 585 m_widgetType.equals(WidgetType.groupwidget) 586 ? I_CmsPrincipal.PRINCIPAL_GROUP 587 : I_CmsPrincipal.PRINCIPAL_USER); 588 } 589 590 /** 591 * @see com.vaadin.data.Validatable#validate() 592 */ 593 public void validate() throws InvalidValueException { 594 595 m_principalName.validate(); 596 } 597 598 /** 599 * @see com.vaadin.v7.data.Property.ValueChangeListener#valueChange(com.vaadin.v7.data.Property.ValueChangeEvent) 600 */ 601 public void valueChange(com.vaadin.v7.data.Property.ValueChangeEvent event) { 602 603 m_principalName.valueChange(event); 604 } 605 606 /** 607 * Closes the principal select dialog window if present.<p> 608 */ 609 protected void closeWindow() { 610 611 if (m_window != null) { 612 m_window.close(); 613 m_window = null; 614 } 615 } 616 617 /** 618 * Sets the principal type and name.<p> 619 * 620 * @param type the principal type 621 * @param principalName the principal name 622 */ 623 protected void setPrincipal(int type, String principalName) { 624 625 m_principalName.setValue(principalName); 626 627 String typeName = null; 628 switch (type) { 629 case 0: 630 typeName = I_CmsPrincipal.PRINCIPAL_GROUP; 631 break; 632 case 1: 633 default: 634 typeName = I_CmsPrincipal.PRINCIPAL_USER; 635 break; 636 } 637 if (typeName != null) { 638 m_principalTypeSelect.setValue(typeName); 639 } 640 } 641 642 /** 643 * Calls the principal select handler.<p> 644 */ 645 void onSelect() { 646 647 if (m_selectHandler != null) { 648 String principalType = (String)m_principalTypeSelect.getValue(); 649 if (CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_LABEL_ROLE_0).equals( 650 principalType)) { 651 principalType = CmsRole.PRINCIPAL_ROLE; 652 } 653 m_selectHandler.onPrincipalSelect(principalType, m_principalName.getValue()); 654 } 655 } 656 657 /** 658 * Opens the principal select dialog window.<p> 659 */ 660 void openPrincipalSelect() { 661 662 CmsPrincipalSelectDialog dialog; 663 664 m_window = CmsBasicDialog.prepareWindow(DialogWidth.max); 665 CmsPrincipalSelect.PrincipalType defaultType = CmsPrincipalSelect.PrincipalType.group; 666 if (m_principalTypeSelect.getValue().equals(I_CmsPrincipal.PRINCIPAL_USER)) { 667 defaultType = CmsPrincipalSelect.PrincipalType.user; 668 } else if (m_principalTypeSelect.getValue().equals(CmsRole.PRINCIPAL_ROLE)) { 669 defaultType = CmsPrincipalSelect.PrincipalType.role; 670 } 671 672 dialog = new CmsPrincipalSelectDialog( 673 this, 674 m_ou == null ? A_CmsUI.getCmsObject().getRequestContext().getOuFqn() : m_ou, 675 m_window, 676 m_widgetType, 677 m_realOnly, 678 defaultType, 679 m_includeWebOus, 680 m_roleSelectionAllowed); 681 682 dialog.setOuComboBoxEnabled(m_ouChangeEnabled); 683 684 m_window.setCaption( 685 CmsVaadinUtils.getMessageText( 686 org.opencms.workplace.commons.Messages.GUI_PRINCIPALSELECTION_LIST_ACTION_SELECT_NAME_0)); 687 m_window.setContent(dialog); 688 A_CmsUI.get().addWindow(m_window); 689 } 690 691 /** 692 * Sets the add permission button enabled.<p> 693 * 694 * @param enabled <code>true</code> to enable the button 695 */ 696 private void enableSetButton(boolean enabled) { 697 698 if (enabled) { 699 if (m_addPermissionSetButton == null) { 700 m_addPermissionSetButton = new Button(FontAwesome.PLUS); 701 m_addPermissionSetButton.addStyleName(OpenCmsTheme.BUTTON_ICON); 702 m_addPermissionSetButton.addClickListener(new ClickListener() { 703 704 private static final long serialVersionUID = 1L; 705 706 public void buttonClick(ClickEvent event) { 707 708 onSelect(); 709 } 710 }); 711 m_main.addComponent(m_addPermissionSetButton); 712 } 713 } else if (m_addPermissionSetButton != null) { 714 m_main.removeComponent(m_addPermissionSetButton); 715 m_addPermissionSetButton = null; 716 } 717 } 718}