Skip to content

Commit

Permalink
chore: changes for CD tech debt (#33231)
Browse files Browse the repository at this point in the history
## Description

Creating a new permission for Application, which is
APPLICATION_DELETE_PAGES, this permission would be used to derive
DELETE_PAGES permission for those permissionGroupIds which don't have
DELETE_APPLICATIONS permission.

Once such example is CD bot role. although it requires permission to
delete pages and entities inside it, we don't want to provide permission
for deleting application. This could be achieved by providing
DELETE_PAGES permission, however when creating new pages, the permission
would still be derived from application and it would lack the particular
permission group id in DELETE_PAGES permissionGroups.

Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/9013034630>
> Commit: 9c01c08
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=9013034630&attempt=2"
target="_blank">Click here!</a>

<!-- end of auto-generated comment: Cypress test results  -->












## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No
  • Loading branch information
sondermanish committed May 9, 2024
1 parent a3429f9 commit 6c27ccc
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public enum AclPermission {

APPLICATION_CREATE_PAGES("create:pages", Application.class),

/**
* This permission would be used to provide delete permission to pages where the user does not have
* permission to delete application.
*/
APPLICATION_DELETE_PAGES("delete:applicationPages", Application.class),

MANAGE_PAGES("manage:pages", NewPage.class),
READ_PAGES("read:pages", NewPage.class),
DELETE_PAGES("delete:pages", NewPage.class),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.stream.Collectors;

import static com.appsmith.server.acl.AclPermission.APPLICATION_CREATE_PAGES;
import static com.appsmith.server.acl.AclPermission.APPLICATION_DELETE_PAGES;
import static com.appsmith.server.acl.AclPermission.COMMENT_ON_APPLICATIONS;
import static com.appsmith.server.acl.AclPermission.CONNECT_TO_GIT;
import static com.appsmith.server.acl.AclPermission.DELETE_ACTIONS;
Expand Down Expand Up @@ -210,7 +211,8 @@ protected void createApplicationPolicyGraph() {

// If the user is being given MANAGE_APPLICATION permission, they must also be given READ_APPLICATION perm
lateralGraph.addEdge(MANAGE_APPLICATIONS, READ_APPLICATIONS);

// If the user has permission to delete application, they must have permission to delete application-pages,
lateralGraph.addEdge(DELETE_APPLICATIONS, APPLICATION_DELETE_PAGES);
// If the user can read an application, the should be able to comment on it.
lateralGraph.addEdge(READ_APPLICATIONS, COMMENT_ON_APPLICATIONS);
}
Expand All @@ -229,6 +231,7 @@ protected void createPagePolicyGraph() {
hierarchyGraph.addEdge(MANAGE_APPLICATIONS, MANAGE_PAGES);
hierarchyGraph.addEdge(READ_APPLICATIONS, READ_PAGES);
hierarchyGraph.addEdge(DELETE_APPLICATIONS, DELETE_PAGES);
hierarchyGraph.addEdge(APPLICATION_DELETE_PAGES, DELETE_PAGES);
hierarchyGraph.addEdge(APPLICATION_CREATE_PAGES, PAGE_CREATE_PAGE_ACTIONS);

lateralGraph.addEdge(MANAGE_PAGES, READ_PAGES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ public static class Fields extends BaseDomain.Fields {
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.gitAuth);
public static final String gitApplicationMetadata_defaultApplicationId =
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.defaultApplicationId);
public static final String gitApplicationMetadata_isAutoDeploymentEnabled =
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.isAutoDeploymentEnabled);
public static final String gitApplicationMetadata_branchName =
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.branchName);
public static final String gitApplicationMetadata_isRepoPrivate =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.appsmith.server.migrations.db.ce;

import com.appsmith.external.models.BaseDomain;
import com.appsmith.server.acl.AclPermission;
import com.appsmith.server.domains.Application;
import io.mongock.api.annotations.ChangeUnit;
import io.mongock.api.annotations.Execution;
import io.mongock.api.annotations.RollbackExecution;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;

import static com.appsmith.server.migrations.db.ce.Migration047AddMissingFieldsInDefaultAppsmithAiDatasource.newerCheckForDeletedCriteria;
import static com.appsmith.server.migrations.db.ce.Migration047AddMissingFieldsInDefaultAppsmithAiDatasource.olderCheckForDeletedCriteria;

/**
* This class adds a new policy delete:applicationPages to all non deleted applications.
* The permissionGroups of the new policy is copied from the policy having permission delete application
* in the same application.
*
*/
@Slf4j
@ChangeUnit(order = "053", id = "add-app-delete-pages-permission-to-application", author = " ")
@RequiredArgsConstructor
public class Migration053AddApplicationDeletePagePermissionToApplications {

private final MongoTemplate mongoTemplate;

private static final String APPLICATION_DELETE_PAGES_VALUE = AclPermission.APPLICATION_DELETE_PAGES.getValue();
private static final String DELETE_APPLICATIONS_VALUE = AclPermission.DELETE_APPLICATIONS.getValue();

private static final String POLICIES = BaseDomain.Fields.policies;
private static final String PERMISSION = "permission";
private static final String PERMISSION_GROUPS = "permissionGroups";

@RollbackExecution
public void rollbackExecution() {}

@Execution
public void addApplicationDeletePagesPermissionToApplication() {

// selection of all the applications which have not been deleted.
Criteria applicationCriteria =
new Criteria().andOperator(olderCheckForDeletedCriteria(), newerCheckForDeletedCriteria());

// conditional to match delete:applications permission
Document equalityConditionDoc = new Document("$eq", List.of("$$this.permission", DELETE_APPLICATIONS_VALUE));

// filtering the policy from the policies based on equality condition
Document filterPermissionGroupsDoc = new Document(
"$filter", new Document().append("input", "$policies").append("cond", equalityConditionDoc));

// selecting the permissionGroups set present at array index,
// (the list is dynamically created after filtering policies on permission and then returning permissionGroups)
Document permissionGroupArrayElementAtDoc = new Document("$arrayElemAt", List.of(filterPermissionGroupsDoc, 0));

// creating a new policy with permission delete:applicationPages and permissionGroups from delete:app policy
List<Document> singletonPolicyList = List.of(new Document(PERMISSION, APPLICATION_DELETE_PAGES_VALUE)
.append(
PERMISSION_GROUPS,
new Document(
"$let",
new Document()
.append(
"vars",
new Document("existingPolicy", permissionGroupArrayElementAtDoc))
.append("in", "$$existingPolicy.permissionGroups"))));

// concatenating existing policies set with the newly created policy which is in set
Document concatPolicySets = new Document("$concatArrays", List.of("$policies", singletonPolicyList));

AggregationOperation aggregationOperation = Aggregation.addFields()
.addFieldWithValue(POLICIES, concatPolicySets)
.build();

try {
mongoTemplate.updateMulti(
new Query().addCriteria(applicationCriteria),
Aggregation.newUpdate(aggregationOperation),
Application.class);
} catch (Exception exception) {
log.debug(
"Migration with change-id : add-app-delete-pages-permission-to-application failed due to reason {}."
+ "skipping addition of policy to applications ",
exception.getMessage());

throw exception;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ public interface ApplicationPermissionCE extends ArtifactPermission {
AclPermission getManageDefaultBranchPermission();

AclPermission getManageAutoCommitPermission();

AclPermission getPublishPermission();

AclPermission getApplicationDeletePagesPermission();
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,13 @@ public AclPermission getManageDefaultBranchPermission() {
public AclPermission getManageAutoCommitPermission() {
return AclPermission.MANAGE_AUTO_COMMIT;
}

public AclPermission getPublishPermission() {
return AclPermission.PUBLISH_APPLICATIONS;
}

@Override
public AclPermission getApplicationDeletePagesPermission() {
return AclPermission.APPLICATION_DELETE_PAGES;
}
}

0 comments on commit 6c27ccc

Please sign in to comment.