This is an automated email from the ASF dual-hosted git repository.

billyliu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit fde86c2d67bdc08b057ab31698a7b01986518b34
Author: Jiatao Tao <245915...@qq.com>
AuthorDate: Thu Feb 8 20:56:36 2018 +0800

    KYLIN-3248, add batch grant API for project ACL.
    
    minor, change the batch reqs.
---
 .../kylin/rest/controller/AccessController.java    | 25 ++++++++++++++++++++
 .../apache/kylin/rest/service/AccessService.java   | 26 ++++++++++++++++++---
 .../org/apache/kylin/rest/service/AclService.java  | 11 +++++++++
 .../kylin/rest/service/AccessServiceTest.java      | 20 ++++++++++++++++
 .../apache/kylin/rest/service/AclServiceTest.java  | 27 ++++++++++++++++++++++
 5 files changed, 106 insertions(+), 3 deletions(-)

diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/controller/AccessController.java
 
b/server-base/src/main/java/org/apache/kylin/rest/controller/AccessController.java
index 56cae10..b9a00b3 100644
--- 
a/server-base/src/main/java/org/apache/kylin/rest/controller/AccessController.java
+++ 
b/server-base/src/main/java/org/apache/kylin/rest/controller/AccessController.java
@@ -20,8 +20,11 @@ package org.apache.kylin.rest.controller;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import com.google.common.base.Preconditions;
 import org.apache.kylin.common.persistence.AclEntity;
 import org.apache.kylin.common.util.Pair;
 import org.apache.kylin.metadata.MetadataConstants;
@@ -156,6 +159,28 @@ public class AccessController extends BasicController 
implements InitializingBea
     }
 
     /**
+     * Batch API.Grant a new access on a domain object to a user/role
+     */
+    @RequestMapping(value = "batch/{type}/{uuid}", method = { 
RequestMethod.POST }, produces = { "application/json" })
+    @ResponseBody
+    public void batchGrant(@PathVariable String type, @PathVariable String 
uuid,
+            @RequestBody List<Object[]> reqs) throws IOException {
+        Map<Sid, Permission> sidToPerm = new HashMap<>();
+        AclEntity ae = accessService.getAclEntity(type, uuid);
+        for (Object[] req : reqs) {
+            Preconditions.checkArgument(req.length == 3, "error access 
requests.");
+            String name = (String) req[0];
+            boolean isPrincipal = (boolean) req[1];
+            validateUtil.checkIdentifiersExists(name, isPrincipal);
+
+            Sid sid = accessService.getSid(name, isPrincipal);
+            Permission permission = 
AclPermissionFactory.getPermission((String) req[2]);
+            sidToPerm.put(sid, permission);
+        }
+        accessService.batchGrant(ae, sidToPerm);
+    }
+
+    /**
      * Update a access on a domain object
      * 
      * @param accessRequest
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java 
b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
index 09a89c8..dfac275 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
@@ -100,6 +100,29 @@ public class AccessService {
 
     @Transactional
     @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#ae, 
'ADMINISTRATION')")
+    public void batchGrant(AclEntity ae, Map<Sid, Permission> sidToPerm) {
+        Message msg = MsgPicker.getMsg();
+
+        if (ae == null)
+            throw new BadRequestException(msg.getACL_DOMAIN_NOT_FOUND());
+        if (sidToPerm == null)
+            throw new BadRequestException(msg.getACL_PERMISSION_REQUIRED());
+
+        MutableAclRecord acl;
+        try {
+            acl = aclService.readAcl(new ObjectIdentityImpl(ae));
+        } catch (NotFoundException e) {
+            acl = init(ae, null);
+        }
+
+        for (Sid sid : sidToPerm.keySet()) {
+            secureOwner(acl, sid);
+        }
+        aclService.batchUpsertAce(acl, sidToPerm);
+    }
+
+    @Transactional
+    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#ae, 
'ADMINISTRATION')")
     public MutableAclRecord grant(AclEntity ae, Permission permission, Sid 
sid) {
         Message msg = MsgPicker.getMsg();
 
@@ -304,9 +327,6 @@ public class AccessService {
 
     /**
      * Protect admin permission granted to acl owner.
-     *
-     * @param acl
-     * @param indexOfAce
      */
     private void secureOwner(MutableAclRecord acl, Sid sid) {
         Message msg = MsgPicker.getMsg();
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java 
b/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
index adc7c30..f3e2393 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
@@ -243,6 +243,17 @@ public class AclService implements MutableAclService, 
InitializingBean {
         });
     }
 
