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.db.DB;
31 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
32 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
33 import com.liferay.portal.kernel.dao.orm.QueryUtil;
34 import com.liferay.portal.kernel.log.Log;
35 import com.liferay.portal.kernel.log.LogFactoryUtil;
36 import com.liferay.portal.kernel.util.FileUtil;
37 import com.liferay.portal.kernel.util.PropsKeys;
38 import com.liferay.portal.kernel.util.StringPool;
39 import com.liferay.portal.kernel.util.StringUtil;
40 import com.liferay.portal.kernel.util.Tuple;
41 import com.liferay.portal.kernel.util.Validator;
42 import com.liferay.portal.model.Company;
43 import com.liferay.portal.model.Group;
44 import com.liferay.portal.model.ResourceAction;
45 import com.liferay.portal.model.ResourceCode;
46 import com.liferay.portal.model.ResourceConstants;
47 import com.liferay.portal.model.ResourcePermission;
48 import com.liferay.portal.model.Role;
49 import com.liferay.portal.model.RoleConstants;
50 import com.liferay.portal.model.impl.PermissionModelImpl;
51 import com.liferay.portal.model.impl.ResourceCodeModelImpl;
52 import com.liferay.portal.model.impl.ResourceModelImpl;
53 import com.liferay.portal.model.impl.ResourcePermissionModelImpl;
54 import com.liferay.portal.model.impl.RoleModelImpl;
55 import com.liferay.portal.security.permission.PermissionCacheUtil;
56 import com.liferay.portal.security.permission.ResourceActionsUtil;
57 import com.liferay.portal.service.ClassNameLocalServiceUtil;
58 import com.liferay.portal.service.CompanyLocalServiceUtil;
59 import com.liferay.portal.service.GroupLocalServiceUtil;
60 import com.liferay.portal.service.ResourceActionLocalServiceUtil;
61 import com.liferay.portal.service.ResourceCodeLocalServiceUtil;
62 import com.liferay.portal.service.RoleLocalServiceUtil;
63 import com.liferay.portal.service.UserLocalServiceUtil;
64 import com.liferay.portal.service.persistence.BatchSessionUtil;
65 import com.liferay.portal.upgrade.util.Table;
66 import com.liferay.portal.util.MaintenanceUtil;
67 import com.liferay.portal.util.PropsValues;
68
69 import java.io.BufferedReader;
70 import java.io.BufferedWriter;
71 import java.io.FileReader;
72 import java.io.FileWriter;
73
74 import java.sql.Connection;
75 import java.sql.PreparedStatement;
76 import java.sql.ResultSet;
77 import java.sql.Types;
78
79 import java.util.ArrayList;
80 import java.util.Collections;
81 import java.util.HashMap;
82 import java.util.HashSet;
83 import java.util.List;
84 import java.util.Map;
85 import java.util.Set;
86
87 import org.apache.commons.collections.map.MultiValueMap;
88
89
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 DB db = DBFactoryUtil.getDB();
217
218 db.runSQL("DELETE FROM " + ResourceCodeModelImpl.TABLE_NAME);
219 db.runSQL("DELETE FROM " + PermissionModelImpl.TABLE_NAME);
220 db.runSQL("DELETE FROM " + ResourceModelImpl.TABLE_NAME);
221 db.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 DB db = DBFactoryUtil.getDB();
356
357 db.runSQL(legacyTable.getDeleteSQL());
358
359 FileUtil.delete(legacyFile);
360 }
361
362 private void _convertResourcePermission(BufferedWriter writer, String name)
363 throws Exception {
364
365 ResourcePermissionView resourcePermissionView =
366 new ResourcePermissionView(name);
367
368 BufferedReader resourcePermReader = null;
369
370 String resourcePermissionFile =
371 resourcePermissionView.generateTempFile();
372
373 if (resourcePermissionFile == null) {
374 return;
375 }
376
377 MultiValueMap mvp = new MultiValueMap();
378
379 try {
380 resourcePermReader =
381 new BufferedReader(new FileReader(resourcePermissionFile));
382
383 String line = null;
384
385 while (Validator.isNotNull(line = resourcePermReader.readLine())) {
386 String[] values = StringUtil.split(line);
387
388 String actionId = ResourcePermissionView.getActionId(values);
389 long companyId = ResourcePermissionView.getCompanyId(values);
390 int scope = ResourcePermissionView.getScope(values);
391 String primKey = ResourcePermissionView.getPrimaryKey(values);
392 long roleId = ResourcePermissionView.getRoleId(values);
393
394 mvp.put(new Tuple(companyId, scope, primKey, roleId), actionId);
395 }
396 }
397 finally {
398 if (resourcePermReader != null) {
399 resourcePermReader.close();
400 }
401
402 FileUtil.delete(resourcePermissionFile);
403 }
404
405 for (Tuple key : (Set<Tuple>)mvp.keySet()) {
406 long resourcePermissionId = CounterLocalServiceUtil.increment(
407 ResourcePermission.class.getName());
408
409 long companyId = (Long)key.getObject(0);
410 int scope = (Integer)key.getObject(1);
411 String primKey = (String)key.getObject(2);
412 long roleId = (Long)key.getObject(3);
413
414 String[] actionIdArray =
415 (String[])mvp.getCollection(key).toArray(new String[0]);
416
417 long actionIds = 0;
418
419 for (String actionId : actionIdArray) {
420 try {
421 ResourceAction resourceAction =
422 ResourceActionLocalServiceUtil.getResourceAction(
423 name, actionId);
424
425 actionIds |= resourceAction.getBitwiseValue();
426 }
427 catch (NoSuchResourceActionException nsrae) {
428 if (_log.isWarnEnabled()) {
429 String msg = nsrae.getMessage();
430
431 _log.warn("Could not find resource action " + msg);
432 }
433 }
434 }
435
436 writer.append(resourcePermissionId + StringPool.COMMA);
437 writer.append(companyId + StringPool.COMMA);
438 writer.append(name + StringPool.COMMA);
439 writer.append(scope + StringPool.COMMA);
440 writer.append(primKey + StringPool.COMMA);
441 writer.append(roleId + StringPool.COMMA);
442 writer.append(actionIds + StringPool.COMMA + StringPool.NEW_LINE);
443 }
444 }
445
446 private void _convertRoles(
447 String legacyFile, int type, String newName, Object[][] newColumns)
448 throws Exception {
449
450 BufferedReader legacyFileReader = new BufferedReader(
451 new FileReader(legacyFile));
452
453 BufferedWriter legacyFileExtRoleWriter = new BufferedWriter(
454 new FileWriter(legacyFile + _EXT_ROLE));
455 BufferedWriter legacyFileExtRolesPermissionsWriter = new BufferedWriter(
456 new FileWriter(legacyFile + _EXT_ROLES_PERMIMISSIONS));
457 BufferedWriter legacyFileExtOtherRolesWriter = new BufferedWriter(
458 new FileWriter(legacyFile + _EXT_OTHER_ROLES));
459
460 try {
461
462
464 MultiValueMap mvp = new MultiValueMap();
465
466 String line = null;
467
468 while (Validator.isNotNull(line = legacyFileReader.readLine())) {
469 String[] values = StringUtil.split(line);
470
471 long resourceId = PermissionView.getResourceId(values);
472
473 mvp.put(resourceId, values);
474 }
475
476
478 for (Long key : (Set<Long>)mvp.keySet()) {
479 List<String[]> valuesList = new ArrayList<String[]>(
480 mvp.getCollection(key));
481
482 String[] values = valuesList.get(0);
483
484 long companyId = PermissionView.getCompanyId(values);
485 long groupId = PermissionView.getPrimaryKey(values);
486 String name = PermissionView.getNameId(values);
487 int scope = PermissionView.getScopeId(values);
488
489
491 List<String> actionsIds = new ArrayList<String>();
492 List<Long> permissionIds = new ArrayList<Long>();
493
494 for (String[] curValues : valuesList) {
495 String actionId = PermissionView.getActionId(curValues);
496 long permissionId = PermissionView.getPermissionId(
497 curValues);
498
499 actionsIds.add(actionId);
500 permissionIds.add(permissionId);
501 }
502
503
505 if ((type != RoleConstants.TYPE_ORGANIZATION) &&
506 (scope == ResourceConstants.SCOPE_INDIVIDUAL)) {
507
508
510 List<String> defaultActions = null;
511
512 if (type == RoleConstants.TYPE_REGULAR) {
513 defaultActions =
514 ResourceActionsUtil.getResourceActions(name);
515 }
516 else {
517 defaultActions =
518 ResourceActionsUtil.
519 getResourceCommunityDefaultActions(name);
520 }
521
522
524 Role defaultRole = null;
525
526 if (type == RoleConstants.TYPE_REGULAR) {
527 Collections.sort(actionsIds);
528 Collections.sort(defaultActions);
529
530 if (defaultActions.equals(actionsIds)) {
531 defaultRole = _ownerRolesMap.get(companyId);
532 }
533 }
534 else {
535 if (defaultActions.containsAll(actionsIds)) {
536 Role[] defaultRoles = _defaultRolesMap.get(
537 companyId);
538
539 Group group = _groupsMap.get(groupId);
540
541 if (group.isCommunity()) {
542 defaultRole = defaultRoles[0];
543 }
544 else if (group.isOrganization()) {
545 defaultRole = defaultRoles[1];
546 }
547 else if (group.isUser() || group.isUserGroup()) {
548 defaultRole = defaultRoles[2];
549 }
550 }
551 }
552
553 if (defaultRole != null) {
554 long roleId = defaultRole.getRoleId();
555
556 for (Long permissionId : permissionIds) {
557 String curKey = roleId + "_" + permissionId;
558
559 if (_rolesPermissions.contains(curKey)) {
560 continue;
561 }
562 else {
563 _rolesPermissions.add(curKey);
564 }
565
566 legacyFileExtRolesPermissionsWriter.write(
567 roleId + "," + permissionId + ",\n");
568 }
569
570 continue;
571 }
572 }
573
574
576 long roleId = CounterLocalServiceUtil.increment();
577
578 String roleName = StringUtil.upperCaseFirstLetter(
579 RoleConstants.getTypeLabel(type));
580
581 roleName += " " + Long.toHexString(roleId);
582
583 String[] roleColumns = new String[] {
584 String.valueOf(roleId), String.valueOf(companyId),
585 String.valueOf(
586 ClassNameLocalServiceUtil.getClassNameId(Role.class)),
587 String.valueOf(roleId), roleName, StringPool.BLANK,
588 "Autogenerated role from portal upgrade",
589 String.valueOf(type), "lfr-permission-algorithm-5"
590 };
591
592 for (int i = 0; i < roleColumns.length; i++) {
593 legacyFileExtRoleWriter.write(
594 roleColumns[i] + StringPool.COMMA);
595
596 if (i == (roleColumns.length - 1)) {
597 legacyFileExtRoleWriter.write(StringPool.NEW_LINE);
598 }
599 }
600
601
603 for (Long permissionId : permissionIds) {
604 String curKey = roleId + "_" + permissionId;
605
606 if (_rolesPermissions.contains(curKey)) {
607 continue;
608 }
609 else {
610 _rolesPermissions.add(curKey);
611 }
612
613 legacyFileExtRolesPermissionsWriter.write(
614 roleId + "," + permissionId + ",\n");
615 }
616
617
619 for (int i = 0; i < newColumns.length - 1; i++) {
620 legacyFileExtOtherRolesWriter.write(
621 values[i] + StringPool.COMMA);
622 }
623
624 legacyFileExtOtherRolesWriter.write(roleId + ",\n");
625 }
626 }
627 finally {
628 legacyFileReader.close();
629
630 legacyFileExtRoleWriter.close();
631 legacyFileExtRolesPermissionsWriter.close();
632 legacyFileExtOtherRolesWriter.close();
633 }
634
635
637 Table roleTable = new Table(
638 RoleModelImpl.TABLE_NAME, RoleModelImpl.TABLE_COLUMNS);
639
640 roleTable.populateTable(legacyFile + _EXT_ROLE);
641
642
644 Table rolesPermissionsTable = new Table(
645 "Roles_Permissions",
646 new Object[][] {
647 {"roleId", Types.BIGINT}, {"permissionId", Types.BIGINT}
648 });
649
650 rolesPermissionsTable.populateTable(
651 legacyFile + _EXT_ROLES_PERMIMISSIONS);
652
653
655 Table othersRolesTable = new Table(newName, newColumns);
656
657 othersRolesTable.populateTable(legacyFile + _EXT_OTHER_ROLES);
658
659
661 FileUtil.delete(legacyFile + _EXT_ROLE);
662 FileUtil.delete(legacyFile + _EXT_ROLES_PERMIMISSIONS);
663 FileUtil.delete(legacyFile + _EXT_OTHER_ROLES);
664 }
665
666 private void _initialize() throws Exception {
667
668
670 List<ResourceCode> resourceCodes =
671 ResourceCodeLocalServiceUtil.getResourceCodes(
672 QueryUtil.ALL_POS, QueryUtil.ALL_POS);
673
674 for (ResourceCode resourceCode : resourceCodes) {
675 String name = resourceCode.getName();
676
677 if (!name.contains(StringPool.PERIOD)) {
678 ResourceActionsUtil.getPortletResourceActions(name);
679 }
680 }
681 }
682
683 private void _initializeRBAC() throws Exception {
684
685
687 List<Company> companies = CompanyLocalServiceUtil.getCompanies();
688
689 for (Company company : companies) {
690 long companyId = company.getCompanyId();
691
692 _defaultRolesMap.put(
693 companyId,
694 new Role[] {
695 RoleLocalServiceUtil.getRole(
696 companyId, RoleConstants.COMMUNITY_MEMBER),
697 RoleLocalServiceUtil.getRole(
698 companyId, RoleConstants.ORGANIZATION_MEMBER),
699 RoleLocalServiceUtil.getRole(
700 companyId, RoleConstants.POWER_USER),
701 }
702 );
703
704 Role guestRole = RoleLocalServiceUtil.getRole(
705 companyId, RoleConstants.GUEST);
706
707 _guestRolesMap.put(companyId, guestRole);
708
709 Role ownerRole = RoleLocalServiceUtil.getRole(
710 companyId, RoleConstants.OWNER);
711
712 _ownerRolesMap.put(companyId, ownerRole);
713
714 long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
715 companyId);
716
717 _guestUsersSet.add(defaultUserId);
718 }
719
720
722 Connection con = null;
723 PreparedStatement ps = null;
724 ResultSet rs = null;
725
726 try {
727 con = DataAccess.getConnection();
728
729 ps = con.prepareStatement("SELECT * FROM Roles_Permissions");
730
731 rs = ps.executeQuery();
732
733 while (rs.next()) {
734 long roleId = rs.getLong("roleId");
735 long permissionId = rs.getLong("permissionId");
736
737 _rolesPermissions.add(roleId + "_" + permissionId);
738 }
739 }
740 finally {
741 DataAccess.cleanUp(con, ps, rs);
742 }
743
744
746 List<Group> groups = GroupLocalServiceUtil.getGroups(
747 QueryUtil.ALL_POS, QueryUtil.ALL_POS);
748
749 for (Group group : groups) {
750 _groupsMap.put(group.getGroupId(), group);
751 }
752 }
753
754 private static final String _EXT_OTHER_ROLES = ".others_roles";
755
756 private static final String _EXT_RESOURCE_PERMISSION =
757 ".resource_permission";
758
759 private static final String _EXT_ROLE = ".role";
760
761 private static final String _EXT_ROLES_PERMIMISSIONS = ".roles_permissions";
762
763 private static final String _UPDATED = ".updated";
764
765 private static final Log _log =
766 LogFactoryUtil.getLog(ConvertPermissionAlgorithm.class);
767
768 private Map<Long, Role[]> _defaultRolesMap = new HashMap<Long, Role[]>();
769 private Map<Long, Group> _groupsMap = new HashMap<Long, Group>();
770 private Map<Long, Role> _guestRolesMap = new HashMap<Long, Role>();
771 private Set<Long> _guestUsersSet = new HashSet<Long>();
772 private Map<Long, Role> _ownerRolesMap = new HashMap<Long, Role>();
773 private Set<String> _rolesPermissions = new HashSet<String>();
774
775 }