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