+    void batchUpsertAce(MutableAclRecord acl, final Map<Sid, Permission> 
sidToPerm) {
+        updateAclWithRetry(acl, new AclRecordUpdater() {
+            @Override
+            public void update(AclRecord record) {
+                for (Sid sid : sidToPerm.keySet()) {
+                    record.upsertAce(sidToPerm.get(sid), sid);
+                }
+            }
+        });
+    }
+
     MutableAclRecord inherit(MutableAclRecord acl, final MutableAclRecord 
parentAcl) {
         return updateAclWithRetry(acl, new AclRecordUpdater() {
             @Override
diff --git 
a/server/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java 
b/server/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java
index 8f18ed1..52f5cd2 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java
@@ -22,7 +22,9 @@ import static 
org.apache.kylin.rest.security.AclEntityType.PROJECT_INSTANCE;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.kylin.common.persistence.AclEntity;
 import org.apache.kylin.common.persistence.RootPersistentEntity;
@@ -31,6 +33,7 @@ import org.apache.kylin.metadata.project.ProjectInstance;
 import org.apache.kylin.rest.response.AccessEntryResponse;
 import org.apache.kylin.rest.security.AclPermission;
 import org.apache.kylin.rest.security.AclPermissionFactory;
+import org.apache.kylin.rest.security.springacl.MutableAclRecord;
 import org.apache.kylin.rest.service.AclServiceTest.MockAclEntity;
 import org.junit.Assert;
 import org.junit.Ignore;
@@ -40,6 +43,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.acls.domain.PrincipalSid;
 import org.springframework.security.acls.model.AccessControlEntry;
 import org.springframework.security.acls.model.Acl;
+import org.springframework.security.acls.model.Permission;
 import org.springframework.security.acls.model.Sid;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -148,6 +152,22 @@ public class AccessServiceTest extends ServiceTestBase {
         Assert.assertNull(attachedEntityAcl);
     }
 
+    @Test
+    public void testBatchGrant() {
+        AclEntity ae = new AclServiceTest.MockAclEntity("batch-grant");
+        final Map<Sid, Permission> sidToPerm = new HashMap<>();
+        for (int i = 0; i < 10; i++) {
+            sidToPerm.put(new PrincipalSid("u" + i), 
AclPermission.ADMINISTRATION);
+        }
+        accessService.batchGrant(ae, sidToPerm);
+        MutableAclRecord acl = accessService.getAcl(ae);
+        List<AccessControlEntry> e = acl.getEntries();
+        Assert.assertEquals(10, e.size());
+        for (int i = 0; i < e.size(); i++) {
+            Assert.assertEquals(new PrincipalSid("u" + i), e.get(i).getSid());
+        }
+    }
+
     @Ignore
     @Test
     public void test100000Entries() throws JsonProcessingException {
diff --git 
a/server/src/test/java/org/apache/kylin/rest/service/AclServiceTest.java 
b/server/src/test/java/org/apache/kylin/rest/service/AclServiceTest.java
index 875a2a1..4aabee1 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/AclServiceTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/AclServiceTest.java
@@ -18,7 +18,10 @@
 
 package org.apache.kylin.rest.service;
 
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.kylin.common.persistence.AclEntity;
 import org.apache.kylin.rest.security.AclPermission;
@@ -33,8 +36,12 @@ import 
org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.acls.domain.GrantedAuthoritySid;
 import org.springframework.security.acls.domain.PrincipalSid;
 import org.springframework.security.acls.model.AccessControlEntry;
+import org.springframework.security.acls.model.Acl;
 import org.springframework.security.acls.model.AlreadyExistsException;
 import org.springframework.security.acls.model.NotFoundException;
+import org.springframework.security.acls.model.ObjectIdentity;
+import org.springframework.security.acls.model.Permission;
+import org.springframework.security.acls.model.Sid;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -132,6 +139,26 @@ public class AclServiceTest extends ServiceTestBase {
         }
     }
 
+    @Test
+    public void testBatchUpsertAce() {
+        switchToAdmin();
+        ObjectIdentity oid = oid("acl");
+        MutableAclRecord acl = (MutableAclRecord) aclService.createAcl(oid);
+        final Map<Sid, Permission> sidToPerm = new HashMap<>();
+        for (int i = 0; i < 10; i++) {
+            sidToPerm.put(new PrincipalSid("u" + i), 
AclPermission.ADMINISTRATION);
+        }
+        aclService.batchUpsertAce(acl, sidToPerm);
+
+        for (Acl a : 
aclService.readAclsById(Collections.singletonList(oid)).values()) {
+            List<AccessControlEntry> e = a.getEntries();
+            Assert.assertEquals(10, e.size());
+            for (int i = 0; i < e.size(); i++) {
+                Assert.assertEquals(new PrincipalSid("u" + i), 
e.get(i).getSid());
+            }
+        }
+    }
+
     private void switchToAdmin() {
         Authentication adminAuth = new TestingAuthenticationToken("ADMIN", 
"ADMIN", "ROLE_ADMIN");
         SecurityContextHolder.getContext().setAuthentication(adminAuth);

-- 
To stop receiving notification emails like this one, please contact
billy...@apache.org.

Reply via email to