1
22
23 package com.liferay.portal.convert;
24
25 import com.liferay.counter.service.CounterLocalServiceUtil;
26 import com.liferay.portal.NoSuchResourceActionException;
27 import com.liferay.portal.convert.util.PermissionView;
28 import com.liferay.portal.convert.util.ResourcePermissionView;
29 import com.liferay.portal.kernel.cache.CacheRegistry;
30 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
31 import com.liferay.portal.kernel.dao.orm.QueryUtil;
32 import com.liferay.portal.kernel.log.Log;
33 import com.liferay.portal.kernel.log.LogFactoryUtil;
34 import com.liferay.portal.kernel.util.FileUtil;
35 import com.liferay.portal.kernel.util.StringPool;
36 import com.liferay.portal.kernel.util.StringUtil;
37 import com.liferay.portal.kernel.util.Tuple;
38 import com.liferay.portal.kernel.util.Validator;
39 import com.liferay.portal.model.Group;
40 import com.liferay.portal.model.ResourceAction;
41 import com.liferay.portal.model.ResourceCode;
42 import com.liferay.portal.model.ResourceConstants;
43 import com.liferay.portal.model.ResourcePermission;
44 import com.liferay.portal.model.Role;
45 import com.liferay.portal.model.RoleConstants;
46 import com.liferay.portal.model.impl.PermissionModelImpl;
47 import com.liferay.portal.model.impl.ResourceCodeModelImpl;
48 import com.liferay.portal.model.impl.ResourceModelImpl;
49 import com.liferay.portal.model.impl.ResourcePermissionModelImpl;
50 import com.liferay.portal.model.impl.RoleModelImpl;
51 import com.liferay.portal.security.permission.PermissionCacheUtil;
52 import com.liferay.portal.security.permission.ResourceActionsUtil;
53 import com.liferay.portal.service.ClassNameLocalServiceUtil;
54 import com.liferay.portal.service.GroupLocalServiceUtil;
55 import com.liferay.portal.service.ResourceActionLocalServiceUtil;
56 import com.liferay.portal.service.ResourceCodeLocalServiceUtil;
57 import com.liferay.portal.service.RoleLocalServiceUtil;
58 import com.liferay.portal.service.UserLocalServiceUtil;
59 import com.liferay.portal.service.persistence.BatchSessionUtil;
60 import com.liferay.portal.tools.sql.DBUtil;
61 import com.liferay.portal.upgrade.util.Table;
62 import com.liferay.portal.util.MaintenanceUtil;
63 import com.liferay.portal.util.PortalInstances;
64 import com.liferay.portal.util.PropsKeys;
65 import com.liferay.portal.util.PropsValues;
66
67 import java.io.BufferedReader;
68 import java.io.BufferedWriter;
69 import java.io.FileReader;
70 import java.io.FileWriter;
71
72 import java.sql.Connection;
73 import java.sql.PreparedStatement;
74 import java.sql.ResultSet;
75 import java.sql.Types;
76
77 import java.util.ArrayList;
78 import java.util.Collections;
79 import java.util.HashMap;
80 import java.util.HashSet;
81 import java.util.List;
82 import java.util.Map;
83 import java.util.Set;
84
85 import org.apache.commons.collections.map.MultiValueMap;
86
87
98 public class ConvertPermissionAlgorithm extends ConvertProcess {
99
100 public String getDescription() {
101 return "convert-legacy-permission-algorithm";
102 }
103
104 public boolean isEnabled() {
105 boolean enabled = false;
106
107 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 6) {
108 enabled = true;
109 }
110
111 return enabled;
112 }
113
114 protected void doConvert() throws Exception {
115 try {
116 BatchSessionUtil.setEnabled(true);
117
118 _initialize();
119
120 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 5) {
121 _convertToRBAC();
122 }
123
124 _convertToBitwise();
125
126 MaintenanceUtil.appendStatus(
127 "Please set " + PropsKeys.PERMISSIONS_USER_CHECK_ALGORITHM +
128 " in your portal-ext.properties to use algorithm 6");
129 }
130 catch (Exception e) {
131 _log.fatal(e, e);
132 }
133 finally {
134 CacheRegistry.clear();
135
136 PermissionCacheUtil.clearCache();
137
138 BatchSessionUtil.setEnabled(false);
139 }
140 }
141
142 private void _convertToBitwise() throws Exception {
143
144
146 MaintenanceUtil.appendStatus(
147 "Generating ResourceAction and ResourcePermission data");
148
149 Table table = new Table(
150 ResourceCodeModelImpl.TABLE_NAME,
151 ResourceCodeModelImpl.TABLE_COLUMNS);
152
153 table.setSelectSQL(
154 "SELECT * FROM " + ResourceCodeModelImpl.TABLE_NAME +
155 " GROUP BY name");
156
157 String tempFile = table.generateTempFile();
158
159 BufferedReader resourceNameReader = new BufferedReader(
160 new FileReader(tempFile));
161
162 BufferedWriter resourcePermissionWriter = new BufferedWriter(
163 new FileWriter(tempFile + _EXT_RESOURCE_PERMISSION));
164
165 PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM = 6;
166
167 try {
168 String line = null;
169
170 while (Validator.isNotNull(line = resourceNameReader.readLine())) {
171 String[] values = StringUtil.split(line);
172
173 String name = values[2];
174
175 List<String> defaultActionIds =
176 ResourceActionsUtil.getResourceActions(name);
177
178 ResourceActionLocalServiceUtil.checkResourceActions(
179 name, defaultActionIds);
180
181 _convertResourcePermission(resourcePermissionWriter, name);
182 }
183
184 resourcePermissionWriter.close();
185
186 MaintenanceUtil.appendStatus("Updating ResourcePermission table");
187
188 Table resourcePermissionTable = new Table(
189 ResourcePermissionModelImpl.TABLE_NAME,
190 ResourcePermissionModelImpl.TABLE_COLUMNS);
191
192 resourcePermissionTable.populateTable(
193 tempFile + _EXT_RESOURCE_PERMISSION);
194 }
195 catch (Exception e) {
196 PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM = 5;
197
198 throw e;
199 }
200 finally {
201 resourceNameReader.close();
202
203 resourcePermissionWriter.close();
204
205 FileUtil.delete(tempFile);
206 FileUtil.delete(tempFile + _EXT_RESOURCE_PERMISSION);
207 }
208
209
211 MaintenanceUtil.appendStatus("Cleaning up legacy tables");
212
213 DBUtil dbUtil = DBUtil.getInstance();
214
215 dbUtil.runSQL("DELETE FROM " + ResourceCodeModelImpl.TABLE_NAME);
216 dbUtil.runSQL("DELETE FROM " + PermissionModelImpl.TABLE_NAME);
217 dbUtil.runSQL("DELETE FROM " + ResourceModelImpl.TABLE_NAME);
218 dbUtil.runSQL("DELETE FROM Roles_Permissions");
219
220 MaintenanceUtil.appendStatus("Converted to bitwise permission");
221 }
222
223 private void _convertToRBAC() throws Exception {
224 _initializeRBAC();
225
226
228 _convertPermissions(
229 RoleConstants.TYPE_COMMUNITY, "Groups_Permissions",
230 new String[] {"groupId"}, "Groups_Roles",
231 new Object[][] {
232 {"groupId", Types.BIGINT}, {"roleId", Types.BIGINT}
233 });
234
235
237 _convertPermissions(
238 RoleConstants.TYPE_ORGANIZATION, "OrgGroupPermission",
239 new String[] {"organizationId", "groupId"}, "OrgGroupRole",
240 new Object[][] {
241 {"organizationId", Types.BIGINT}, {"groupId", Types.BIGINT},
242 {"roleId", Types.BIGINT}
243 });
244
245
247 _convertPermissions(
248 RoleConstants.TYPE_REGULAR, "Users_Permissions",
249 new String[] {"userId"}, "Users_Roles",
250 new Object[][] {
251 {"userId", Types.BIGINT}, {"roleId", Types.BIGINT}
252 });
253
254
256 PermissionCacheUtil.clearCache();
257
258 PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM = 5;
259
260 MaintenanceUtil.appendStatus("Converted to RBAC permission");
261 }
262
263 private String _convertGuestUsers(String legacyFile) throws Exception {
264 BufferedReader legacyFileReader = new BufferedReader(
265 new FileReader(legacyFile));
266
267 BufferedWriter legacyFileUpdatedWriter = new BufferedWriter(
268 new FileWriter(legacyFile + _UPDATED));
269 BufferedWriter legacyFileExtRolesPermissionsWriter = new BufferedWriter(
270 new FileWriter(legacyFile + _EXT_ROLES_PERMIMISSIONS));
271
272 try {
273 String line = null;
274
275 while (Validator.isNotNull(line = legacyFileReader.readLine())) {
276 String[] values = StringUtil.split(line);
277
278 long companyId = PermissionView.getCompanyId(values);
279 long permissionId = PermissionView.getPermissionId(values);
280 int scope = PermissionView.getScopeId(values);
281 long userId = PermissionView.getPrimaryKey(values);
282
283 if ((scope == ResourceConstants.SCOPE_INDIVIDUAL) &&
284 (_guestUsersSet.contains(userId))) {
285
286 long roleId = _guestRolesMap.get(companyId).getRoleId();
287
288 String key = roleId + "_" + permissionId;
289
290 if (_rolesPermissions.contains(key)) {
291 continue;
292 }
293 else {
294 _rolesPermissions.add(key);
295 }
296
297 legacyFileExtRolesPermissionsWriter.write(
298 roleId + "," + permissionId + "\n");
299 }
300 else {
301 legacyFileUpdatedWriter.write(line + "\n");
302 }
303 }
304 }
305 finally {
306 legacyFileReader.close();
307
308 legacyFileUpdatedWriter.close();
309 legacyFileExtRolesPermissionsWriter.close();
310 }
311
312 Table table = new Table(
313 "Roles_Permissions",
314 new Object[][] {
315 {"roleId", Types.BIGINT}, {"permissionId", Types.BIGINT}
316 });
317
318 table.populateTable(legacyFile + _EXT_ROLES_PERMIMISSIONS);
319
320 FileUtil.delete(legacyFile);
321 FileUtil.delete(legacyFile + _EXT_ROLES_PERMIMISSIONS);
322
323 return legacyFile + _UPDATED;
324 }
325
326 private void _convertPermissions(
327 int type, String legacyName, String[] primKeys, String newName,
328 Object[][] newColumns)
329 throws Exception {
330
331 MaintenanceUtil.appendStatus("Processing " + legacyName);
332
333 Table legacyTable = new PermissionView(legacyName, primKeys);
334
335 String legacyFile = legacyTable.generateTempFile();
336
337 if (legacyFile == null) {
338 return;
339 }
340
341 if (type == RoleConstants.TYPE_REGULAR) {
342 legacyFile = _convertGuestUsers(legacyFile);
343
344 MaintenanceUtil.appendStatus(
345 "Converted guest users to guest roles");
346 }
347
348 _convertRoles(legacyFile, type, newName, newColumns);
349
350 MaintenanceUtil.appendStatus("Converted roles for " + legacyName);
351
352 DBUtil.getInstance().runSQL(legacyTable.getDeleteSQL());
353
354 FileUtil.delete(legacyFile);
355 }
356
357 private void _convertResourcePermission(BufferedWriter writer, String name)
358 throws Exception {
359
360 ResourcePermissionView resourcePermissionView =
361 new ResourcePermissionView(name);
362
363 BufferedReader resourcePermReader = null;
364
365 String resourcePermissionFile =
366 resourcePermissionView.generateTempFile();
367
368 if (resourcePermissionFile == null) {
369 return;
370 }
371
372 MultiValueMap mvp = new MultiValueMap();
373
374 try {
375 resourcePermReader =
376 new BufferedReader(new FileReader(resourcePermissionFile));
377
378 String line = null;
379
380 while (Validator.isNotNull(line = resourcePermReader.readLine())) {
381 String[] values = StringUtil.split(line);
382
383 String actionId = ResourcePermissionView.getActionId(values);
384 long companyId = ResourcePermissionView.getCompanyId(values);
385 int scope = ResourcePermissionView.getScope(values);
386 String primKey = ResourcePermissionView.getPrimaryKey(values);
387 long roleId = ResourcePermissionView.getRoleId(values);
388
389 mvp.put(new Tuple(companyId, scope, primKey, roleId), actionId);
390 }
391 }
392 finally {
393 if (resourcePermReader != null) {
394 resourcePermReader.close();
395 }
396
397 FileUtil.delete(resourcePermissionFile);
398 }
399
400 for (Tuple key : (Set<Tuple>)mvp.keySet()) {
401 long resourcePermissionId = CounterLocalServiceUtil.increment(
402 ResourcePermission.class.getName());
403
404 long companyId = (Long)key.getObject(0);
405 int scope = (Integer)key.getObject(1);
406 String primKey = (String)key.getObject(2);
407 long roleId = (Long)key.getObject(3);
408
409 String[] actionIdArray =
410 (String[])mvp.getCollection(key).toArray(new String[0]);
411
412 long actionIds = 0;
413
414 for (String actionId : actionIdArray) {
415 try {
416 ResourceAction resourceAction =
417 ResourceActionLocalServiceUtil.getResourceAction(
418 name, actionId);
419
420 actionIds |= resourceAction.getBitwiseValue();
421 }
422 catch (NoSuchResourceActionException nsrae) {
423 if (_log.isWarnEnabled()) {
424 String msg = nsrae.getMessage();
425
426 _log.warn("Could not find resource action " + msg);
427 }
428 }
429 }
430
431 writer.append(resourcePermissionId + StringPool.COMMA);
432 writer.append(companyId + StringPool.COMMA);
433 writer.append(name + StringPool.COMMA);
434 writer.append(scope + StringPool.COMMA);
435 writer.append(primKey + StringPool.COMMA);
436 writer.append(roleId + StringPool.COMMA);
437 writer.append(actionIds + StringPool.COMMA + StringPool.NEW_LINE);
438 }
439 }
440
441 private void _convertRoles(
442 String legacyFile, int type, String newName, Object[][] newColumns)
443 throws Exception {
444
445 BufferedReader legacyFileReader = new BufferedReader(
446 new FileReader(legacyFile));
447
448 BufferedWriter legacyFileExtRoleWriter = new BufferedWriter(
449 new FileWriter(legacyFile + _EXT_ROLE));
450 BufferedWriter legacyFileExtRolesPermissionsWriter = new BufferedWriter(
451 new FileWriter(legacyFile + _EXT_ROLES_PERMIMISSIONS));
452 BufferedWriter legacyFileExtOtherRolesWriter = new BufferedWriter(
453 new FileWriter(legacyFile + _EXT_OTHER_ROLES));
454
455 try {
456
457
459 MultiValueMap mvp = new MultiValueMap();
460
461 String line = null;
462
463 while (Validator.isNotNull(line = legacyFileReader.readLine())) {
464 String[] values = StringUtil.split(line);
465
466 long resourceId = PermissionView.getResourceId(values);
467
468 mvp.put(resourceId, values);
469 }
470
471
473 for (Long key : (Set<Long>)mvp.keySet()) {
474 List<String[]> valuesList = new ArrayList<String[]>(
475 mvp.getCollection(key));
476
477 String[] values = valuesList.get(0);
478
479 long companyId = PermissionView.getCompanyId(values);
480 long groupId = PermissionView.getPrimaryKey(values);
481 String name = PermissionView.getNameId(values);
482 int scope = PermissionView.getScopeId(values);
483
484
486 List<String> actionsIds = new ArrayList<String>();
487 List<Long> permissionIds = new ArrayList<Long>();
488
489 for (String[] curValues : valuesList) {
490 String actionId = PermissionView.getActionId(curValues);
491 long permissionId = PermissionView.getPermissionId(
492 curValues);
493
494 actionsIds.add(actionId);
495 permissionIds.add(permissionId);
496 }
497
498
500 if ((type != RoleConstants.TYPE_ORGANIZATION) &&
501 (scope == ResourceConstants.SCOPE_INDIVIDUAL)) {
502
503
505 List<String> defaultActions = null;
506
507 if (type == RoleConstants.TYPE_REGULAR) {
508 defaultActions =
509 ResourceActionsUtil.getResourceActions(name);
510 }
511 else {
512 defaultActions =
513 ResourceActionsUtil.
514 getResourceCommunityDefaultActions(name);
515 }
516
517
519 Role defaultRole = null;
520
521 if (type == RoleConstants.TYPE_REGULAR) {
522 Collections.sort(actionsIds);
523 Collections.sort(defaultActions);
524
525 if (defaultActions.equals(actionsIds)) {
526 defaultRole = _ownerRolesMap.get(companyId);
527 }
528 }
529 else {
530 if (defaultActions.containsAll(actionsIds)) {
531 Role[] defaultRoles = _defaultRolesMap.get(
532 companyId);
533
534 Group group = _groupsMap.get(groupId);
535
536 if (group.isCommunity()) {
537 defaultRole = defaultRoles[0];
538 }
539 else if (group.isOrganization()) {
540 defaultRole = defaultRoles[1];
541 }
542 else if (group.isUser() || group.isUserGroup()) {
543 defaultRole = defaultRoles[2];
544 }
545 }
546 }
547
548 if (defaultRole != null) {
549 long roleId = defaultRole.getRoleId();
550
551 for (Long permissionId : permissionIds) {
552 String curKey = roleId + "_" + permissionId;
553
554 if (_rolesPermissions.contains(curKey)) {
555 continue;
556 }
557 else {
558 _rolesPermissions.add(curKey);
559 }
560
561 legacyFileExtRolesPermissionsWriter.write(
562 roleId + "," + permissionId + ",\n");
563 }
564
565 continue;
566 }
567 }
568
569
571 long roleId = CounterLocalServiceUtil.increment();
572
573 String roleName = StringUtil.upperCaseFirstLetter(
574 RoleConstants.getTypeLabel(type));
575
576 roleName += " " + Long.toHexString(roleId);
577
578 String[] roleColumns = new String[] {
579 String.valueOf(roleId), String.valueOf(companyId),
580 String.valueOf(
581 ClassNameLocalServiceUtil.getClassNameId(Role.class)),
582 String.valueOf(roleId), roleName, StringPool.BLANK,
583 "Autogenerated role from portal upgrade",
584 String.valueOf(type), "lfr-permission-algorithm-5"
585 };
586
587 for (int i = 0; i < roleColumns.length; i++) {
588 legacyFileExtRoleWriter.write(
589 roleColumns[i] + StringPool.COMMA);
590
591 if (i == (roleColumns.length - 1)) {
592 legacyFileExtRoleWriter.write(StringPool.NEW_LINE);
593 }
594 }
595
596
598 for (Long permissionId : permissionIds) {
599 String curKey = roleId + "_" + permissionId;
600
601 if (_rolesPermissions.contains(curKey)) {
602 continue;
603 }
604 else {
605 _rolesPermissions.add(curKey);
606 }
607
608 legacyFileExtRolesPermissionsWriter.write(
609 roleId + "," + permissionId + ",\n");
610 }
611
612
614 for (int i = 0; i < newColumns.length - 1; i++) {
615 legacyFileExtOtherRolesWriter.write(
616 values[i] + StringPool.COMMA);
617 }
618
619 legacyFileExtOtherRolesWriter.write(roleId + ",\n");
620 }
621 }
622 finally {
623 legacyFileReader.close();
624
625 legacyFileExtRoleWriter.close();
626 legacyFileExtRolesPermissionsWriter.close();
627 legacyFileExtOtherRolesWriter.close();
628 }
629
630
632 Table roleTable = new Table(
633 RoleModelImpl.TABLE_NAME, RoleModelImpl.TABLE_COLUMNS);
634
635 roleTable.populateTable(legacyFile + _EXT_ROLE);
636
637
639 Table rolesPermissionsTable = new Table(
640 "Roles_Permissions",
641 new Object[][] {
642 {"roleId", Types.BIGINT}, {"permissionId", Types.BIGINT}
643 });
644
645 rolesPermissionsTable.populateTable(
646 legacyFile + _EXT_ROLES_PERMIMISSIONS);
647
648
650 Table othersRolesTable = new Table(newName, newColumns);
651
652 othersRolesTable.populateTable(legacyFile + _EXT_OTHER_ROLES);
653
654
656 FileUtil.delete(legacyFile + _EXT_ROLE);
657 FileUtil.delete(legacyFile + _EXT_ROLES_PERMIMISSIONS);
658 FileUtil.delete(legacyFile + _EXT_OTHER_ROLES);
659 }
660
661 private void _initialize() throws Exception {
662
663
665 List<ResourceCode> resourceCodes =
666 ResourceCodeLocalServiceUtil.getResourceCodes(
667 QueryUtil.ALL_POS, QueryUtil.ALL_POS);
668
669 for (ResourceCode resourceCode : resourceCodes) {
670 String name = resourceCode.getName();
671
672 if (!name.contains(StringPool.PERIOD)) {
673 ResourceActionsUtil.getPortletResourceActions(name);
674 }
675 }
676 }
677
678 private void _initializeRBAC() throws Exception {
679
680
682 long[] companyIds = PortalInstances.getCompanyIds();
683
684 for (long companyId : companyIds) {
685 _defaultRolesMap.put(
686 companyId,
687 new Role[] {
688 RoleLocalServiceUtil.getRole(
689 companyId, RoleConstants.COMMUNITY_MEMBER),
690 RoleLocalServiceUtil.getRole(
691 companyId, RoleConstants.ORGANIZATION_MEMBER),
692 RoleLocalServiceUtil.getRole(
693 companyId, RoleConstants.POWER_USER),
694 }
695 );
696
697 Role guestRole = RoleLocalServiceUtil.getRole(
698 companyId, RoleConstants.GUEST);
699
700 _guestRolesMap.put(companyId, guestRole);
701
702 Role ownerRole = RoleLocalServiceUtil.getRole(
703 companyId, RoleConstants.OWNER);
704
705 _ownerRolesMap.put(companyId, ownerRole);
706
707 long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
708 companyId);
709
710 _guestUsersSet.add(defaultUserId);
711 }
712
713
715 Connection con = null;
716 PreparedStatement ps = null;
717 ResultSet rs = null;
718
719 try {
720 con = DataAccess.getConnection();
721
722 ps = con.prepareStatement("SELECT * FROM Roles_Permissions");
723
724 rs = ps.executeQuery();
725
726 while (rs.next()) {
727 long roleId = rs.getLong("roleId");
728 long permissionId = rs.getLong("permissionId");
729
730 _rolesPermissions.add(roleId + "_" + permissionId);
731 }
732 }
733 finally {
734 DataAccess.cleanUp(con, ps, rs);
735 }
736
737
739 List<Group> groups = GroupLocalServiceUtil.getGroups(
740 QueryUtil.ALL_POS, QueryUtil.ALL_POS);
741
742 for (Group group : groups) {
743 _groupsMap.put(group.getGroupId(), group);
744 }
745 }
746
747 private static final String _EXT_OTHER_ROLES = ".others_roles";
748
749 private static final String _EXT_RESOURCE_PERMISSION =
750 ".resource_permission";
751
752 private static final String _EXT_ROLE = ".role";
753
754 private static final String _EXT_ROLES_PERMIMISSIONS = ".roles_permissions";
755
756 private static final String _UPDATED = ".updated";
757
758 private static final Log _log =
759 LogFactoryUtil.getLog(ConvertPermissionAlgorithm.class);
760
761 private Map<Long, Role[]> _defaultRolesMap = new HashMap<Long, Role[]>();
762 private Map<Long, Group> _groupsMap = new HashMap<Long, Group>();
763 private Map<Long, Role> _guestRolesMap = new HashMap<Long, Role>();
764 private Set<Long> _guestUsersSet = new HashSet<Long>();
765 private Map<Long, Role> _ownerRolesMap = new HashMap<Long, Role>();
766 private Set<String> _rolesPermissions = new HashSet<String>();
767
768 }