Skip to content

Commit

Permalink
feat: Update calls to UserACL to avoid implicit usage of Conversation…
Browse files Browse the repository at this point in the history
… State in Service Layer - MEED-7555 - Meeds-io/MIPs#151 (#225)

This change will update UserACL usage to not implicitly use the current
conversation state of authenticated user.
  • Loading branch information
boubaker committed Oct 2, 2024
1 parent 58f89aa commit 2c73794
Show file tree
Hide file tree
Showing 14 changed files with 44 additions and 185 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public boolean hasAccessPermission(Identity userIdentity, String entityId) throw
List<String> permissions = portletInstance.getPermissions();
return CollectionUtils.isEmpty(permissions)
|| (userIdentity != null
&& permissions.stream().anyMatch(p -> layoutAclService.isMemberOf(userIdentity.getUserId(), p)));
&& permissions.stream().anyMatch(p -> layoutAclService.hasPermission(userIdentity.getUserId(), p)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public boolean hasAccessPermission(long id, String username) throws ObjectNotFou
}
List<String> permissions = category.getPermissions();
return CollectionUtils.isEmpty(permissions)
|| permissions.stream().anyMatch(p -> layoutAclService.isMemberOf(username, p));
|| permissions.stream().anyMatch(p -> layoutAclService.hasPermission(username, p));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public boolean hasAccessPermission(long id, String username) throws ObjectNotFou
}
List<String> permissions = portletInstance.getPermissions();
return CollectionUtils.isEmpty(permissions)
|| permissions.stream().anyMatch(p -> layoutAclService.isMemberOf(username, p));
|| permissions.stream().anyMatch(p -> layoutAclService.hasPermission(username, p));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,6 @@ public class LayoutModel {
// Specific to container
private String profiles;

private String[] moveAppsPermissions;

private String[] moveContainersPermissions;

private List<PortletInstancePreference> preferences;

private List<LayoutModel> children;
Expand Down Expand Up @@ -260,8 +256,6 @@ private void init(ModelObject model) { // NOSONAR
this.cssClass = container.getCssClass();
this.profiles = container.getProfiles();
this.accessPermissions = container.getAccessPermissions();
this.moveAppsPermissions = container.getMoveAppsPermissions();
this.moveContainersPermissions = container.getMoveContainersPermissions();
this.children = container.getChildren().stream().map(LayoutModel::new).toList();

ApplicationBackgroundStyle appCssStyle = container.getAppBackgroundStyle();
Expand Down Expand Up @@ -344,8 +338,6 @@ public static ModelObject toModelObject(LayoutModel layoutModel) { // NOSONAR
container.setCssClass(layoutModel.getCssClass());
container.setProfiles(layoutModel.getProfiles());
container.setAccessPermissions(layoutModel.getAccessPermissions());
container.setMoveAppsPermissions(layoutModel.getMoveAppsPermissions());
container.setMoveContainersPermissions(layoutModel.getMoveContainersPermissions());
container.setCssStyle(cssStyle);
container.setAppBackgroundStyle(mapToAppStyle(layoutModel));
if (layoutModel.getChildren() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,201 +18,94 @@
*/
package io.meeds.layout.service;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.portal.config.UserACL;
import org.exoplatform.portal.config.model.Page;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.page.PageKey;
import org.exoplatform.portal.mop.service.LayoutService;
import org.exoplatform.services.security.Authenticator;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.Identity;
import org.exoplatform.services.security.IdentityConstants;
import org.exoplatform.services.security.IdentityRegistry;
import org.exoplatform.social.core.identity.model.Identity;
import org.exoplatform.social.core.manager.IdentityManager;

import jakarta.annotation.PostConstruct;
import lombok.Setter;
import lombok.SneakyThrows;

@Service
public class LayoutAclService {

@Autowired
private UserACL userAcl;

@Autowired
private LayoutService layoutService;
private LayoutService layoutService;

@Autowired
private Authenticator authenticator;
private IdentityManager identityManager;

@Autowired
private IdentityManager identityManager;

@Setter
private IdentityRegistry identityRegistry;

@PostConstruct
public void init() {
// Can't be autowired from Kernel IoC, thus inject it once Spring Bean
// initialized
setIdentityRegistry(ExoContainerContext.getService(IdentityRegistry.class));
}
private UserACL userAcl;

public boolean canAddSite(String username) {
ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasCreatePortalPermission();
} finally {
ConversationState.setCurrent(currentConversationState);
}
return userAcl.hasCreatePortalPermission(userAcl.getUserIdentity(username));
}

public boolean canEditSite(SiteKey siteKey, String username) {
PortalConfig portalConfig = layoutService.getPortalConfig(siteKey);
if (portalConfig == null) {
return false;
}
ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasEditPermission(portalConfig);
} finally {
ConversationState.setCurrent(currentConversationState);
}
return userAcl.hasEditPermission(portalConfig, userAcl.getUserIdentity(username));
}

public boolean canViewSite(SiteKey siteKey, String username) {
PortalConfig portalConfig = layoutService.getPortalConfig(siteKey);
if (portalConfig == null) {
return false;
}
ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasPermission(portalConfig);
} finally {
ConversationState.setCurrent(currentConversationState);
}
return userAcl.hasAccessPermission(portalConfig, userAcl.getUserIdentity(username));
}

public boolean canEditNavigation(SiteKey siteKey, String username) {
PortalConfig portalConfig = layoutService.getPortalConfig(siteKey);
if (portalConfig == null) {
return false;
}

ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasEditPermission(portalConfig) || userAcl.hasEditPermissionOnNavigation(siteKey);
} finally {
ConversationState.setCurrent(currentConversationState);
}
return canEditSite(siteKey, username);
}

public boolean canViewNavigation(SiteKey siteKey, PageKey pageKey, String username) {
PortalConfig portalConfig = layoutService.getPortalConfig(siteKey);
if (portalConfig == null) {
return false;
}
Page page = pageKey == null ? null : layoutService.getPage(pageKey);
ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasAccessPermission(portalConfig) && (page == null || userAcl.hasPermission(page));
} finally {
ConversationState.setCurrent(currentConversationState);
}
return canViewSite(siteKey, username) && (pageKey == null || canViewPage(pageKey, username));
}

