Ranger-201:Update UserSync to optimize the REST calls made to sync users and group
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/2203ffbe Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/2203ffbe Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/2203ffbe Branch: refs/heads/stack Commit: 2203ffbeb756e63781c7806edcdada28ea415817 Parents: a0d23c7 Author: rmani <[email protected]> Authored: Fri Dec 19 23:40:07 2014 -0800 Committer: rmani <[email protected]> Committed: Fri Dec 19 23:40:07 2014 -0800 ---------------------------------------------------------------------- .../java/org/apache/ranger/biz/XUserMgr.java | 27 +++ .../java/org/apache/ranger/rest/XUserREST.java | 8 + .../org/apache/ranger/view/VXUserGroupInfo.java | 66 ++++++ .../org/apache/ranger/biz/TestXUserMgr.java | 51 +++++ .../config/UserGroupSyncConfig.java | 6 + .../unixusersync/model/UserGroupInfo.java | 41 ++++ .../unixusersync/model/UserGroupList.java | 57 ++++++ .../process/FileSourceUserGroupBuilder.java | 161 +++++++++++++++ .../process/PolicyMgrUserGroupBuilder.java | 204 ++++++++++--------- .../conf.dist/unixauthservice.properties | 9 +- 10 files changed, 538 insertions(+), 92 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java index 64ae9b3..fa03f2f 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java @@ -42,6 +42,7 @@ import org.apache.ranger.view.VXGroupUser; import org.apache.ranger.view.VXGroupUserList; import org.apache.ranger.view.VXPortalUser; import org.apache.ranger.view.VXUser; +import org.apache.ranger.view.VXUserGroupInfo; import org.apache.ranger.view.VXUserList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -299,6 +300,32 @@ public class XUserMgr extends XUserMgrBase { return vXUser; } + + public VXUserGroupInfo createXUserGroupFromMap(VXUserGroupInfo vXUserGroupInfo) { + + VXUserGroupInfo vxUGInfo = new VXUserGroupInfo(); + + VXUser vXUser = vXUserGroupInfo.getXuserInfo(); + + vXUser = xUserService.createXUserWithOutLogin(vXUser); + + vxUGInfo.setXuserInfo(vXUser); + + List<VXGroup> vxg = new ArrayList<VXGroup>(); + + for(VXGroup vXGroup : vXUserGroupInfo.getXgroupInfo()){ + VXGroup VvXGroup = xGroupService.createXGroupWithOutLogin(vXGroup); + vxg.add(VvXGroup); + VXGroupUser vXGroupUser = new VXGroupUser(); + vXGroupUser.setUserId(vXUser.getId()); + vXGroupUser.setName(VvXGroup.getName()); + vXGroupUser = xGroupUserService.createXGroupUserWithOutLogin(vXGroupUser); + } + + vxUGInfo.setXgroupInfo(vxg); + + return vxUGInfo; + } public VXUser createXUserWithOutLogin(VXUser vXUser) { return xUserService.createXUserWithOutLogin(vXUser); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java b/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java index 5e6243e..9ebdd63 100644 --- a/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java +++ b/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java @@ -60,6 +60,7 @@ import org.apache.ranger.view.VXLong; import org.apache.ranger.view.VXPermMap; import org.apache.ranger.view.VXPermMapList; import org.apache.ranger.view.VXUser; +import org.apache.ranger.view.VXUserGroupInfo; import org.apache.ranger.view.VXUserList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @@ -218,6 +219,13 @@ public class XUserREST { } @POST + @Path("/users/userinfo") + @Produces({ "application/xml", "application/json" }) + public VXUserGroupInfo createXUserGroupFromMap(VXUserGroupInfo vXUserGroupInfo) { + return xUserMgr.createXUserGroupFromMap(vXUserGroupInfo); + } + + @POST @Path("/secure/users") @Produces({ "application/xml", "application/json" }) public VXUser secureCreateXUser(VXUser vXUser) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java b/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java new file mode 100644 index 0000000..09cc1aa --- /dev/null +++ b/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + package org.apache.ranger.view; + +/** + * UserGroupInfo + * + */ + +import java.util.List; + +import javax.xml.bind.annotation.*; + +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +@JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY) +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL ) +@JsonIgnoreProperties(ignoreUnknown=true) +@XmlRootElement +public class VXUserGroupInfo extends VXDataObject implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + VXUser xuserInfo; + List<VXGroup> xgroupInfo; + + public VXUserGroupInfo ( ) { + } + + public VXUser getXuserInfo() { + return xuserInfo; + } + + public void setXuserInfo(VXUser xuserInfo) { + this.xuserInfo = xuserInfo; + } + + public List<VXGroup> getXgroupInfo() { + return xgroupInfo; + } + + public void setXgroupInfo(List<VXGroup> xgroupInfo) { + this.xgroupInfo = xgroupInfo; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java ---------------------------------------------------------------------- diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java index 972e7b7..b05ebb4 100644 --- a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java +++ b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java @@ -18,6 +18,7 @@ package org.apache.ranger.biz; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import org.apache.ranger.common.ContextUtil; import org.apache.ranger.common.RESTErrorUtil; @@ -40,6 +41,7 @@ import org.apache.ranger.view.VXGroupUser; import org.apache.ranger.view.VXGroupUserList; import org.apache.ranger.view.VXPortalUser; import org.apache.ranger.view.VXUser; +import org.apache.ranger.view.VXUserGroupInfo; import org.apache.ranger.view.VXUserList; import org.junit.Assert; import org.junit.FixMethodOrder; @@ -393,4 +395,53 @@ public class TestXUserMgr { Mockito.verify(xGroupUserService).searchXGroupUsers((SearchCriteria) Mockito .anyObject()); } + + @Test + public void test24CreateVXUserGroupInfo(){ + + VXUserGroupInfo vXUserGroupInfo = new VXUserGroupInfo(); + VXUser vXUser = new VXUser(); + vXUser.setName("user1"); + vXUser.setDescription("testuser1 -added for unit testing"); + + List<VXGroupUser> vXGroupUserList = new ArrayList<VXGroupUser>(); + List<VXGroup> vXGroupList = new ArrayList<VXGroup>(); + + final VXGroup vXGroup1 = new VXGroup(); + vXGroup1.setName("users"); + vXGroup1.setDescription("users -added for unit testing"); + vXGroupList.add(vXGroup1); + + VXGroupUser vXGroupUser1 = new VXGroupUser(); + vXGroupUser1.setName("users"); + vXGroupUserList.add(vXGroupUser1); + + final VXGroup vXGroup2 = new VXGroup(); + vXGroup2.setName("user1"); + vXGroup2.setDescription("user1 -added for unit testing"); + vXGroupList.add(vXGroup2); + + VXGroupUser vXGroupUser2 = new VXGroupUser(); + vXGroupUser2.setName("user1"); + vXGroupUserList.add(vXGroupUser2); + + vXUserGroupInfo.setXuserInfo(vXUser); + vXUserGroupInfo.setXgroupInfo(vXGroupList); + + Mockito.when(xUserService.createXUserWithOutLogin(vXUser)).thenReturn(vXUser); + Mockito.when(xGroupService.createXGroupWithOutLogin(vXGroup1)).thenReturn(vXGroup1); + Mockito.when(xGroupService.createXGroupWithOutLogin(vXGroup2)).thenReturn(vXGroup2); + Mockito.when(xGroupUserService.createXGroupUserWithOutLogin(vXGroupUser1)).thenReturn(vXGroupUser1); + Mockito.when(xGroupUserService.createXGroupUserWithOutLogin(vXGroupUser2)).thenReturn(vXGroupUser2); + + VXUserGroupInfo vxUserGroupTest = xUserMgr.createXUserGroupFromMap(vXUserGroupInfo); + Assert.assertEquals("user1", vxUserGroupTest + .getXuserInfo() + .getName()); + List<VXGroup> result = vxUserGroupTest.getXgroupInfo(); + List<VXGroup> expected = new ArrayList<VXGroup>(); + expected.add(vXGroup1); + expected.add(vXGroup2); + Assert.assertTrue(result.containsAll(expected)); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java ---------------------------------------------------------------------- diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java index b9ea343..28372f1 100644 --- a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java @@ -46,6 +46,8 @@ public class UserGroupSyncConfig { public static final String UGSYNC_MOCK_RUN_PROP = "usergroupSync.policymanager.mockRun" ; + public static final String UGSYNC_SOURCE_FILE_PROC = "usergroupSync.filesource.file"; + private static final String SSL_KEYSTORE_PATH_PARAM = "keyStore" ; private static final String SSL_KEYSTORE_PATH_PASSWORD_PARAM = "keyStorePassword" ; @@ -174,6 +176,10 @@ public class UserGroupSyncConfig { return ret; } + public String getUserSyncFileSource(){ + String val = prop.getProperty(UGSYNC_SOURCE_FILE_PROC) ; + return val; + } public boolean isUserSyncEnabled() { String val = prop.getProperty(UGSYNC_ENABLED_PROP) ; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java ---------------------------------------------------------------------- diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java new file mode 100644 index 0000000..d720eae --- /dev/null +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.unixusersync.model; + +import java.util.List; + +public class UserGroupInfo { + + XUserInfo xuserInfo; + List<XGroupInfo> xgroupInfo; + + public XUserInfo getXuserInfo() { + return xuserInfo; + } + public void setXuserInfo(XUserInfo xuserInfo) { + this.xuserInfo = xuserInfo; + } + public List<XGroupInfo> getXgroupInfo() { + return xgroupInfo; + } + public void setXgroupInfo(List<XGroupInfo> xgroupInfo) { + this.xgroupInfo = xgroupInfo; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java ---------------------------------------------------------------------- diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java new file mode 100644 index 0000000..0eec94c --- /dev/null +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.unixusersync.model; + +import java.util.List; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +@JsonAutoDetect(getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, fieldVisibility = Visibility.ANY) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +@XmlRootElement +public class UserGroupList { + + String user; + + List<String> groups; + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public List<String> getGroups() { + return groups; + } + + public void setGroups(List<String> groups) { + this.groups = groups; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java ---------------------------------------------------------------------- diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java new file mode 100644 index 0000000..8ebe71c --- /dev/null +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.ranger.unixusersync.process; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.apache.ranger.unixusersync.config.UserGroupSyncConfig; +import org.apache.ranger.unixusersync.model.UserGroupList; +import org.apache.ranger.usergroupsync.UserGroupSink; +import org.apache.ranger.usergroupsync.UserGroupSource; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class FileSourceUserGroupBuilder implements UserGroupSource { + + private static final Logger LOG = Logger.getLogger(FileSourceUserGroupBuilder.class) ; + + public static String DEFAULT_USER_GROUP_FILE = null; + public static String USER_GROUP_FILE = null; + + private static boolean isManualRun=false; + private Map<String,List<String>> user2GroupListMap = new HashMap<String,List<String>>(); + private UserGroupSyncConfig config = UserGroupSyncConfig.getInstance() ; + private UserGroupSink ugSink = null ; + private long usergroupFileModified = 0 ; + + public static void main(String[] args) throws Throwable { + if (args.length > 0) { + isManualRun=true; + USER_GROUP_FILE = args[0]; + } + FileSourceUserGroupBuilder filesourceUGBuilder = new FileSourceUserGroupBuilder() ; + filesourceUGBuilder.init(); + if ( LOG.isDebugEnabled()) { + filesourceUGBuilder.print(); + } + } + + @Override + public void init() throws Throwable { + DEFAULT_USER_GROUP_FILE = config.getUserSyncFileSource(); + buildUserGroupInfo(); + if (isManualRun) { + ugSink = UserGroupSyncConfig.getInstance().getUserGroupSink(); + LOG.info("initializing sink: " + ugSink.getClass().getName()); + ugSink.init(); + updateSink(ugSink); + } + } + + private void print() { + for(String user : user2GroupListMap.keySet()) { + LOG.debug("USER:" + user) ; + List<String> groups = user2GroupListMap.get(user) ; + if (groups != null) { + for(String group : groups) { + LOG.debug("\tGROUP: " + group) ; + } + } + } + } + + @Override + public boolean isChanged() { + long TempUserGroupFileModifedAt = new File(DEFAULT_USER_GROUP_FILE).lastModified() ; + if (usergroupFileModified != TempUserGroupFileModifedAt) { + return true ; + } + return false; + } + + @Override + public void updateSink(UserGroupSink sink) throws Throwable { + buildUserGroupInfo() ; + for (Map.Entry<String, List<String>> entry : user2GroupListMap.entrySet()) { + String user = entry.getKey(); + List<String> groups = entry.getValue(); + sink.addOrUpdateUser(user, groups); + } + } + + public void buildUserGroupInfo() throws Throwable { + user2GroupListMap = new HashMap<String,List<String>>(); + buildUserGroupList(); + if ( LOG.isDebugEnabled()) { + print(); + } + } + + public void buildUserGroupList() throws Throwable { + + Gson gson = new GsonBuilder().create() ; + + UserGroupList usergrouplist = new UserGroupList(); + + String usergroupFile = null; + + if (isManualRun) { + usergroupFile = USER_GROUP_FILE; + } else { + usergroupFile = DEFAULT_USER_GROUP_FILE; + } + + if (usergroupFile == null){ + throw new Exception("User Group Source File is not Configured. Please maintain in unixauthservice.properties or pass it as command line argument for org.apache.ranger.unixusersync.process.FileSourceUserGroupBuilder"); + } + + File f = new File(usergroupFile); + + if (f.exists()) { + + BufferedReader bfr = new BufferedReader(new FileReader(f)); + + String line = null ; + + while ((line = bfr.readLine()) != null) { + + if (line.trim().isEmpty()) + continue ; + + usergrouplist = gson.fromJson(line,UserGroupList.class); + + String user = usergrouplist.getUser(); + + List<String> groups = usergrouplist.getGroups(); + + if ( user != null) { + user2GroupListMap.put(user, groups); + } + } + + bfr.close(); + usergroupFileModified = f.lastModified() ; + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java ---------------------------------------------------------------------- diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java index db25943..acbee13 100644 --- a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java @@ -42,15 +42,6 @@ import javax.ws.rs.core.MediaType; import org.apache.log4j.Level; import org.apache.log4j.Logger; -import org.apache.ranger.unixusersync.config.UserGroupSyncConfig; -import org.apache.ranger.unixusersync.model.GetXGroupListResponse; -import org.apache.ranger.unixusersync.model.GetXUserGroupListResponse; -import org.apache.ranger.unixusersync.model.GetXUserListResponse; -import org.apache.ranger.unixusersync.model.MUserInfo; -import org.apache.ranger.unixusersync.model.XGroupInfo; -import org.apache.ranger.unixusersync.model.XUserGroupInfo; -import org.apache.ranger.unixusersync.model.XUserInfo; -import org.apache.ranger.usergroupsync.UserGroupSink; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -60,6 +51,16 @@ import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.client.urlconnection.HTTPSProperties; +import org.apache.ranger.unixusersync.config.UserGroupSyncConfig; +import org.apache.ranger.unixusersync.model.GetXGroupListResponse; +import org.apache.ranger.unixusersync.model.GetXUserGroupListResponse; +import org.apache.ranger.unixusersync.model.GetXUserListResponse; +import org.apache.ranger.unixusersync.model.MUserInfo; +import org.apache.ranger.unixusersync.model.XGroupInfo; +import org.apache.ranger.unixusersync.model.XUserGroupInfo; +import org.apache.ranger.unixusersync.model.XUserInfo; +import org.apache.ranger.unixusersync.model.UserGroupInfo; +import org.apache.ranger.usergroupsync.UserGroupSink; public class PolicyMgrUserGroupBuilder implements UserGroupSink { @@ -67,10 +68,12 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { public static final String PM_USER_LIST_URI = "/service/xusers/users/" ; // GET private static final String PM_ADD_USER_URI = "/service/xusers/users/" ; // POST + private static final String PM_ADD_USER_GROUP_INFO_URI = "/service/xusers/users/userinfo" ; // POST public static final String PM_GROUP_LIST_URI = "/service/xusers/groups/" ; // GET private static final String PM_ADD_GROUP_URI = "/service/xusers/groups/" ; // POST + public static final String PM_USER_GROUP_MAP_LIST_URI = "/service/xusers/groupusers/" ; // GET private static final String PM_ADD_USER_GROUP_LINK_URI = "/service/xusers/groupusers/" ; // POST @@ -85,6 +88,7 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { private UserGroupSyncConfig config = UserGroupSyncConfig.getInstance() ; + private UserGroupInfo usergroupInfo = new UserGroupInfo(); private List<XGroupInfo> xgroupList = new ArrayList<XGroupInfo>() ; private List<XUserInfo> xuserList = new ArrayList<XUserInfo>() ; private List<XUserGroupInfo> xusergroupList = new ArrayList<XUserGroupInfo>() ; @@ -162,7 +166,6 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { } - private void rebuildUserGroupMap() { for(XUserInfo user : xuserList) { @@ -173,9 +176,12 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { addGroupToList(group); } + for(XUserGroupInfo ug : xusergroupList) { addUserGroupToList(ug); } + + } @@ -210,7 +216,6 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { } - private void addUserGroupToList(XUserGroupInfo ugInfo) { String userId = ugInfo.getUserId() ; @@ -225,6 +230,21 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { } } } + + private void addUserGroupInfoToList(XUserInfo userInfo, XGroupInfo groupInfo) { + String userId = userInfo.getId(); + + if (userId != null) { + XUserInfo user = userId2XUserInfoMap.get(userId) ; + + if (user != null) { + List<String> groups = user.getGroups() ; + if (! groups.contains(groupInfo.getName())) { + groups.add(groupInfo.getName()) ; + } + } + } + } private void delUserGroupFromList(XUserInfo userInfo, XGroupInfo groupInfo) { List<String> groups = userInfo.getGroups() ; @@ -252,26 +272,20 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { } if (user == null) { // Does not exists + LOG.debug("INFO: addPMAccount(" + userName + ")" ) ; if (! isMockRun) { addMUser(userName) ; } - LOG.debug("INFO: addPMXAUser(" + userName + ")" ) ; - if (! isMockRun) { - user = addXUserInfo(userName) ; - } - - for(String g : groups) { - LOG.debug("INFO: addPMXAGroupToUser(" + userName + "," + g + ")" ) ; - } - if (! isMockRun ) { - addXUserGroupInfo(user, groups) ; + //* Build the user group info object and do the rest call + if ( ! isMockRun ) { + addUserGroupInfo(userName,groups); } + } else { // Validate group memberships List<String> oldGroups = user.getGroups() ; - List<String> addGroups = new ArrayList<String>() ; List<String> delGroups = new ArrayList<String>() ; @@ -414,108 +428,115 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { } + private UserGroupInfo addUserGroupInfo(String userName, List<String> groups){ - private XUserInfo addXUserInfo(String aUserName) { - XUserInfo ret = null ; + UserGroupInfo ret = null; - XUserInfo addUser = new XUserInfo() ; - addUser.setName(aUserName); - addUser.setDescription(aUserName + " - add from Unix box") ; + XUserInfo user = null; - Client c = getClient() ; - - WebResource r = c.resource(getURL(PM_ADD_USER_URI)) ; - - Gson gson = new GsonBuilder().create() ; + LOG.debug("INFO: addPMXAUser(" + userName + ")" ) ; + if (! isMockRun) { + user = addXUserInfo(userName) ; + } + + for(String g : groups) { + LOG.debug("INFO: addPMXAGroupToUser(" + userName + "," + g + ")" ) ; + } + if (! isMockRun ) { + addXUserGroupInfo(user, groups) ; + } + + Client c = new Client(); + + WebResource r = c.resource(getURL(PM_ADD_USER_GROUP_INFO_URI)); + + Gson gson = new GsonBuilder().create(); + + String jsonString = gson.toJson(usergroupInfo); + + LOG.debug("USER GROUP MAPPING" + jsonString); + + String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ; + + LOG.debug("RESPONSE: [" + response + "]") ; + + ret = gson.fromJson(response, UserGroupInfo.class); + + if ( ret != null) { + + XUserInfo xUserInfo = ret.getXuserInfo(); + addUserToList(xUserInfo); + + for(XGroupInfo xGroupInfo : ret.getXgroupInfo()) { + addGroupToList(xGroupInfo); + addUserGroupInfoToList(xUserInfo,xGroupInfo); + } + } + + return ret; + } - String jsonString = gson.toJson(addUser) ; - - String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ; - - LOG.debug("RESPONSE: [" + response + "]") ; - ret = gson.fromJson(response, XUserInfo.class) ; + private XUserInfo addXUserInfo(String aUserName) { + + XUserInfo xuserInfo = new XUserInfo() ; - if (ret != null) { - addUserToList(ret); - } + xuserInfo.setName(aUserName); - return ret ; + xuserInfo.setDescription(aUserName + " - add from Unix box") ; + + usergroupInfo.setXuserInfo(xuserInfo); + + return xuserInfo ; } + private XGroupInfo addXGroupInfo(String aGroupName) { - XGroupInfo ret = null ; - XGroupInfo addGroup = new XGroupInfo() ; + addGroup.setName(aGroupName); + addGroup.setDescription(aGroupName + " - add from Unix box") ; - addGroup.setGroupType("1") ; - Client c = getClient() ; - - WebResource r = c.resource(getURL(PM_ADD_GROUP_URI)) ; - - Gson gson = new GsonBuilder().create() ; - - String jsonString = gson.toJson(addGroup) ; - - String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ; - - LOG.debug("RESPONSE: [" + response + "]") ; + addGroup.setGroupType("1") ; - ret = gson.fromJson(response, XGroupInfo.class) ; - - if (ret != null) { - addGroupToList(ret); - } - - return ret ; + return addGroup ; } - - + private void addXUserGroupInfo(XUserInfo aUserInfo, List<String> aGroupList) { + + List<XGroupInfo> xGroupInfoList = new ArrayList<XGroupInfo>(); + for(String groupName : aGroupList) { XGroupInfo group = groupName2XGroupInfoMap.get(groupName) ; if (group == null) { group = addXGroupInfo(groupName) ; } + xGroupInfoList.add(group); addXUserGroupInfo(aUserInfo, group) ; } + + usergroupInfo.setXgroupInfo(xGroupInfoList); } + + - private XUserGroupInfo addXUserGroupInfo(XUserInfo aUserInfo, XGroupInfo aGroupInfo) { - - XUserGroupInfo ret = null ; + + private XUserGroupInfo addXUserGroupInfo(XUserInfo aUserInfo, XGroupInfo aGroupInfo) { - XUserGroupInfo ugInfo = new XUserGroupInfo() ; + XUserGroupInfo ugInfo = new XUserGroupInfo() ; ugInfo.setUserId(aUserInfo.getId()); - ugInfo.setGroupName(aGroupInfo.getName()) ; - // ugInfo.setParentGroupId("1"); - Client c = getClient() ; - - WebResource r = c.resource(getURL(PM_ADD_USER_GROUP_LINK_URI)) ; - - Gson gson = new GsonBuilder().create() ; - - String jsonString = gson.toJson(ugInfo) ; - - String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ; - - LOG.debug("RESPONSE: [" + response + "]") ; - - ret = gson.fromJson(response, XUserGroupInfo.class) ; - - if (ret != null) { - addUserGroupToList(ret); - } + ugInfo.setGroupName(aGroupInfo.getName()) ; - return ret ; + // ugInfo.setParentGroupId("1"); + return ugInfo ; } + private void delXUserGroupInfo(XUserInfo aUserInfo, List<String> aGroupList) { for(String groupName : aGroupList) { @@ -556,7 +577,7 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { userInfo.setFirstName(aUserName); userInfo.setLastName(aUserName); userInfo.setEmailAddress(aUserName + "@" + LOCAL_HOSTNAME); - + Client c = getClient() ; WebResource r = c.resource(getURL(PM_ADD_LOGIN_USER_URI)) ; @@ -574,10 +595,11 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink { LOG.debug("MUser Creation successful " + ret); return ret ; + } - + private synchronized Client getClient() { Client ret = null; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/unixauthservice/conf.dist/unixauthservice.properties ---------------------------------------------------------------------- diff --git a/unixauthservice/conf.dist/unixauthservice.properties b/unixauthservice/conf.dist/unixauthservice.properties index 993f80c..25b8887 100644 --- a/unixauthservice/conf.dist/unixauthservice.properties +++ b/unixauthservice/conf.dist/unixauthservice.properties @@ -74,12 +74,19 @@ usergroupSync.unix.minUserId = 500 usergroupSync.sleepTimeInMillisBetweenSyncCycle = # sync source class -# we provide 2 classes out of box +# we provide 3 classes out of box # org.apache.ranger.unixusersync.process.UnixUserGroupBuilder # org.apache.ranger.ldapusersync.process.LdapUserGroupBuilder +# org.apache.ranger.unixusersync.process.FileSourceUserGroupBuilder # default value: org.apache.ranger.unixusersync.process.UnixUserGroupBuilder usergroupSync.source.impl.class = +# --------------------------------------------------------------- +# The following properties are relevant +# only if value of usergroupSync.source.impl.class is +# org.apache.ranger.unixusersync.process.FileSourceUserGroupBuilder +# --------------------------------------------------------------- +usergroupSync.filesource.file = # --------------------------------------------------------------- # The following properties are relevant
