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.apps.user; 029 030import org.opencms.file.CmsGroup; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsUser; 033import org.opencms.main.CmsException; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.security.CmsAccessControlEntry; 037import org.opencms.security.CmsOrganizationalUnit; 038import org.opencms.security.CmsPrincipal; 039import org.opencms.security.CmsRole; 040import org.opencms.security.CmsRoleViolationException; 041import org.opencms.security.I_CmsPrincipal; 042import org.opencms.ui.A_CmsUI; 043import org.opencms.ui.CmsCssIcon; 044import org.opencms.ui.CmsUserIconHelper; 045import org.opencms.ui.CmsVaadinUtils; 046import org.opencms.ui.FontOpenCms; 047import org.opencms.ui.apps.A_CmsWorkplaceApp; 048import org.opencms.ui.apps.CmsAppWorkplaceUi; 049import org.opencms.ui.apps.CmsFileExplorer; 050import org.opencms.ui.apps.I_CmsAppUIContext; 051import org.opencms.ui.apps.Messages; 052import org.opencms.ui.apps.user.CmsGroupTable.TableProperty; 053import org.opencms.ui.components.CmsBasicDialog; 054import org.opencms.ui.components.CmsBasicDialog.DialogWidth; 055import org.opencms.ui.components.CmsInfoButton; 056import org.opencms.ui.components.CmsResourceInfo; 057import org.opencms.ui.components.CmsToolBar; 058import org.opencms.ui.components.OpenCmsTheme; 059import org.opencms.ui.dialogs.permissions.CmsPrincipalSelect.WidgetType; 060import org.opencms.ui.dialogs.permissions.CmsPrincipalSelectDialog; 061import org.opencms.ui.dialogs.permissions.I_CmsPrincipalSelect; 062import org.opencms.util.CmsStringUtil; 063import org.opencms.util.CmsUUID; 064 065import java.util.ArrayList; 066import java.util.Collections; 067import java.util.LinkedHashMap; 068import java.util.List; 069import java.util.Map; 070import java.util.Set; 071import java.util.function.Function; 072 073import org.apache.commons.logging.Log; 074 075import com.vaadin.server.ExternalResource; 076import com.vaadin.server.FontAwesome; 077import com.vaadin.server.Sizeable.Unit; 078import com.vaadin.ui.Button; 079import com.vaadin.ui.Button.ClickEvent; 080import com.vaadin.ui.Button.ClickListener; 081import com.vaadin.ui.Component; 082import com.vaadin.ui.HorizontalSplitPanel; 083import com.vaadin.ui.UI; 084import com.vaadin.ui.Window; 085import com.vaadin.ui.themes.ValoTheme; 086import com.vaadin.v7.data.Item; 087import com.vaadin.v7.data.Property.ValueChangeEvent; 088import com.vaadin.v7.data.Property.ValueChangeListener; 089import com.vaadin.v7.data.util.IndexedContainer; 090import com.vaadin.v7.event.FieldEvents.TextChangeEvent; 091import com.vaadin.v7.event.FieldEvents.TextChangeListener; 092import com.vaadin.v7.ui.ComboBox; 093import com.vaadin.v7.ui.Label; 094import com.vaadin.v7.ui.Table; 095import com.vaadin.v7.ui.TextField; 096import com.vaadin.v7.ui.VerticalLayout; 097 098/** 099 * App for the OU Management.<p> 100 */ 101public class CmsAccountsApp extends A_CmsWorkplaceApp implements I_CmsPrincipalSelect { 102 103 /** 104 * Bean for the state of the app.<p> 105 */ 106 class CmsStateBean { 107 108 /**the filter for tables. */ 109 private String m_filter; 110 111 /**Group id to be opended (or null). */ 112 private CmsUUID m_groupID; 113 114 /**ou path. */ 115 private String m_path = ""; 116 117 /**type of element to be openend. */ 118 private I_CmsOuTreeType m_type; 119 120 /** 121 * public constructor.<p> 122 * 123 * @param path ou path 124 * @param type type to be opened 125 * @param groupID groupid 126 * @param filter filter string 127 */ 128 public CmsStateBean(String path, I_CmsOuTreeType type, CmsUUID groupID, String filter) { 129 130 m_path = path.equals("/") ? "" : path; 131 m_type = type; 132 m_groupID = groupID; 133 m_filter = filter; 134 } 135 136 /** 137 * Gets group id.<p> 138 * 139 * @return group id 140 */ 141 public CmsUUID getGroupID() { 142 143 return m_groupID; 144 } 145 146 /** 147 * Gets the ou path.<p> 148 * 149 * @return ou path 150 */ 151 public String getPath() { 152 153 return m_path; 154 } 155 156 /** 157 * Gets the state string of the current bean.<p> 158 * 159 * @return state string 160 */ 161 public String getState() { 162 163 String typeString = m_type.getId(); 164 String groupString = ""; 165 if (m_groupID != null) { 166 groupString = m_groupID.getStringValue(); 167 } 168 return typeString + STATE_SEPERATOR + m_path + STATE_SEPERATOR + groupString + STATE_SEPERATOR + m_filter; 169 170 } 171 172 /** 173 * Gets the filter string for the table.<p> 174 * 175 * @return the table filter 176 */ 177 public String getTableFilter() { 178 179 return m_filter; 180 } 181 182 /** 183 * Gets type of element to open.<p> 184 * 185 * @return type of element 186 */ 187 public I_CmsOuTreeType getType() { 188 189 return m_type; 190 } 191 } 192 193 /**State seperator. */ 194 public static String STATE_SEPERATOR = "!!"; 195 196 /** Default tree type provider. */ 197 private static final CmsDefaultTreeTypeProvider DEFAULT_TREETYPES = new CmsDefaultTreeTypeProvider(); 198 199 /** The log object for this class. */ 200 private static final Log LOG = CmsLog.getLog(CmsAccountsApp.class); 201 202 /**Button to add an element. */ 203 protected Button m_addElementButton; 204 205 /**CmsObject. */ 206 protected CmsObject m_cms; 207 208 /**vaadin component. */ 209 protected CmsInfoButton m_infoButton; 210 211 /**vaadin component.*/ 212 protected Button m_newButton; 213 214 /**vaadin component.*/ 215 protected Button m_toggleButtonGroups; 216 217 /**vaadin component.*/ 218 protected Button m_toggleButtonRole; 219 220 /**vaadin component.*/ 221 protected Button m_toggleButtonUser; 222 223 /**Don't handle change event flag.*/ 224 boolean m_doNotChange; 225 226 /**State bean. */ 227 CmsStateBean m_stateBean; 228 229 /**Base ou. */ 230 private String m_baseOU = ""; 231 232 /**vaadin component.*/ 233 private ComboBox m_filter; 234 235 /** The file table filter input. */ 236 private TextField m_filterTable; 237 238 /**Class to handle visible and managable ous. */ 239 private CmsOUHandler m_ouHandler; 240 241 /** The folder tree. */ 242 private CmsOuTree m_ouTree; 243 244 /**vaadin component.*/ 245 private HorizontalSplitPanel m_splitScreen; 246 247 /**vaadin component.*/ 248 private I_CmsFilterableTable m_table; 249 250 /** 251 * constructor.<p> 252 */ 253 public CmsAccountsApp() { 254 255 super(); 256 try { 257 m_cms = OpenCms.initCmsObject(A_CmsUI.getCmsObject()); 258 m_cms.getRequestContext().setSiteRoot(""); 259 m_ouHandler = new CmsOUHandler(m_cms); 260 m_baseOU = m_ouHandler.getBaseOU(); 261 262 } catch ( 263 264 CmsException e) { 265 //} 266 } 267 m_rootLayout.setMainHeightFull(true); 268 m_splitScreen = new HorizontalSplitPanel(); 269 m_splitScreen.setSizeFull(); 270 m_splitScreen.setSplitPosition(CmsFileExplorer.LAYOUT_SPLIT_POSITION, Unit.PIXELS); 271 m_rootLayout.setMainContent(m_splitScreen); 272 m_ouTree = new CmsOuTree(m_cms, this, m_baseOU); 273 m_splitScreen.setFirstComponent(m_ouTree); 274 275 } 276 277 /** 278 * Creates info panel for OUs.<p> 279 * 280 * 281 * @param ou to get panel for 282 * @return CmsResourceInfo 283 */ 284 public static CmsResourceInfo getOUInfo(CmsOrganizationalUnit ou) { 285 286 String style = OpenCmsTheme.ICON_OU; 287 if (ou.hasFlagWebuser()) { 288 style = OpenCmsTheme.ICON_OU_WEB; 289 } 290 CmsCssIcon image = new CmsCssIcon(style); 291 return new CmsResourceInfo( 292 ou.getDisplayName(A_CmsUI.get().getLocale()), 293 ou.getDescription(A_CmsUI.get().getLocale()), 294 image); 295 } 296 297 /** 298 * Creates info panel for principals.<p> 299 * 300 * @param principal to get info panel for 301 * @return CmsResourceInfo 302 */ 303 public static CmsResourceInfo getPrincipalInfo(I_CmsPrincipal principal) { 304 305 if (principal == null) { 306 return null; 307 } 308 if (principal instanceof CmsUser) { 309 CmsUser user = (CmsUser)principal; 310 CmsUserIconHelper helper = OpenCms.getWorkplaceAppManager().getUserIconHelper(); 311 return new CmsResourceInfo( 312 user.getName(), 313 user.getEmail(), 314 new ExternalResource(helper.getTinyIconPath(A_CmsUI.getCmsObject(), user))); 315 } 316 if (principal.getId().equals(CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID)) { 317 return new CmsResourceInfo( 318 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_LABEL_ALLOTHERS_0), 319 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_DESCRIPTION_ALLOTHERS_0), 320 new CmsCssIcon(OpenCmsTheme.ICON_PRINCIPAL_ALL)); 321 } 322 if (principal.getId().equals(CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID)) { 323 return new CmsResourceInfo( 324 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_LABEL_OVERWRITEALL_0), 325 CmsVaadinUtils.getMessageText(org.opencms.workplace.commons.Messages.GUI_DESCRIPTION_OVERWRITEALL_0), 326 new CmsCssIcon(OpenCmsTheme.ICON_PRINCIPAL_OVERWRITE)); 327 } 328 CmsRole role = CmsRole.valueOfId(principal.getId()); 329 if (role != null) { 330 return new CmsResourceInfo( 331 role.getName(A_CmsUI.get().getLocale()), 332 role.getDescription(A_CmsUI.get().getLocale()), 333 new CmsCssIcon(OpenCmsTheme.ICON_ROLE)); 334 } 335 return new CmsResourceInfo( 336 principal.getName(), 337 principal.getDescription(A_CmsUI.get().getLocale()), 338 new CmsCssIcon(OpenCmsTheme.ICON_GROUP)); 339 } 340 341 /** 342 * Adds additional properties for groups to a container. 343 * 344 * @param container the container to update 345 */ 346 public void addGroupContainerProperties(IndexedContainer container) { 347 348 // do nothing 349 350 } 351 352 /** 353 * Adds additional properties for users to a container. 354 * 355 * @param container the container to update 356 */ 357 public void addUserContainerProperties(IndexedContainer container) { 358 359 // do nothing 360 361 } 362 363 /** 364 * Checks if the given user is editable.<p> 365 * 366 * @param id the id of the user 367 * @return true if the user is editable 368 */ 369 public boolean canEditUser(CmsUUID id) { 370 371 return true; 372 } 373 374 /** 375 * Checks if group members can be removed from the given OU.<p> 376 * 377 * @param group the group name 378 * @return true if group members can be removed from the given OU 379 */ 380 public boolean canRemoveGroupMemebers(String group) { 381 382 return true; 383 } 384 385 /** 386 * Checks if a set of groups can be added to a user.<p> 387 * 388 * @param principal the user 389 * @param data the set of names of groups to check 390 * 391 * @return true if the groups can be added to the user 392 */ 393 public boolean checkAddGroup(CmsUser principal, Set<String> data) { 394 395 return true; 396 } 397 398 /** 399 * Checks if a user can be removed from a set of groups.<p> 400 * 401 * @param principal the user 402 * @param items the names of groups to check 403 * 404 * @return true if the user can be removed from the group 405 */ 406 public boolean checkRemoveGroups(CmsUser principal, Set<String> items) { 407 408 return true; 409 } 410 411 /** 412 * Fills the container item representing a group.<p> 413 * 414 * @param item the item 415 * @param group the group 416 * @param indirects the indirect groups 417 */ 418 public void fillGroupItem(Item item, CmsGroup group, List<CmsGroup> indirects) { 419 420 item.getItemProperty(TableProperty.Name).setValue(group.getName()); 421 item.getItemProperty(TableProperty.Description).setValue(group.getDescription(A_CmsUI.get().getLocale())); 422 item.getItemProperty(TableProperty.OU).setValue(group.getOuFqn()); 423 if (indirects.contains(group)) { 424 item.getItemProperty(TableProperty.INDIRECT).setValue(Boolean.TRUE); 425 } 426 } 427 428 /** 429 * Gets the app id.<p> 430 * 431 * @return the app id 432 */ 433 public String getAppId() { 434 435 return CmsAccountsAppConfiguration.APP_ID; 436 } 437 438 /** 439 * Gets a data container for the groups available to be added to a user, excluding some groups.<p> 440 * 441 * @param cms the current CMS context 442 * @param ouFqn the OU for which to get the groups 443 * @param propCaption the property for the caption 444 * @param propIcon the property for the icon 445 * @param propOu the property for the OU 446 * @param groupsOfUser the groups to exclude 447 * @param iconProvider the icon provider 448 * 449 * @return the container with the group data 450 */ 451 public IndexedContainer getAvailableGroupsContainerWithout( 452 CmsObject cms, 453 String ouFqn, 454 String propCaption, 455 String propIcon, 456 String propOu, 457 List<CmsGroup> groupsOfUser, 458 Function<CmsGroup, CmsCssIcon> iconProvider) { 459 460 // TODO Auto-generated method stub 461 return CmsVaadinUtils.getAvailableGroupsContainerWithout( 462 cms, 463 ouFqn, 464 propCaption, 465 propIcon, 466 propOu, 467 groupsOfUser, 468 iconProvider); 469 } 470 471 /** 472 * Gets the group edit parameters for a given group.<p> 473 * 474 * @param group a group 475 * 476 * @return the group edit parameters for the group 477 */ 478 public CmsGroupEditParameters getGroupEditParameters(CmsGroup group) { 479 480 CmsGroupEditParameters params = new CmsGroupEditParameters(); 481 return params; 482 } 483 484 /** 485 * Gets the icon for a group.<p> 486 * 487 * @param group the group 488 * @return the icon for the group 489 */ 490 public CmsCssIcon getGroupIcon(CmsGroup group) { 491 492 return new CmsCssIcon("oc-icon-24-group"); 493 } 494 495 /** 496 * Gets the user edit parameters.<p> 497 * 498 * @param user the user 499 * @return the user edit parameters 500 */ 501 public CmsUserEditParameters getUserEditParameters(CmsUser user) { 502 503 CmsUserEditParameters params = new CmsUserEditParameters(); 504 params.setEditEnabled(true); 505 params.setPasswordChangeEnabled(true); 506 return params; 507 } 508 509 /** 510 * Gets the container for the groups of an user for the purpose of editing them.<p> 511 * 512 * @param user the user 513 * @param propName the property for the name 514 * @param propIcon the property for the icon 515 * @param propStatus the property for the status 516 * 517 * @return the container with the user groups 518 */ 519 public IndexedContainer getUserGroupsEditorContainer( 520 CmsUser user, 521 String propName, 522 String propIcon, 523 String propStatus) { 524 525 IndexedContainer container = new IndexedContainer(); 526 container.addContainerProperty(propName, String.class, ""); 527 container.addContainerProperty(CmsUserEditGroupsDialog.ID_OU, String.class, ""); 528 container.addContainerProperty(propStatus, Boolean.class, new Boolean(true)); 529 container.addContainerProperty(propIcon, CmsCssIcon.class, new CmsCssIcon("oc-icon-group-24")); 530 try { 531 for (CmsGroup group : m_cms.getGroupsOfUser(user.getName(), true)) { 532 Item item = container.addItem(group); 533 item.getItemProperty(propName).setValue(group.getSimpleName()); 534 item.getItemProperty(CmsUserEditGroupsDialog.ID_OU).setValue(group.getOuFqn()); 535 item.getItemProperty(propIcon).setValue(getGroupIcon(group)); 536 } 537 } catch (CmsException e) { 538 LOG.error("Unable to read groups from user", e); 539 } 540 return container; 541 } 542 543 /** 544 * Gets list of users for organizational unit.<p> 545 * 546 * @param cms the CMS context 547 * @param ou the OU path 548 * @param recursive true if users from other OUs should be retrieved 549 * 550 * @return the list of users, without their additional info 551 * 552 * @throws CmsException if something goes wrong 553 */ 554 public List<CmsUser> getUsersWithoutAdditionalInfo( 555 CmsObject cms, 556 I_CmsOuTreeType type, 557 String ou, 558 boolean recursive) 559 throws CmsException { 560 561 return CmsPrincipal.filterCoreUsers( 562 OpenCms.getOrgUnitManager().getUsersWithoutAdditionalInfo(cms, ou, recursive)); 563 } 564 565 /** 566 * @see org.opencms.ui.dialogs.permissions.I_CmsPrincipalSelect#handlePrincipal(org.opencms.security.I_CmsPrincipal) 567 */ 568 public void handlePrincipal(I_CmsPrincipal principal) { 569 570 if (m_stateBean.getType().isGroup()) { 571 try { 572 CmsGroup group = m_cms.readGroup(m_stateBean.getGroupID()); 573 m_cms.addUserToGroup(principal.getName(), group.getName()); 574 575 } catch (CmsException e) { 576 return; 577 } 578 } 579 if (m_stateBean.getType().isRole()) { 580 try { 581 OpenCms.getRoleManager().addUserToRole( 582 m_cms, 583 CmsRole.valueOfId(m_stateBean.getGroupID()).forOrgUnit(m_stateBean.getPath()), 584 principal.getName()); 585 } catch (CmsException e) { 586 return; 587 } 588 } 589 A_CmsUI.get().reload(); 590 } 591 592 /** 593 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#initUI(org.opencms.ui.apps.I_CmsAppUIContext) 594 */ 595 @Override 596 public void initUI(I_CmsAppUIContext context) { 597 598 context.addPublishButton(changed -> {/* do nothing*/}); 599 super.initUI(context); 600 } 601 602 /** 603 * Checks if the given OU is manageable.<p> 604 * 605 * @param ou to check 606 * @return true if user is allowed to manage ou 607 */ 608 public boolean isOUManagable(String ou) { 609 610 return m_ouHandler.isOUManagable(ou); 611 } 612 613 /** 614 * Checks if given ou is parent of a managable ou.<p> 615 * 616 * @param name to check 617 * @return boolean 618 */ 619 public boolean isParentOfManagableOU(String name) { 620 621 return m_ouHandler.isParentOfManagableOU(name); 622 } 623 624 /** 625 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#openSubView(java.lang.String, boolean) 626 */ 627 @Override 628 public void openSubView(String state, boolean updateState) { 629 630 if (updateState) { 631 CmsAppWorkplaceUi.get().changeCurrentAppState(state); 632 } 633 634 Component comp = getComponentForState(state); 635 636 updateInfoButton(); 637 if (comp != null) { 638 VerticalLayout layout = new VerticalLayout(); 639 layout.setSizeFull(); 640 comp.setSizeFull(); 641 layout.addComponent(m_table.getEmptyLayout()); 642 layout.addComponent(m_table); 643 handleSetTable(m_table); 644 m_splitScreen.setSecondComponent(layout); 645 } else { 646 m_splitScreen.setSecondComponent(new Label("Malformed path, tool not available for path: " + state)); 647 handleSetTable(null); 648 } 649 m_splitScreen.setSizeFull(); 650 updateSubNav(getSubNavEntries(state)); 651 updateBreadCrumb(getBreadCrumbForState(state)); 652 } 653 654 /** 655 * Parses a given state string to state bean.<p> 656 * 657 * @param state to be read 658 * @param baseOU baseOu 659 * @return CmsStateBean 660 */ 661 public CmsStateBean parseState(String state, String baseOU) { 662 663 String path = baseOU; 664 String filter = ""; 665 I_CmsOuTreeType type = CmsOuTreeType.OU; 666 CmsUUID groupId = null; 667 List<String> fields = CmsStringUtil.splitAsList(state, STATE_SEPERATOR); 668 if (!fields.isEmpty()) { 669 if (fields.size() > 1) { 670 path = fields.get(1); 671 //Make sure to only show OUs which are under baseOU 672 if (path.equals("") | !path.startsWith(baseOU)) { 673 path = baseOU; 674 } 675 } 676 for (I_CmsOuTreeType ty : getTreeTypeProvider().getTreeTypes()) { 677 if (fields.get(0).equals(ty.getId())) { 678 type = ty; 679 } 680 } 681 if (fields.size() > 2) { 682 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(fields.get(2))) { 683 groupId = new CmsUUID(fields.get(2)); 684 } 685 } 686 if (fields.size() > 3) { 687 filter = fields.get(3); 688 } 689 } 690 return new CmsStateBean(path, type, groupId, filter); 691 } 692 693 /** 694 * Reads the list of groups for an organizational unit.<p> 695 * 696 * @param cms the CMS context 697 * @param ou the OU path 698 * @param type the tree type 699 * @param subOus true if groups for sub-OUs should be read 700 * @return the list of groups for the OU 701 * 702 * @throws CmsException if something goes wrong 703 */ 704 public List<CmsGroup> readGroupsForOu(CmsObject cms, String ou, I_CmsOuTreeType type, boolean subOus) 705 throws CmsException { 706 707 return CmsPrincipal.filterCoreGroups(OpenCms.getOrgUnitManager().getGroups(m_cms, ou, subOus)); 708 } 709 710 /** 711 * Reloads the app with current state.<p> 712 */ 713 public void reload() { 714 715 update(m_stateBean.getPath(), m_stateBean.getType(), m_stateBean.getGroupID()); 716 } 717 718 /** 719 * @see org.opencms.ui.dialogs.permissions.I_CmsPrincipalSelect#setType(java.lang.String) 720 */ 721 public void setType(String type) { 722 723 // is never called 724 725 } 726 727 /** 728 * Updates the app state.<p> 729 * 730 * @param ou to be opened 731 * @param type to be opened 732 * @param groupID to be openend(may be null) 733 */ 734 public void update(String ou, I_CmsOuTreeType type, CmsUUID groupID) { 735 736 update(ou, type, groupID, m_filterTable.getValue()); 737 738 } 739 740 /** 741 * Updates the app state.<p> 742 * 743 * @param ou to be opened 744 * @param type to be opened 745 * @param roleOrGroupID to be openend(may be null) 746 * @param filter filter string 747 */ 748 public void update(String ou, I_CmsOuTreeType type, CmsUUID roleOrGroupID, String filter) { 749 750 CmsStateBean stateBean = new CmsStateBean(ou, type, roleOrGroupID, filter); 751 openSubView(stateBean.getState(), true); 752 753 } 754 755 /** 756 * Creates a table for displaying groups.<p> 757 * 758 * @param path the path 759 * @param cmsAccountsApp the app instance 760 * @param type the tree type 761 * @param toggle the value of the 'sub-OU' toggle 762 * 763 * @return the table 764 */ 765 protected I_CmsFilterableTable createGroupTable( 766 String path, 767 CmsAccountsApp cmsAccountsApp, 768 I_CmsOuTreeType type, 769 boolean toggle) { 770 771 return new CmsGroupTable(path, cmsAccountsApp, type, toggle); 772 } 773 774 /** 775 * Creates the overview table for the given OU.<p> 776 * 777 * @param ou the OU path 778 * @return the overview table for the given OU 779 */ 780 protected I_CmsFilterableTable createOUTable(String ou) { 781 782 return new CmsOUTable(ou, this); 783 } 784 785 /** 786 * Creates the role table for the given OU.<p> 787 * 788 * @param ou the OU path 789 * @return the role table for the given OU 790 */ 791 protected I_CmsFilterableTable createRoleTable(String ou) { 792 793 return new CmsRoleTable(this, ou); 794 } 795 796 /** 797 * Creates user table for a specific group or role.<p> 798 * 799 * @param ou the OU path 800 * @param groupID the group id 801 * @param type the tree type 802 * @param showAll true if all users should be shown 803 * @param cmsAccountsApp the app instance 804 * 805 * @return the user table 806 */ 807 protected I_CmsFilterableTable createUserTable( 808 String ou, 809 CmsUUID groupID, 810 I_CmsOuTreeType type, 811 boolean showAll, 812 CmsAccountsApp cmsAccountsApp) { 813 814 return new CmsUserTable(ou, groupID, type, showAll, cmsAccountsApp); 815 } 816 817 /** 818 * Creates the user table for an OU.<p> 819 * 820 * @param ou the OU path 821 * @param type the tree type 822 * @param cmsAccountsApp the app instance 823 * @param buttonPressed true if toggle button for users is active 824 825 * @return the user table 826 */ 827 protected I_CmsFilterableTable createUserTable( 828 String ou, 829 I_CmsOuTreeType type, 830 CmsAccountsApp cmsAccountsApp, 831 boolean buttonPressed) { 832 833 return new CmsUserTable(ou, type, cmsAccountsApp, buttonPressed); 834 } 835 836 /** 837 * Filters table.<p> 838 *" 839 * @param text for filter 840 */ 841 protected void filterTable(String text) { 842 843 if (m_table != null) { 844 m_table.filter(text); 845 } 846 } 847 848 /** 849 * Gets the additional buttons to display.<p> 850 * 851 * @return the additional buttons to display 852 */ 853 protected List<Button> getAdditionalButtons() { 854 855 return new ArrayList<>(); 856 } 857 858 /** 859 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getBreadCrumbForState(java.lang.String) 860 */ 861 @Override 862 protected LinkedHashMap<String, String> getBreadCrumbForState(String state) { 863 864 try { 865 CmsStateBean bean = parseState(state, m_baseOU); 866 String[] ouPath = bean.getPath().split("/"); 867 LinkedHashMap<String, String> crumbs = new LinkedHashMap<String, String>(); 868 869 if ((bean.getPath().equals(m_baseOU)) 870 && (CmsOuTreeType.OU.equals(bean.getType()) | (bean.getType() == null))) { 871 crumbs.put( 872 "", 873 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_TOOL_NAME_0) 874 + " (" 875 + OpenCms.getOrgUnitManager().readOrganizationalUnit(m_cms, m_baseOU).getDisplayName( 876 A_CmsUI.get().getLocale()) 877 + ")"); 878 return crumbs; 879 } 880 CmsStateBean beanCr = new CmsStateBean(m_baseOU, CmsOuTreeType.OU, null, ""); 881 crumbs.put( 882 getAppId() + "/" + beanCr.getState(), 883 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_TOOL_NAME_0) 884 + " (" 885 + OpenCms.getOrgUnitManager().readOrganizationalUnit(m_cms, m_baseOU).getDisplayName( 886 A_CmsUI.get().getLocale()) 887 + ")"); 888 String base = ""; 889 String pathOfLastElement = ""; 890 for (String oP : ouPath) { 891 if (!oP.isEmpty()) { 892 if ((oP + base).length() > m_baseOU.length()) { 893 if (oP.equals(ouPath[ouPath.length - 1])) { 894 CmsStateBean beanCrumb = new CmsStateBean(base + oP, CmsOuTreeType.OU, null, ""); 895 pathOfLastElement = getAppId() + "/" + beanCrumb.getState(); 896 crumbs.put("", oP); 897 } else { 898 CmsStateBean beanCrumb = new CmsStateBean(base + oP, CmsOuTreeType.OU, null, ""); 899 crumbs.put(getAppId() + "/" + beanCrumb.getState(), oP); 900 } 901 } 902 base += oP + "/"; 903 } 904 } 905 if (bean.getType() != null) { 906 if (!bean.getType().equals(CmsOuTreeType.OU)) { 907 if (!pathOfLastElement.isEmpty()) { 908 crumbs.put(pathOfLastElement, crumbs.get("")); 909 crumbs.remove(""); 910 } 911 if (bean.getGroupID() == null) { 912 crumbs.put("", bean.getType().getName()); 913 } else { 914 CmsStateBean beanCrumb = new CmsStateBean(bean.getPath(), bean.getType(), null, ""); 915 crumbs.put(getAppId() + "/" + beanCrumb.getState(), beanCrumb.getType().getName()); 916 if (bean.getType().equals(CmsOuTreeType.ROLE)) { 917 crumbs.put("", CmsRole.valueOfId(bean.getGroupID()).getName(A_CmsUI.get().getLocale())); 918 } else { 919 crumbs.put("", m_cms.readGroup(bean.getGroupID()).getSimpleName()); 920 } 921 } 922 } 923 } 924 return crumbs; 925 } catch (CmsException e) { 926 return null; 927 } 928 } 929 930 /** 931 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getComponentForState(java.lang.String) 932 */ 933 @Override 934 protected Component getComponentForState(String state) { 935 936 m_stateBean = parseState(state, m_baseOU); 937 938 if (m_filter == null) { 939 iniButtons(); 940 } 941 942 m_doNotChange = true; 943 944 m_filter.setValue(m_stateBean.getPath()); 945 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_stateBean.getTableFilter())) { 946 m_filterTable.setValue(m_stateBean.getTableFilter()); 947 } else { 948 m_filterTable.setValue(""); 949 } 950 951 m_newButton.setVisible((m_stateBean.getGroupID() == null) & isOUManagable(m_stateBean.getPath())); 952 m_toggleButtonRole.setVisible(m_stateBean.getType().isRole() && (m_stateBean.getGroupID() != null)); 953 m_toggleButtonUser.setVisible(m_stateBean.getType().isUser()); 954 955 m_toggleButtonGroups.setVisible(m_stateBean.getType().isGroup() && (m_stateBean.getGroupID() == null)); 956 m_infoButton.setVisible( 957 m_stateBean.getType().isUser() 958 || (m_stateBean.getType().isRole() && (m_stateBean.getGroupID() != null)) 959 || (m_stateBean.getType().isGroup() && (m_stateBean.getGroupID() != null))); 960 m_addElementButton.setVisible( 961 (m_stateBean.getType().isGroup() || m_stateBean.getType().isRole()) & (m_stateBean.getGroupID() != null)); 962 m_ouTree.openPath(m_stateBean.getPath(), m_stateBean.getType(), m_stateBean.getGroupID()); 963 964 m_doNotChange = false; 965 I_CmsFilterableTable table = null; 966 if (m_stateBean.getType().equals(CmsOuTreeType.OU)) { 967 m_table = createOUTable(m_stateBean.getPath()); 968 table = m_table; 969 } 970 if (m_stateBean.getType().isUser()) { 971 m_table = createUserTable( 972 m_stateBean.getPath(), 973 m_stateBean.getType(), 974 this, 975 CmsVaadinUtils.isButtonPressed(m_toggleButtonUser)); 976 table = m_table; 977 } 978 if (m_stateBean.getType().isGroup()) { 979 if (m_stateBean.getGroupID() == null) { 980 m_table = createGroupTable( 981 m_stateBean.getPath(), 982 this, 983 m_stateBean.getType(), 984 CmsVaadinUtils.isButtonPressed(m_toggleButtonGroups)); 985 table = m_table; 986 } else { 987 m_table = createUserTable( 988 m_stateBean.getPath(), 989 m_stateBean.getGroupID(), 990 m_stateBean.getType(), 991 false, 992 this); 993 table = m_table; 994 } 995 } 996 if (m_stateBean.getType().isRole()) { 997 if (m_stateBean.getGroupID() == null) { 998 m_table = createRoleTable(m_stateBean.getPath()); 999 table = m_table; 1000 } else { 1001 m_table = createUserTable( 1002 m_stateBean.getPath(), 1003 m_stateBean.getGroupID(), 1004 m_stateBean.getType(), 1005 CmsVaadinUtils.isButtonPressed(m_toggleButtonRole), 1006 this); 1007 table = m_table; 1008 } 1009 } 1010 if ((table != null) && !CmsStringUtil.isEmptyOrWhitespaceOnly(m_filterTable.getValue())) { 1011 table.filter(m_filterTable.getValue()); 1012 } 1013 return table; 1014 } 1015 1016 /** 1017 * Gets the group-, role-, or ou name.<p> 1018 * 1019 * @param stateBean to be read out 1020 * @return Name 1021 */ 1022 protected String getElementName(CmsStateBean stateBean) { 1023 1024 if (stateBean.getType().equals(CmsOuTreeType.USER)) { 1025 try { 1026 return OpenCms.getOrgUnitManager().readOrganizationalUnit(m_cms, stateBean.getPath()).getDisplayName( 1027 A_CmsUI.get().getLocale()); 1028 } catch (CmsException e) { 1029 LOG.error("Unable to read OU", e); 1030 } 1031 } 1032 if (stateBean.getType().equals(CmsOuTreeType.ROLE)) { 1033 return CmsRole.valueOfId(stateBean.getGroupID()).getName(A_CmsUI.get().getLocale()); 1034 } else { 1035 try { 1036 return m_cms.readGroup(stateBean.getGroupID()).getSimpleName(); 1037 } catch (CmsException e) { 1038 LOG.error("Unable to read group", e); 1039 } 1040 } 1041 return ""; 1042 } 1043 1044 /** 1045 * Gets the full user List including additionInfos.<p> 1046 * 1047 * @param users user list 1048 * @return List of user 1049 */ 1050 protected List<CmsUser> getFullUser(List<CmsUser> users) { 1051 1052 List<CmsUser> res = new ArrayList<CmsUser>(); 1053 for (CmsUser user : users) { 1054 try { 1055 res.add(m_cms.readUser(user.getId())); 1056 } catch (CmsException e) { 1057 LOG.error("Unable to read user", e); 1058 } 1059 } 1060 return res; 1061 } 1062 1063 /** 1064 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getSubNavEntries(java.lang.String) 1065 */ 1066 @Override 1067 protected List<NavEntry> getSubNavEntries(String state) { 1068 1069 return null; 1070 } 1071 1072 /** 1073 * Get the current toggle button.<p> 1074 * 1075 * @param stateBean to be read out 1076 * @return Button 1077 */ 1078 protected Button getToggleButton(CmsStateBean stateBean) { 1079 1080 if (stateBean.getType().equals(CmsOuTreeType.USER)) { 1081 return m_toggleButtonUser; 1082 } 1083 if (stateBean.getType().equals(CmsOuTreeType.ROLE)) { 1084 return m_toggleButtonRole; 1085 } else { 1086 return m_toggleButtonGroups; 1087 } 1088 } 1089 1090 /** 1091 * Gets the tree type provider.<p> 1092 * 1093 * @return the tree type provider 1094 */ 1095 protected I_CmsTreeTypeProvider getTreeTypeProvider() { 1096 1097 return DEFAULT_TREETYPES; 1098 } 1099 1100 /** 1101 * Gets all currently visible user.<p> 1102 * 1103 * @return List of CmsUser 1104 */ 1105 protected List<CmsUser> getVisibleUser() { 1106 1107 if (m_table instanceof CmsUserTable) { 1108 return ((CmsUserTable)m_table).getVisibleUser(); 1109 } 1110 return null; 1111 } 1112 1113 /** 1114 * Called when new table is shown.<p> 1115 * 1116 * @param component the table that is displayed 1117 */ 1118 protected void handleSetTable(Component component) { 1119 // do nothing 1120 } 1121 1122 /** 1123 * Opens a dialog for a new item (ou, group or user).<p> 1124 */ 1125 protected void openNewDialog() { 1126 1127 final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide); 1128 CmsBasicDialog dialog = new CmsNewElementDialog(m_cms, m_stateBean.getPath(), window, this); 1129 window.setContent(dialog); 1130 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ADD_ELEMENT_0)); 1131 A_CmsUI.get().addWindow(window); 1132 } 1133 1134 /** 1135 * opens a principle select dialog.<p> 1136 */ 1137 void openAddUserDialog() { 1138 1139 CmsPrincipalSelectDialog dialog; 1140 1141 final Window window = CmsBasicDialog.prepareWindow(DialogWidth.max); 1142 1143 dialog = new CmsPrincipalSelectDialog( 1144 this, 1145 m_stateBean.getPath(), 1146 window, 1147 WidgetType.userwidget, 1148 true, 1149 WidgetType.userwidget); 1150 1151 try { 1152 dialog.setOuComboBoxEnabled( 1153 !OpenCms.getOrgUnitManager().readOrganizationalUnit(m_cms, m_stateBean.getPath()).hasFlagWebuser() 1154 | m_stateBean.getType().equals(CmsOuTreeType.ROLE)); 1155 } catch (CmsException e) { 1156 LOG.error("Can not read OU.", e); 1157 } 1158 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ADD_USER_TO_GROUP_0)); 1159 window.setContent(dialog); 1160 A_CmsUI.get().addWindow(window); 1161 1162 } 1163 1164 /** 1165 * Toggles the table.<p> 1166 * 1167 * @param toggleButton the toggle button state 1168 */ 1169 void toggleTable(Button toggleButton) { 1170 1171 I_CmsToggleTable table = (I_CmsToggleTable)m_table; 1172 table.toggle(!CmsVaadinUtils.isButtonPressed(toggleButton)); 1173 CmsVaadinUtils.toggleButton(toggleButton); 1174 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_filterTable.getValue())) { 1175 filterTable(m_filterTable.getValue()); 1176 } 1177 updateInfoButton(); 1178 } 1179 1180 /** 1181 * Initializes the toolbar buttons.<p> 1182 */ 1183 private void iniButtons() { 1184 1185 m_newButton = CmsToolBar.createButton( 1186 FontOpenCms.WAND, 1187 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ADD_ELEMENT_0)); 1188 m_newButton.addClickListener(new ClickListener() { 1189 1190 private static final long serialVersionUID = 1L; 1191 1192 public void buttonClick(ClickEvent event) { 1193 1194 openNewDialog(); 1195 } 1196 }); 1197 m_infoButton = new CmsInfoButton(); 1198 Button csvButton = new Button(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_EXPORT_ONLY_USER_0)); 1199 csvButton.addClickListener(new ClickListener() { 1200 1201 private static final long serialVersionUID = 5472430305539438757L; 1202 1203 public void buttonClick(ClickEvent event) { 1204 1205 boolean includeTechnicalFields = false; 1206 try { 1207 OpenCms.getRoleManager().checkRole(m_cms, CmsRole.ADMINISTRATOR); 1208 includeTechnicalFields = true; 1209 } catch (CmsRoleViolationException e) { 1210 // ok 1211 } 1212 Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide); 1213 CmsUserCsvExportDialog dialog = new CmsUserCsvExportDialog( 1214 getFullUser(getVisibleUser()), 1215 m_stateBean.getPath(), 1216 m_stateBean.getType(), 1217 getElementName(m_stateBean), 1218 CmsVaadinUtils.isButtonPressed(getToggleButton(m_stateBean)), 1219 window, 1220 includeTechnicalFields); 1221 window.setContent(dialog); 1222 A_CmsUI.get().addWindow(window); 1223 1224 } 1225 1226 }); 1227 m_infoButton.setAdditionalButton(csvButton); 1228 1229 m_addElementButton = CmsToolBar.createButton( 1230 FontAwesome.PLUS, 1231 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ADD_USER_TO_GROUP_0)); 1232 m_addElementButton.addClickListener(new ClickListener() { 1233 1234 private static final long serialVersionUID = 1859694635385726953L; 1235 1236 public void buttonClick(ClickEvent event) { 1237 1238 openAddUserDialog(); 1239 1240 } 1241 }); 1242 1243 m_toggleButtonRole = CmsToolBar.createButton( 1244 FontOpenCms.USERS, 1245 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ROLES_TOGGLE_0)); 1246 m_toggleButtonRole.addClickListener(new ClickListener() { 1247 1248 private static final long serialVersionUID = 8265075332953321274L; 1249 1250 public void buttonClick(ClickEvent event) { 1251 1252 toggleTable(m_toggleButtonRole); 1253 1254 } 1255 1256 }); 1257 1258 m_toggleButtonUser = CmsToolBar.createButton( 1259 FontOpenCms.USERS, 1260 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_USER_TOGGLE_0)); 1261 m_toggleButtonUser.addClickListener(new ClickListener() { 1262 1263 private static final long serialVersionUID = 8265075332953321274L; 1264 1265 public void buttonClick(ClickEvent event) { 1266 1267 toggleTable(m_toggleButtonUser); 1268 1269 } 1270 1271 }); 1272 1273 m_toggleButtonGroups = CmsToolBar.createButton( 1274 FontOpenCms.USERS, 1275 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_GROUPS_TOGGLE_0)); 1276 m_toggleButtonGroups.addClickListener(new ClickListener() { 1277 1278 private static final long serialVersionUID = 8265075332953321274L; 1279 1280 public void buttonClick(ClickEvent event) { 1281 1282 toggleTable(m_toggleButtonGroups); 1283 1284 } 1285 1286 }); 1287 1288 m_uiContext.addToolbarButton(m_newButton); 1289 1290 m_uiContext.addToolbarButton(m_addElementButton); 1291 m_uiContext.addToolbarButton(m_infoButton); 1292 m_uiContext.addToolbarButton(m_toggleButtonRole); 1293 m_uiContext.addToolbarButton(m_toggleButtonUser); 1294 m_uiContext.addToolbarButton(m_toggleButtonGroups); 1295 1296 for (Button button : getAdditionalButtons()) { 1297 m_uiContext.addToolbarButton(button); 1298 } 1299 m_filter = CmsVaadinUtils.getOUComboBox(m_cms, m_baseOU, LOG); 1300 m_filter.setWidth("379px"); 1301 m_infoLayout.addComponent(m_filter, 0); 1302 1303 m_filterTable = new TextField(); 1304 m_filterTable.setIcon(FontOpenCms.FILTER); 1305 m_filterTable.setInputPrompt( 1306 Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_FILTER_0)); 1307 m_filterTable.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON); 1308 // m_filterTable.setWidth("200px"); 1309 m_filterTable.addTextChangeListener(new TextChangeListener() { 1310 1311 private static final long serialVersionUID = 1L; 1312 1313 public void textChange(TextChangeEvent event) { 1314 1315 filterTable(event.getText()); 1316 } 1317 }); 1318 m_filterTable.setWidth("200px"); 1319 m_infoLayout.addComponent(m_filterTable); 1320 m_infoLayout.addStyleName("o-many-elements"); 1321 m_filter.addValueChangeListener(new ValueChangeListener() { 1322 1323 private static final long serialVersionUID = 1L; 1324 1325 public void valueChange(ValueChangeEvent event) { 1326 1327 if ((m_stateBean.getType() != null) & !m_doNotChange) { 1328 update((String)event.getProperty().getValue(), CmsOuTreeType.OU, null); 1329 } else { 1330 // 1331 } 1332 } 1333 }); 1334 if (!m_ouHandler.isOUManagable(m_stateBean.getPath())) { 1335 boolean change = m_doNotChange; 1336 m_doNotChange = false; 1337 m_filter.select(m_filter.getItemIds().iterator().next()); 1338 m_doNotChange = change; 1339 } 1340 } 1341 1342 /** 1343 * Updates the info button.<p> 1344 */ 1345 private void updateInfoButton() { 1346 1347 if (m_stateBean.getType().isUser()) { 1348 Map<String, String> dataMap = new LinkedHashMap<String, String>(); 1349 dataMap.put( 1350 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_COUNT_0), 1351 String.valueOf(((Table)m_table).size())); 1352 try { 1353 int count = getUsersWithoutAdditionalInfo( 1354 m_cms, 1355 m_stateBean.getType(), 1356 m_stateBean.getPath(), 1357 true).size(); 1358 if (count > ((Table)m_table).size()) { 1359 dataMap.put( 1360 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_TOT_COUNT_0), 1361 String.valueOf(count)); 1362 } 1363 } catch (CmsException e) { 1364 //; 1365 } 1366 m_infoButton.replaceData(dataMap); 1367 } else { 1368 int size = ((Table)m_table).size(); 1369 if (m_table instanceof CmsUserTable) { 1370 size = ((CmsUserTable)m_table).getVisibleUser().size(); 1371 } 1372 m_infoButton.replaceData( 1373 Collections.singletonMap( 1374 CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_COUNT_0), 1375 String.valueOf(size))); 1376 } 1377 } 1378 1379}