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