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