public boolean canViewPage(PageKey pageKey, String username) {
Page page = layoutService.getPage(pageKey);
if (page == null) {
return false;
}

ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasPermission(page);
} finally {
ConversationState.setCurrent(currentConversationState);
}
return userAcl.hasAccessPermission(page, userAcl.getUserIdentity(username));
}

public boolean canEditPage(PageKey pageKey, String username) {
Page page = layoutService.getPage(pageKey);
if (page == null) {
return false;
}

ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasEditPermission(page);
} finally {
ConversationState.setCurrent(currentConversationState);
}
return userAcl.hasEditPermission(page, userAcl.getUserIdentity(username));
}

public boolean isAdministrator(String username) {
ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.isSuperUser() || userAcl.isUserInGroup(getAdministratorsGroup());
} finally {
ConversationState.setCurrent(currentConversationState);
}
return userAcl.isAdministrator(userAcl.getUserIdentity(username));
}

public boolean isMemberOf(String username, String expression) {
ConversationState currentConversationState = ConversationState.getCurrent();
ConversationState.setCurrent(getConversationState(username));
try {
return userAcl.hasPermission(expression);
} finally {
ConversationState.setCurrent(currentConversationState);
}
public boolean hasPermission(String username, String expression) {
return userAcl.hasPermission(userAcl.getUserIdentity(username), expression);
}

public String getAdministratorsGroup() {
return userAcl.getAdminGroups();
}

public ConversationState getSuperUserConversationState() {
return new ConversationState(getUserIdentity(userAcl.getSuperUser()));
return new ConversationState(userAcl.getUserIdentity(userAcl.getSuperUser()));
}

public long getSuperUserIdentityId() {
org.exoplatform.social.core.identity.model.Identity userIdentity =
identityManager.getOrCreateUserIdentity(userAcl.getSuperUser());
String id = userIdentity == null ? null : userIdentity.getId();
return id == null ? 0 : Long.parseLong(id);
}

private ConversationState getConversationState(String username) {
return new ConversationState(getUserIdentity(username));
}

@SneakyThrows
private Identity getUserIdentity(String username) {
if (StringUtils.isBlank(username) || IdentityConstants.ANONIM.equals(username)) {
return null;
}
Identity identity = identityRegistry.getIdentity(username);
if (identity != null) {
return identity;
} else {
return authenticator.createIdentity(username);
}
Identity userIdentity = identityManager.getOrCreateUserIdentity(userAcl.getSuperUser());
return userIdentity == null ? 0l : Long.parseLong(userIdentity.getId());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,6 @@ public void updatePageLink(PageKey pageKey,
pageState.getFactoryId(),
pageState.getAccessPermissions(),
pageState.getEditPermission(),
pageState.getMoveAppsPermissions(),
pageState.getMoveContainersPermissions(),
pageState.getType(),
link));
layoutService.save(pageContext);
Expand All @@ -323,8 +321,6 @@ public void updatePagePermissions(PageKey pageKey,
pageState.getFactoryId(),
accessPermissionsList,
editPermission,
pageState.getMoveAppsPermissions(),
pageState.getMoveContainersPermissions(),
pageState.getType(),
pageState.getLink()));
layoutService.save(pageContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ public List<PortletInstancePreference> getApplicationPreferences(long applicatio
}
if (!layoutAclService.isAdministrator(username)
&& Arrays.stream(application.getAccessPermissions())
.noneMatch(permission -> layoutAclService.isMemberOf(username, permission))) {
.noneMatch(permission -> layoutAclService.hasPermission(username, permission))) {
throw new IllegalAccessException(String.format("Application with id %s access denied", applicationId));
}
return getApplicationPreferences(application);
Expand Down Expand Up @@ -453,13 +453,13 @@ private boolean hasPermission(PortletInstance portletInstance, String username)
List<String> permissions = portletInstance.getPermissions();
return CollectionUtils.isEmpty(permissions)
|| permissions.equals(EVERYONE_PERMISSIONS_LIST)
|| (StringUtils.isNotBlank(username) && permissions.stream().anyMatch(p -> layoutAclService.isMemberOf(username, p)));
|| (StringUtils.isNotBlank(username) && permissions.stream().anyMatch(p -> layoutAclService.hasPermission(username, p)));
}

