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