private boolean hasPermission(PortletInstanceCategory category, String username) {
List<String> permissions = category.getPermissions();
return CollectionUtils.isEmpty(permissions)
|| permissions.equals(EVERYONE_PERMISSIONS_LIST)
|| (StringUtils.isNotBlank(username) && permissions.stream().anyMatch(p -> layoutAclService.isMemberOf(username, p)));
|| (StringUtils.isNotBlank(username) && permissions.stream().anyMatch(p -> layoutAclService.hasPermission(username, p)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,7 @@ private Page getPortletInstanceSystemPage() {
false,
null,
Arrays.asList(UserACL.EVERYONE),
page.getEditPermission(),
Arrays.asList(UserACL.EVERYONE),
Arrays.asList(UserACL.EVERYONE));
page.getEditPermission());
layoutService.save(new PageContext(PORTLET_EDITOR_SYSTEM_PAGE_KEY, pageState), page);
page = layoutService.getPage(PORTLET_EDITOR_SYSTEM_PAGE_KEY);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public void hasAccessPermission() {
when(portletInstance.getPermissions()).thenReturn(Collections.singletonList(permissionExpression));
assertFalse(attachmentPlugin.hasAccessPermission(userIdentity, "1"));

when(layoutAclService.isMemberOf(username, permissionExpression)).thenReturn(true);
when(layoutAclService.hasPermission(username, permissionExpression)).thenReturn(true);
assertTrue(attachmentPlugin.hasAccessPermission(userIdentity, "1"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void hasAccessPermission() {
when(portletInstanceCategory.getPermissions()).thenReturn(Collections.singletonList(permissionExpression));
assertFalse(translationPlugin.hasAccessPermission(1, username));

when(layoutAclService.isMemberOf(username, permissionExpression)).thenReturn(true);
when(layoutAclService.hasPermission(username, permissionExpression)).thenReturn(true);
assertTrue(translationPlugin.hasAccessPermission(1, username));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void hasAccessPermission() {
when(portletInstance.getPermissions()).thenReturn(Collections.singletonList(permissionExpression));
assertFalse(translationPlugin.hasAccessPermission(1, username));

when(layoutAclService.isMemberOf(username, permissionExpression)).thenReturn(true);
when(layoutAclService.hasPermission(username, permissionExpression)).thenReturn(true);
assertTrue(translationPlugin.hasAccessPermission(1, username));
}

Expand Down
Loading

0 comments on commit 2c73794

Please sign in to comment.