You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by sp...@apache.org on 2020/02/13 17:21:57 UTC
[ranger] branch master updated: RANGER-2697: Usersync and Ranger
admin changes to support retriving additional user/group attributes from
LDAP/AD
This is an automated email from the ASF dual-hosted git repository.
spolavarapu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new dc63813 RANGER-2697: Usersync and Ranger admin changes to support retriving additional user/group attributes from LDAP/AD
dc63813 is described below
commit dc6381372bc49bfdfe8586f24102b7d3c376ca58
Author: Sailaja Polavarapu <sp...@cloudera.com>
AuthorDate: Thu Feb 13 09:21:35 2020 -0800
RANGER-2697: Usersync and Ranger admin changes to support retriving additional user/group attributes from LDAP/AD
---
.../org/apache/ranger/plugin/model/GroupInfo.java | 87 ++++++++++
.../ranger/plugin/model/RangerPluginInfo.java | 56 ++++++-
.../org/apache/ranger/plugin/model/UserInfo.java | 95 +++++++++++
.../apache/ranger/plugin/util/RangerUserStore.java | 186 +++++++++++++++++++++
.../ranger/plugin/util/RangerUserStoreUtil.java | 60 +++++++
.../main/java/org/apache/ranger/biz/AssetMgr.java | 49 +++++-
.../java/org/apache/ranger/biz/RoleDBStore.java | 2 +-
.../java/org/apache/ranger/biz/ServiceDBStore.java | 2 +-
.../main/java/org/apache/ranger/biz/UserMgr.java | 3 +
.../main/java/org/apache/ranger/biz/XUserMgr.java | 59 +++++--
.../apache/ranger/common/RangerUserStoreCache.java | 122 ++++++++++++++
.../org/apache/ranger/db/XXGlobalStateDao.java | 40 ++---
.../java/org/apache/ranger/rest/XUserREST.java | 111 ++++++++++++
.../apache/ranger/service/XGroupServiceBase.java | 20 +++
.../apache/ranger/service/XUserServiceBase.java | 20 +++
.../process/LdapDeltaUserGroupBuilder.java | 127 ++++++++++++--
.../process/LdapPolicyMgrUserGroupBuilder.java | 70 ++++----
.../ldapusersync/process/LdapUserGroupBuilder.java | 4 +-
.../unixusersync/config/UserGroupSyncConfig.java | 92 ++++++++++
.../ranger/unixusersync/model/MUserInfo.java | 10 +-
.../ranger/unixusersync/model/XGroupInfo.java | 11 +-
.../ranger/unixusersync/model/XUserInfo.java | 11 +-
.../process/PolicyMgrUserGroupBuilder.java | 14 +-
.../apache/ranger/usergroupsync/UserGroupSink.java | 7 +-
.../LdapPolicyMgrUserGroupBuilderTest.java | 10 +-
.../PolicyMgrUserGroupBuilderTest.java | 8 +-
26 files changed, 1172 insertions(+), 104 deletions(-)
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/GroupInfo.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/GroupInfo.java
new file mode 100644
index 0000000..5925014
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/GroupInfo.java
@@ -0,0 +1,87 @@
+/*
+ * 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.plugin.model;
+
+import org.apache.ranger.plugin.util.RangerUserStoreUtil;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class GroupInfo extends RangerBaseModelObject implements java.io.Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private String name;
+ private String description;
+ private Map<String, String> otherAttributes;
+
+ public GroupInfo() {
+ this(null, null, null);
+ }
+
+ public GroupInfo(String name, String description, Map<String, String> otherAttributes) {
+ setName(name);
+ setDescription(description);
+ setOtherAttributes(otherAttributes);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Map<String, String> getOtherAttributes() {
+ return otherAttributes;
+ }
+
+ public void setOtherAttributes(Map<String, String> otherAttributes) {
+ this.otherAttributes = otherAttributes == null ? new HashMap<>() : otherAttributes;
+ }
+
+ @Override
+ public String toString() {
+ return "{name=" + name
+ + ", description=" + description
+ + ", otherAttributes=" + RangerUserStoreUtil.getPrintableOptions(otherAttributes)
+ + "}";
+ }
+
+}
\ No newline at end of file
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java
index 5552ce9..5b92566 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java
@@ -41,9 +41,10 @@ import java.util.Map;
public class RangerPluginInfo implements Serializable {
private static final long serialVersionUID = 1L;
- public static final int ENTITY_TYPE_POLICIES = 0;
- public static final int ENTITY_TYPE_TAGS = 1;
- public static final int ENTITY_TYPE_ROLES = 2;
+ public static final int ENTITY_TYPE_POLICIES = 0;
+ public static final int ENTITY_TYPE_TAGS = 1;
+ public static final int ENTITY_TYPE_ROLES = 2;
+ public static final int ENTITY_TYPE_USERSTORE = 3;
public static final String PLUGIN_INFO_POLICY_DOWNLOAD_TIME = "policyDownloadTime";
public static final String PLUGIN_INFO_POLICY_DOWNLOADED_VERSION = "policyDownloadedVersion";
@@ -59,6 +60,11 @@ public class RangerPluginInfo implements Serializable {
public static final String PLUGIN_INFO_ROLE_ACTIVATION_TIME = "roleActivationTime";
public static final String PLUGIN_INFO_ROLE_ACTIVE_VERSION = "roleActiveVersion";
+ public static final String PLUGIN_INFO_USERSTORE_DOWNLOAD_TIME = "userstoreDownloadTime";
+ public static final String PLUGIN_INFO_USERSTORE_DOWNLOADED_VERSION = "userstoreDownloadedVersion";
+ public static final String PLUGIN_INFO_USERSTORE_ACTIVATION_TIME = "userstoreActivationTime";
+ public static final String PLUGIN_INFO_USERSTORE_ACTIVE_VERSION = "userstoreActiveVersion";
+
public static final String RANGER_ADMIN_LAST_POLICY_UPDATE_TIME = "lastPolicyUpdateTime";
public static final String RANGER_ADMIN_LATEST_POLICY_VERSION = "latestPolicyVersion";
public static final String RANGER_ADMIN_LAST_TAG_UPDATE_TIME = "lastTagUpdateTime";
@@ -344,6 +350,50 @@ public class RangerPluginInfo implements Serializable {
}
@JsonIgnore
+ public void setUserStoreDownloadTime(Long userstoreDownloadTime) {
+ getInfo().put(PLUGIN_INFO_USERSTORE_DOWNLOAD_TIME, userstoreDownloadTime == null ? null : Long.toString(userstoreDownloadTime));
+ }
+
+ @JsonIgnore
+ public Long getUserStoreDownloadTime() {
+ String downloadTimeString = getInfo().get(PLUGIN_INFO_USERSTORE_DOWNLOAD_TIME);
+ return StringUtils.isNotBlank(downloadTimeString) ? Long.valueOf(downloadTimeString) : null;
+ }
+
+ @JsonIgnore
+ public void setUserStoreDownloadedVersion(Long userstoreDownloadedVersion) {
+ getInfo().put(PLUGIN_INFO_USERSTORE_DOWNLOADED_VERSION, userstoreDownloadedVersion == null ? null : Long.toString(userstoreDownloadedVersion));
+ }
+
+ @JsonIgnore
+ public Long getUserStoreDownloadedVersion() {
+ String downloadedVersionString = getInfo().get(PLUGIN_INFO_USERSTORE_DOWNLOADED_VERSION);
+ return StringUtils.isNotBlank(downloadedVersionString) ? Long.valueOf(downloadedVersionString) : null;
+ }
+
+ @JsonIgnore
+ public void setUserStoreActivationTime(Long userstoreActivationTime) {
+ getInfo().put(PLUGIN_INFO_USERSTORE_ACTIVATION_TIME, userstoreActivationTime == null ? null : Long.toString(userstoreActivationTime));
+ }
+
+ @JsonIgnore
+ public Long getUserStoreActivationTime() {
+ String activationTimeString = getInfo().get(PLUGIN_INFO_USERSTORE_ACTIVATION_TIME);
+ return StringUtils.isNotBlank(activationTimeString) ? Long.valueOf(activationTimeString) : null;
+ }
+
+ @JsonIgnore
+ public void setUserStoreActiveVersion(Long userstoreActiveVersion) {
+ getInfo().put(PLUGIN_INFO_USERSTORE_ACTIVE_VERSION, userstoreActiveVersion == null ? null : Long.toString(userstoreActiveVersion));
+ }
+
+ @JsonIgnore
+ public Long getUserStoreActiveVersion() {
+ String activeVersionString = getInfo().get(PLUGIN_INFO_USERSTORE_ACTIVE_VERSION);
+ return StringUtils.isNotBlank(activeVersionString) ? Long.valueOf(activeVersionString) : null;
+ }
+
+ @JsonIgnore
public void setPluginCapabilities(String capabilities) {
setCapabilities(PLUGIN_INFO_CAPABILITIES, capabilities);
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/UserInfo.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/UserInfo.java
new file mode 100644
index 0000000..3e933e8
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/UserInfo.java
@@ -0,0 +1,95 @@
+/*
+ * 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.plugin.model;
+
+import org.apache.ranger.plugin.util.RangerUserStoreUtil;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.*;
+
+@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class UserInfo extends RangerBaseModelObject implements java.io.Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private String name;
+ private String description;
+ private Map<String, String> otherAttributes;
+ private Set<String> groups;
+
+ public UserInfo() {
+ this(null, null, null);
+ }
+
+ public UserInfo(String name, String description, Map<String, String> otherAttributes) {
+ setName(name);
+ setDescription(description);
+ setOtherAttributes(otherAttributes);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Map<String, String> getOtherAttributes() {
+ return otherAttributes;
+ }
+
+ public void setOtherAttributes(Map<String, String> otherAttributes) {
+ this.otherAttributes = otherAttributes == null ? new HashMap<>() : otherAttributes;
+ }
+
+ public Set<String> getGroups(){
+ return this.groups;
+ }
+
+ public void setGroups(Set<String> groups){
+ this.groups = groups;
+ }
+
+ @Override
+ public String toString() {
+ return "{name=" + name
+ + ", description=" + description
+ + ", otherAttributes=" + RangerUserStoreUtil.getPrintableOptions(otherAttributes)
+ + ", groups=" + groups
+ + "}";
+ }
+}
\ No newline at end of file
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerUserStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerUserStore.java
new file mode 100644
index 0000000..dfe742f
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerUserStore.java
@@ -0,0 +1,186 @@
+/*
+ * 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.plugin.util;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.model.GroupInfo;
+import org.apache.ranger.plugin.model.UserInfo;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+@JsonAutoDetect(fieldVisibility= JsonAutoDetect.Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RangerUserStore implements Serializable {
+ private static final long serialVersionUID = 1L;
+ public static final String CLOUD_IDENTITY_NAME = "cloud_id";
+
+ private Long userStoreVersion;
+ private Date userStoreUpdateTime;
+ private Map<String, Map<String, String>> userAttrMapping;
+ private Map<String, Map<String, String>> groupAttrMapping ;
+ private Map<String, Set<String>> userGroupMapping;
+ private Map<String, String> userCloudIdMapping;
+ private Map<String, String> groupCloudIdMapping;
+
+ public RangerUserStore() {this(-1L, null, null);}
+
+ public RangerUserStore(Long userStoreVersion, Set<UserInfo> users, Set<GroupInfo> groups ) {
+ setUserStoreVersion(userStoreVersion);
+ setUserStoreUpdateTime(new Date());
+ buildMap(users, groups);
+ }
+ public Long getUserStoreVersion() {
+ return userStoreVersion;
+ }
+
+ public void setUserStoreVersion(Long userStoreVersion) {
+ this.userStoreVersion = userStoreVersion;
+ }
+
+ public Date getUserStoreUpdateTime() {
+ return userStoreUpdateTime;
+ }
+
+ public void setUserStoreUpdateTime(Date userStoreUpdateTime) {
+ this.userStoreUpdateTime = userStoreUpdateTime;
+ }
+
+ public Map<String, Map<String, String>> getUserAttrMapping() {
+ return userAttrMapping;
+ }
+
+ public void setUserAttrMapping(Map<String, Map<String, String>> userAttrMapping) {
+ this.userAttrMapping = userAttrMapping;
+ }
+
+ public Map<String, Map<String, String>> getGroupAttrMapping() {
+ return groupAttrMapping;
+ }
+
+ public void setGroupAttrMapping(Map<String, Map<String, String>> groupAttrMapping) {
+ this.groupAttrMapping = groupAttrMapping;
+ }
+
+ public Map<String, Set<String>> getUserGroupMapping() {
+ return userGroupMapping;
+ }
+
+ public void setUserGroupMapping(Map<String, Set<String>> userGroupMapping) {
+ this.userGroupMapping = userGroupMapping;
+ }
+
+ public Map<String, String> getUserCloudIdMapping() {
+ return userCloudIdMapping;
+ }
+
+ public void setUserCloudIdMapping(Map<String, String> userCloudIdMapping) {
+ this.userCloudIdMapping = userCloudIdMapping;
+ }
+
+ public Map<String, String> getGroupCloudIdMapping() {
+ return groupCloudIdMapping;
+ }
+
+ public void setGroupCloudIdMapping(Map<String, String> groupCloudIdMapping) {
+ this.groupCloudIdMapping = groupCloudIdMapping;
+ }
+
+ @Override
+ public String toString( ) {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerUserStore={")
+ .append("userStoreVersion=").append(userStoreVersion).append(", ")
+ .append("userStoreUpdateTime=").append(userStoreUpdateTime).append(", ");
+ sb.append("users={");
+ if(MapUtils.isNotEmpty(userAttrMapping)) {
+ for(String user : userAttrMapping.keySet()) {
+ sb.append(user);
+ }
+ }
+ sb.append("}, ");
+ sb.append("groups={");
+ if(MapUtils.isNotEmpty(groupAttrMapping)) {
+ for(String group : groupAttrMapping.keySet()) {
+ sb.append(group);
+ }
+ }
+ sb.append("}");
+ sb.append("}");
+
+ return sb;
+ }
+
+ private void buildMap(Set<UserInfo> users, Set<GroupInfo> groups) {
+ if (CollectionUtils.isNotEmpty(users)) {
+ userAttrMapping = new HashMap<>();
+ userCloudIdMapping = new HashMap<>();
+ userGroupMapping = new HashMap<>();
+ for (UserInfo user : users) {
+ String username = user.getName();
+ Map<String, String> userAttrs = user.getOtherAttributes();
+ if (MapUtils.isNotEmpty(userAttrs)) {
+ userAttrMapping.put(username, userAttrs);
+ String cloudId = userAttrs.get(CLOUD_IDENTITY_NAME);
+ if (StringUtils.isNotEmpty(cloudId)) {
+ userCloudIdMapping.put(cloudId, username);
+ }
+ }
+ userGroupMapping.put(username, user.getGroups());
+ }
+ }
+ if (CollectionUtils.isNotEmpty(groups)) {
+ groupAttrMapping = new HashMap<>();
+ groupCloudIdMapping = new HashMap<>();
+ for (GroupInfo group : groups) {
+ String groupname = group.getName();
+ Map<String, String> groupAttrs = group.getOtherAttributes();
+ if (MapUtils.isNotEmpty(groupAttrs)) {
+ groupAttrMapping.put(groupname, groupAttrs);
+ String cloudId = groupAttrs.get(CLOUD_IDENTITY_NAME);
+ if (StringUtils.isNotEmpty(cloudId)) {
+ groupCloudIdMapping.put(cloudId, groupname);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerUserStoreUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerUserStoreUtil.java
new file mode 100644
index 0000000..f66eb1f
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerUserStoreUtil.java
@@ -0,0 +1,60 @@
+/*
+ * 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.plugin.util;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+
+import java.util.Map;
+
+public class RangerUserStoreUtil {
+ public static final String CLOUD_IDENTITY_NAME = "cloud_id";
+
+ public static String getPrintableOptions(Map<String, String> otherAttributes) {
+ if (MapUtils.isEmpty(otherAttributes)) return "{}";
+ StringBuilder ret = new StringBuilder();
+ ret.append("{");
+ for (Map.Entry<String, String> entry : otherAttributes.entrySet()) {
+ ret.append(entry.getKey()).append(", ").append("[").append(entry.getValue()).append("]").append(",");
+ }
+ ret.append("}");
+ return ret.toString();
+ }
+
+ public static String getAttrVal(Map<String, Map<String, String>> attrMap, String name, String attrName) {
+ String ret = null;
+
+ if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(attrName)) {
+ Map<String, String> attrs = attrMap.get(name);
+ if (MapUtils.isNotEmpty(attrs)) {
+ ret = attrs.get(attrName);
+ }
+ }
+ return ret;
+ }
+
+ public String getCloudId(Map<String, Map<String, String>> attrMap, String name) {
+ String cloudId = null;
+ cloudId = getAttrVal(attrMap, name, CLOUD_IDENTITY_NAME);
+ return cloudId;
+ }
+}
+
+
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
index 0f44888..17c105f 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
@@ -707,6 +707,12 @@ public class AssetMgr extends AssetMgrBase {
pluginSvcVersionInfo.setRoleDownloadedVersion(downloadedVersion);
pluginSvcVersionInfo.setRoleDownloadTime(new Date().getTime());
break;
+ case RangerPluginInfo.ENTITY_TYPE_USERSTORE:
+ pluginSvcVersionInfo.setUserStoreActiveVersion(lastKnownVersion);
+ pluginSvcVersionInfo.setUserStoreActivationTime(lastActivationTime);
+ pluginSvcVersionInfo.setUserStoreDownloadedVersion(downloadedVersion);
+ pluginSvcVersionInfo.setUserStoreDownloadTime(new Date().getTime());
+ break;
}
createOrUpdatePluginInfo(pluginSvcVersionInfo, entityType , httpCode, clusterName);
@@ -735,6 +741,9 @@ public class AssetMgr extends AssetMgrBase {
case RangerPluginInfo.ENTITY_TYPE_ROLES:
isTagVersionResetNeeded = false;
break;
+ case RangerPluginInfo.ENTITY_TYPE_USERSTORE:
+ isTagVersionResetNeeded = false;
+ break;
default:
isTagVersionResetNeeded = false;
break;
@@ -751,7 +760,8 @@ public class AssetMgr extends AssetMgrBase {
Runnable commitWork;
if ((isPolicyDownloadRequest(entityType) && (pluginInfo.getPolicyActiveVersion() == null || pluginInfo.getPolicyActiveVersion() == -1))
|| (isTagDownloadRequest(entityType) && (pluginInfo.getTagActiveVersion() == null || pluginInfo.getTagActiveVersion() == -1))
- || (isRoleDownloadRequest(entityType) && (pluginInfo.getRoleActiveVersion() == null || pluginInfo.getRoleActiveVersion() == -1))) {
+ || (isRoleDownloadRequest(entityType) && (pluginInfo.getRoleActiveVersion() == null || pluginInfo.getRoleActiveVersion() == -1))
+ || (isUserStoreDownloadRequest(entityType) && (pluginInfo.getUserStoreActiveVersion() == null || pluginInfo.getUserStoreActiveVersion() == -1))) {
commitWork = new Runnable() {
@Override
public void run() {
@@ -804,11 +814,16 @@ public class AssetMgr extends AssetMgrBase {
// This is our best guess of when tags may have been downloaded
pluginInfo.setTagDownloadTime(pluginInfo.getTagActivationTime());
}
- } else {
+ } else if (isRoleDownloadRequest(entityType)) {
if (pluginInfo.getRoleDownloadTime() != null && pluginInfo.getRoleDownloadedVersion().equals(pluginInfo.getRoleActiveVersion())) {
// This is our best guess of when role may have been downloaded
pluginInfo.setRoleDownloadTime(pluginInfo.getRoleActivationTime());
}
+ } else {
+ if (pluginInfo.getUserStoreDownloadTime() != null && pluginInfo.getUserStoreDownloadedVersion().equals(pluginInfo.getUserStoreActiveVersion())) {
+ // This is our best guess of when users and groups may have been downloaded
+ pluginInfo.setUserStoreDownloadTime(pluginInfo.getUserStoreActivationTime());
+ }
}
pluginInfo.setAdminCapabilities(adminCapabilities);
@@ -891,7 +906,7 @@ public class AssetMgr extends AssetMgrBase {
dbObj.setTagActivationTime(lastTagActivationTime);
needsUpdating = true;
}
- } else {
+ } else if (isRoleDownloadRequest(entityType)){
if (dbObj.getRoleDownloadedVersion() == null || !dbObj.getRoleDownloadedVersion().equals(pluginInfo.getRoleDownloadedVersion())) {
dbObj.setRoleDownloadedVersion(pluginInfo.getRoleDownloadedVersion());
dbObj.setRoleDownloadTime(pluginInfo.getRoleDownloadTime());
@@ -915,6 +930,30 @@ public class AssetMgr extends AssetMgrBase {
dbObj.setRoleActivationTime(lastRoleActivationTime);
needsUpdating = true;
}
+ } else {
+ if (dbObj.getUserStoreDownloadedVersion() == null || !dbObj.getUserStoreDownloadedVersion().equals(pluginInfo.getUserStoreDownloadedVersion())) {
+ dbObj.setUserStoreDownloadedVersion(pluginInfo.getUserStoreDownloadedVersion());
+ dbObj.setUserStoreDownloadTime(pluginInfo.getUserStoreDownloadTime());
+ needsUpdating = true;
+ }
+
+ Long lastKnownUserStoreVersion = pluginInfo.getUserStoreActiveVersion();
+ Long lastUserStoreActivationTime = pluginInfo.getUserStoreActivationTime();
+
+ if (lastKnownUserStoreVersion != null && lastKnownUserStoreVersion == -1) {
+ dbObj.setUserStoreDownloadTime(pluginInfo.getUserStoreDownloadTime());
+ needsUpdating = true;
+ }
+
+ if (lastKnownUserStoreVersion != null && lastKnownUserStoreVersion > 0 && (dbObj.getUserStoreActiveVersion() == null || !dbObj.getUserStoreActiveVersion().equals(lastKnownUserStoreVersion))) {
+ dbObj.setUserStoreActiveVersion(lastKnownUserStoreVersion);
+ needsUpdating = true;
+ }
+
+ if (lastUserStoreActivationTime != null && lastUserStoreActivationTime > 0 && (dbObj.getUserStoreActivationTime() == null || !dbObj.getUserStoreActivationTime().equals(lastUserStoreActivationTime))) {
+ dbObj.setUserStoreActivationTime(lastUserStoreActivationTime);
+ needsUpdating = true;
+ }
}
if (isTagVersionResetNeeded) {
@@ -1256,4 +1295,8 @@ public class AssetMgr extends AssetMgrBase {
private boolean isRoleDownloadRequest(int entityType) {
return entityType == RangerPluginInfo.ENTITY_TYPE_ROLES;
}
+
+ private boolean isUserStoreDownloadRequest(int entityType) {
+ return entityType == RangerPluginInfo.ENTITY_TYPE_USERSTORE;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
index 04596dc..5be8d9d 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
@@ -293,7 +293,7 @@ public class RoleDBStore implements RoleStore {
XXServiceVersionInfo xxServiceVersionInfo = daoMgr.getXXServiceVersionInfo().findByServiceName(serviceName);
ret = (xxServiceVersionInfo != null) ? xxServiceVersionInfo.getRoleVersion() : null;
} else {
- ret = daoMgr.getXXGlobalState().getRoleVersion(RANGER_ROLE_GLOBAL_STATE_NAME);
+ ret = daoMgr.getXXGlobalState().getAppDataVersion(RANGER_ROLE_GLOBAL_STATE_NAME);
}
return ret;
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index ccda6ab..47250f3 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -3487,7 +3487,7 @@ public class ServiceDBStore extends AbstractServiceStore {
// get the LatestRoleVersion from the GlobalTable and update ServiceInfo for a service
XXGlobalStateDao xxGlobalStateDao = daoMgr.getXXGlobalState();
if (xxGlobalStateDao != null) {
- Long roleVersion = xxGlobalStateDao.getRoleVersion("RangerRole");
+ Long roleVersion = xxGlobalStateDao.getAppDataVersion("RangerRole");
if (roleVersion != null) {
serviceVersionInfoDbObj.setRoleVersion(roleVersion);
serviceVersionInfoDbObj.setRoleUpdateTime(now);
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/UserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/UserMgr.java
index 3045eaf..2b3cdcb 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/UserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/UserMgr.java
@@ -572,6 +572,7 @@ public class UserMgr {
gjUser.setPassword(userProfile.getPassword());
gjUser.setUserSource(userProfile.getUserSource());
gjUser.setPublicScreenName(userProfile.getPublicScreenName());
+ gjUser.setOtherAttributes(userProfile.getOtherAttributes());
if (userProfile.getFirstName() != null
&& userProfile.getLastName() != null
&& !userProfile.getFirstName().trim().isEmpty()
@@ -1171,6 +1172,7 @@ public class UserMgr {
*/
}
}
+
VXPortalUser userProfileRes = null;
if (xXPortalUser != null) {
userProfileRes = mapXXPortalUserToVXPortalUserForDefaultAccount(xXPortalUser);
@@ -1246,6 +1248,7 @@ public class UserMgr {
userProfile.setFirstName(user.getFirstName());
userProfile.setLastName(user.getLastName());
userProfile.setPublicScreenName(user.getPublicScreenName());
+ userProfile.setOtherAttributes(user.getOtherAttributes());
List<XXPortalUserRole> gjUserRoleList = daoManager
.getXXPortalUserRole().findByParentId(user.getId());
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 1c29d82..bfce9a6 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -31,28 +31,21 @@ import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.ranger.common.ContextUtil;
-import org.apache.ranger.common.GUIDUtil;
-import org.apache.ranger.common.RangerCommonEnums;
+import org.apache.ranger.common.*;
import org.apache.ranger.entity.XXGroupPermission;
import org.apache.ranger.entity.XXModuleDef;
import org.apache.ranger.entity.XXUserPermission;
+import org.apache.ranger.plugin.model.GroupInfo;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
+import org.apache.ranger.plugin.model.UserInfo;
+import org.apache.ranger.plugin.util.RangerUserStore;
import org.apache.ranger.security.context.RangerAPIMapping;
import org.apache.ranger.service.*;
import org.apache.ranger.view.*;
import org.apache.log4j.Logger;
-import org.apache.ranger.common.AppConstants;
-import org.apache.ranger.common.MessageEnums;
-import org.apache.ranger.common.PropertiesUtil;
-import org.apache.ranger.common.RangerConstants;
-import org.apache.ranger.common.RangerServicePoliciesCache;
-import org.apache.ranger.common.SearchCriteria;
-import org.apache.ranger.common.StringUtil;
-import org.apache.ranger.common.UserSessionBase;
import org.apache.ranger.db.RangerDaoManager;
import org.apache.ranger.db.XXAuditMapDao;
import org.apache.ranger.db.XXAuthSessionDao;
@@ -93,6 +86,8 @@ import org.apache.ranger.entity.XXPortalUserRole;
@Component
public class XUserMgr extends XUserMgrBase {
+ private static final String RANGER_USER_GROUP_GLOBAL_STATE_NAME = "RangerUserStore";
+
@Autowired
XUserService xUserService;
@@ -584,7 +579,11 @@ public class XUserMgr extends XUserMgrBase {
assignPermissionToUser(vXPortalUser, true);
}
vxUGInfo.setXgroupInfo(vxg);
-
+ try {
+ daoManager.getXXGlobalState().onGlobalAppDataChange(RANGER_USER_GROUP_GLOBAL_STATE_NAME);
+ } catch (Exception excp) {
+ logger.error("createXUserGroupFromMap(" + vXUser.getName() + ") failed", excp);
+ }
return vxUGInfo;
}
@@ -642,6 +641,12 @@ public class XUserMgr extends XUserMgrBase {
vxGUInfo.setXuserInfo(vxu);
+ try {
+ daoManager.getXXGlobalState().onGlobalAppDataChange(RANGER_USER_GROUP_GLOBAL_STATE_NAME);
+ } catch (Exception excp) {
+ logger.error("createXGroupUserFromMap(" + vXGroup.getName() + ") failed", excp);
+ }
+
return vxGUInfo;
}
@@ -2544,4 +2549,34 @@ public class XUserMgr extends XUserMgrBase {
return vxUgsyncAuditInfo;
}
+ public Long getUserStoreVersion() {
+ return daoManager.getXXGlobalState().getAppDataVersion(RANGER_USER_GROUP_GLOBAL_STATE_NAME);
+ }
+
+ public Set<UserInfo> getUsers() {
+ return new HashSet<>(xUserService.getUsers());
+ }
+
+ public Set<GroupInfo> getGroups() {
+ return new HashSet<>(xGroupService.getGroups());
+ }
+
+ public RangerUserStore getRangerUserStore(Long lastKnownUserStoreVersion) throws Exception {
+ RangerUserStore ret = null;
+ Long rangerUserStoreVersionInDB = getUserStoreVersion();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("==> XUserMgr.getRangerUserStore() lastKnownUserStoreVersion= " + lastKnownUserStoreVersion + " rangerUserStoreVersionInDB= " + rangerUserStoreVersionInDB);
+ }
+
+ if (rangerUserStoreVersionInDB != null) {
+ ret = RangerUserStoreCache.getInstance().getLatestRangerUserStoreOrCached(this, lastKnownUserStoreVersion, rangerUserStoreVersionInDB);
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("<= XUserMgr.getRangerUserStore() lastKnownUserStoreVersion= " + lastKnownUserStoreVersion + " rangerUserStoreVersionInDB= " + rangerUserStoreVersionInDB + " RangerRoles= " + ret);
+ }
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/common/RangerUserStoreCache.java b/security-admin/src/main/java/org/apache/ranger/common/RangerUserStoreCache.java
new file mode 100644
index 0000000..8ffc98c
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/common/RangerUserStoreCache.java
@@ -0,0 +1,122 @@
+/*
+ * 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.common;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
+import org.apache.ranger.biz.XUserMgr;
+import org.apache.ranger.plugin.model.GroupInfo;
+import org.apache.ranger.plugin.model.UserInfo;
+import org.apache.ranger.plugin.util.RangerUserStore;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class RangerUserStoreCache {
+ private static final Log LOG = LogFactory.getLog(RangerUserStoreCache.class);
+
+ private static final int MAX_WAIT_TIME_FOR_UPDATE = 10;
+
+ public static volatile RangerUserStoreCache sInstance = null;
+ private final int waitTimeInSeconds;
+ private final ReentrantLock lock = new ReentrantLock();
+ private RangerUserStore rangerUserStore;
+
+ public static RangerUserStoreCache getInstance() {
+ if (sInstance == null) {
+ synchronized (RangerUserStoreCache.class) {
+ if (sInstance == null) {
+ sInstance = new RangerUserStoreCache();
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ private RangerUserStoreCache() {
+ RangerAdminConfig config = RangerAdminConfig.getInstance();
+ waitTimeInSeconds = config.getInt("ranger.admin.userstore.download.cache.max.waittime.for.update", MAX_WAIT_TIME_FOR_UPDATE);
+ this.rangerUserStore = new RangerUserStore();
+ }
+
+ public RangerUserStore getRangerUserStore() {
+ return this.rangerUserStore;
+ }
+
+ public RangerUserStore getLatestRangerUserStoreOrCached(XUserMgr xUserMgr, Long lastKnownUserStoreVersion, Long rangerUserStoreVersionInDB) throws Exception {
+ RangerUserStore ret = null;
+
+ if (lastKnownUserStoreVersion == null || !lastKnownUserStoreVersion.equals(rangerUserStoreVersionInDB)) {
+ ret = getLatestRangerUserStore(xUserMgr, lastKnownUserStoreVersion, rangerUserStoreVersionInDB);
+ } else if (lastKnownUserStoreVersion.equals(rangerUserStoreVersionInDB)) {
+ ret = null;
+ } else {
+ ret = getRangerUserStore();
+ }
+
+ return ret;
+ }
+
+ public RangerUserStore getLatestRangerUserStore(XUserMgr xUserMgr, Long lastKnownUserStoreVersion, Long rangerUserStoreVersionInDB) throws Exception {
+ RangerUserStore ret = null;
+ boolean lockResult = false;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerUserStoreCache.getLatestRangerUserStore(lastKnownUserStoreVersion= " + lastKnownUserStoreVersion + " rangerUserStoreVersionInDB= " + rangerUserStoreVersionInDB + ")");
+ }
+
+ try {
+ lockResult = lock.tryLock(waitTimeInSeconds, TimeUnit.SECONDS);
+
+ if (lockResult) {
+ final Set<UserInfo> rangerUsersInDB = xUserMgr.getUsers();
+ final Set<GroupInfo> rangerGroupsInDB = xUserMgr.getGroups();
+ if (CollectionUtils.isNotEmpty(rangerUsersInDB)) {
+ for (UserInfo userInfo : rangerUsersInDB) {
+ //Get user group mapping from DB and update userInfo object.
+ userInfo.setGroups(xUserMgr.getGroupsForUser(userInfo.getName()));
+ }
+ }
+
+ ret = new RangerUserStore(rangerUserStoreVersionInDB, rangerUsersInDB, rangerGroupsInDB);
+ rangerUserStore = ret;
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not get lock in [" + waitTimeInSeconds + "] seconds, returning cached RangerUserStore");
+ }
+ ret = getRangerUserStore();
+ }
+ } catch (InterruptedException exception) {
+ LOG.error("RangerUserStoreCache.getLatestRangerUserStore:lock got interrupted..", exception);
+ } finally {
+ if (lockResult) {
+ lock.unlock();
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerUserStoreCache.getLatestRangerUserStore(lastKnownUserStoreVersion= " + lastKnownUserStoreVersion + " rangerUserStoreVersionInDB= " + rangerUserStoreVersionInDB + " RangerUserStore= " + ret + ")");
+ }
+ return ret;
+ }
+}
+
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXGlobalStateDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXGlobalStateDao.java
index 2e462bd..b979459 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGlobalStateDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGlobalStateDao.java
@@ -35,7 +35,7 @@ import java.util.Map;
public class XXGlobalStateDao extends BaseDao<XXGlobalState> {
private static final Logger logger = Logger.getLogger(XXGlobalStateDao.class);
- final static String APP_DATA_ENTRY_ROLE_VERSION = "RangerRoleVersion";
+ final static String APP_DATA_ENTRY_VERSION = "Version";
public void onGlobalStateChange(String stateName) throws Exception {
@@ -74,9 +74,9 @@ public class XXGlobalStateDao extends BaseDao<XXGlobalState> {
try {
XXGlobalState globalState = findByStateName(stateName);
if (globalState == null) {
- createGlobalStateForRoleVersion(stateName);
+ createGlobalStateForAppDataVersion(stateName);
} else {
- updateGlobalStateForRoleVersion(globalState, stateName);
+ updateGlobalStateForAppDataVersion(globalState, stateName);
}
} catch (Exception exception) {
logger.error("Cannot create/update GlobalState for state:[" + stateName + "]", exception);
@@ -85,21 +85,21 @@ public class XXGlobalStateDao extends BaseDao<XXGlobalState> {
}
}
- public Long getRoleVersion(String stateName) {
+ public Long getAppDataVersion(String stateName) {
Long ret = null;
try {
XXGlobalState globalState = findByStateName(stateName);
if (globalState != null) {
- Map<String, String> roleVersionJson = new Gson().fromJson(globalState.getAppData(), Map.class);
- if (MapUtils.isNotEmpty(roleVersionJson)) {
- ret = Long.valueOf(roleVersionJson.get(APP_DATA_ENTRY_ROLE_VERSION));
+ Map<String, String> appDataVersionJson = new Gson().fromJson(globalState.getAppData(), Map.class);
+ if (MapUtils.isNotEmpty(appDataVersionJson)) {
+ ret = Long.valueOf(appDataVersionJson.get(APP_DATA_ENTRY_VERSION));
} else {
ret = 1L;
}
}
} catch (Exception exception) {
if (logger.isDebugEnabled()) {
- logger.debug("Unable to find the role version in Ranger Database", exception);
+ logger.debug("Unable to find the version for " + stateName + " in Ranger Database", exception);
}
}
return ret;
@@ -140,25 +140,25 @@ public class XXGlobalStateDao extends BaseDao<XXGlobalState> {
}
}
- private void createGlobalStateForRoleVersion(String stateName) {
+ private void createGlobalStateForAppDataVersion(String stateName) {
XXGlobalState globalState = new XXGlobalState();
globalState.setStateName(stateName);
- Map<String,String> roleVersion = new HashMap<>();
- roleVersion.put(APP_DATA_ENTRY_ROLE_VERSION,new String(Long.toString(1L)));
- globalState.setAppData(new Gson().toJson(roleVersion));
+ Map<String,String> appDataVersion = new HashMap<>();
+ appDataVersion.put(APP_DATA_ENTRY_VERSION,new String(Long.toString(1L)));
+ globalState.setAppData(new Gson().toJson(appDataVersion));
create(globalState);
}
- private void updateGlobalStateForRoleVersion(XXGlobalState globalState, String stateName) {
- Map<String,String> roleVersionJson = new Gson().fromJson(globalState.getAppData(),Map.class);
- if (MapUtils.isNotEmpty(roleVersionJson)) {
- Long roleVersion = Long.valueOf(roleVersionJson.get(APP_DATA_ENTRY_ROLE_VERSION)) + 1L;
- roleVersionJson.put(APP_DATA_ENTRY_ROLE_VERSION, new String(Long.toString(roleVersion)));
- globalState.setAppData(new Gson().toJson(roleVersionJson));
+ private void updateGlobalStateForAppDataVersion(XXGlobalState globalState, String stateName) {
+ Map<String,String> appDataVersionJson = new Gson().fromJson(globalState.getAppData(),Map.class);
+ if (MapUtils.isNotEmpty(appDataVersionJson)) {
+ Long appDataVersion = Long.valueOf(appDataVersionJson.get(APP_DATA_ENTRY_VERSION)) + 1L;
+ appDataVersionJson.put(APP_DATA_ENTRY_VERSION, new String(Long.toString(appDataVersion)));
+ globalState.setAppData(new Gson().toJson(appDataVersionJson));
update(globalState);
} else {
- //if not present create Global State for Role Version.
- createGlobalStateForRoleVersion(stateName);
+ //if not present create Global State for state name Version.
+ createGlobalStateForAppDataVersion(stateName);
}
}
}
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 1e8a093..af80639 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
@@ -24,6 +24,7 @@ import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -32,6 +33,8 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.DefaultValue;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
@@ -39,6 +42,9 @@ import org.apache.log4j.Logger;
import org.apache.ranger.biz.RangerBizUtil;
import org.apache.ranger.biz.SessionMgr;
import org.apache.ranger.biz.XUserMgr;
+import org.apache.ranger.biz.AssetMgr;
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.ServiceUtil;
import org.apache.ranger.common.ContextUtil;
import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.RESTErrorUtil;
@@ -50,6 +56,13 @@ import org.apache.ranger.common.UserSessionBase;
import org.apache.ranger.common.annotation.RangerAnnotationClassName;
import org.apache.ranger.common.annotation.RangerAnnotationJSMgrName;
import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.entity.XXService;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.model.RangerPluginInfo;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.plugin.util.RangerRESTUtils;
+import org.apache.ranger.plugin.util.RangerUserStore;
import org.apache.ranger.security.context.RangerAPIList;
import org.apache.ranger.service.AuthSessionService;
import org.apache.ranger.service.XAuditMapService;
@@ -78,6 +91,8 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class XUserREST {
+ public static final String USERSTORE_DOWNLOAD_USERS = "userstore.download.auth.users";
+
@Autowired
SearchUtil searchUtil;
@@ -131,6 +146,15 @@ public class XUserREST {
@Autowired
StringUtil stringUtil;
+
+ @Autowired
+ AssetMgr assetMgr;
+
+ @Autowired
+ ServiceUtil serviceUtil;
+
+ @Autowired
+ ServiceDBStore svcStore;
static final Logger logger = Logger.getLogger(XUserMgr.class);
@@ -1235,6 +1259,93 @@ public class XUserREST {
}
}
+ @GET
+ @Path("/secure/download/{serviceName}")
+ @Produces({ "application/xml", "application/json" })
+ public RangerUserStore getSecureRangerUserStoreIfUpdated(@PathParam("serviceName") String serviceName,
+ @QueryParam("lastKnownUserStoreVersion") Long lastKnownUserStoreVersion,
+ @DefaultValue("0") @QueryParam("lastActivationTime") Long lastActivationTime,
+ @QueryParam("pluginId") String pluginId,
+ @DefaultValue("") @QueryParam("clusterName") String clusterName,
+ @DefaultValue("") @QueryParam(RangerRESTUtils.REST_PARAM_CAPABILITIES) String pluginCapabilities,
+ @Context HttpServletRequest request) throws Exception {
+ if (logger.isDebugEnabled()) {
+ logger.debug("==> XUserREST.getSecureRangerUserStoreIfUpdated("
+ + serviceName + ", " + lastKnownUserStoreVersion + ", " + lastActivationTime + ")");
+ }
+ RangerUserStore ret = null;
+ int httpCode = HttpServletResponse.SC_OK;
+ String logMsg = null;
+ boolean isAllowed = false;
+ boolean isAdmin = bizUtil.isAdmin();
+ boolean isKeyAdmin = bizUtil.isKeyAdmin();
+ Long downloadedVersion = null;
+
+ boolean isValid = false;
+ try {
+ XXService xService = rangerDaoManager.getXXService().findByName(serviceName);
+ if (xService != null) {
+ isValid = true;
+ }
+ if (isValid) {
+ if (lastKnownUserStoreVersion == null) {
+ lastKnownUserStoreVersion = Long.valueOf(-1);
+ }
+ XXServiceDef xServiceDef = rangerDaoManager.getXXServiceDef().getById(xService.getType());
+ RangerService rangerService = svcStore.getServiceByName(serviceName);
+
+ if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
+ if (isKeyAdmin) {
+ isAllowed = true;
+ } else {
+ isAllowed = bizUtil.isUserAllowed(rangerService, USERSTORE_DOWNLOAD_USERS);
+ }
+ } else {
+ if (isAdmin) {
+ isAllowed = true;
+ } else {
+ isAllowed = bizUtil.isUserAllowed(rangerService, USERSTORE_DOWNLOAD_USERS);
+ }
+ }
+
+ if (isAllowed) {
+ RangerUserStore rangerUserStore = xUserMgr.getRangerUserStore(lastKnownUserStoreVersion);
+ if (rangerUserStore == null) {
+ downloadedVersion = lastKnownUserStoreVersion;
+ httpCode = HttpServletResponse.SC_NOT_MODIFIED;
+ logMsg = "No change since last update";
+ } else {
+ downloadedVersion = rangerUserStore.getUserStoreVersion();
+ ret = rangerUserStore;
+ httpCode = HttpServletResponse.SC_OK;
+ logMsg = "Returning RangerUserStore =>" + (ret.toString());
+ }
+ } else {
+ logger.error("getSecureRangerUserStoreIfUpdated(" + serviceName + ", " + lastKnownUserStoreVersion + ") failed as User doesn't have permission to download UsersAndGroups");
+ httpCode = HttpServletResponse.SC_UNAUTHORIZED;
+ logMsg = "User doesn't have permission to download UsersAndGroups";
+ }
+ }
+
+ } catch (Throwable excp) {
+ logger.error("getSecureRangerUserStoreIfUpdated(" + serviceName + ", " + lastKnownUserStoreVersion + ", " + lastActivationTime + ") failed", excp);
+ httpCode = HttpServletResponse.SC_BAD_REQUEST;
+ logMsg = excp.getMessage();
+ }
+
+ assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_USERSTORE, downloadedVersion, lastKnownUserStoreVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
+
+ if (httpCode != HttpServletResponse.SC_OK) {
+ boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
+ throw restErrorUtil.createRESTException(httpCode, logMsg, logError);
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("<== XUserREST.getSecureRangerUserStoreIfUpdated(" + serviceName + ", " + lastKnownUserStoreVersion + ", " + lastActivationTime + ")" + ret);
+ }
+ return ret;
+ }
+
@POST
@Path("/ugsync/auditinfo")
@Produces({ "application/xml", "application/json" })
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java
index 1a701bb..cde91dc 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XGroupServiceBase.java
@@ -25,15 +25,20 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import org.apache.ranger.common.SearchCriteria;
import org.apache.ranger.entity.XXGroup;
+import org.apache.ranger.plugin.model.GroupInfo;
import org.apache.ranger.view.VXGroup;
import org.apache.ranger.view.VXGroupList;
public abstract class XGroupServiceBase<T extends XXGroup, V extends VXGroup>
extends AbstractBaseResourceService<T, V> {
public static final String NAME = "XGroup";
+ private static final Gson gsonBuilder = new GsonBuilder().create();
public XGroupServiceBase() {
@@ -84,4 +89,19 @@ public abstract class XGroupServiceBase<T extends XXGroup, V extends VXGroup>
return returnList;
}
+ public List<GroupInfo> getGroups() {
+ List<GroupInfo> returnList = new ArrayList<>();
+
+ @SuppressWarnings("unchecked")
+ List<XXGroup> resultList = daoManager.getXXGroup().getAll();
+
+ // Iterate over the result list and create the return list
+ for (XXGroup gjXGroup : resultList) {
+ GroupInfo groupInfo = new GroupInfo(gjXGroup.getName(), gjXGroup.getDescription(), gsonBuilder.fromJson(gjXGroup.getOtherAttributes(), Map.class));
+ returnList.add(groupInfo);
+ }
+
+ return returnList;
+ }
+
}
diff --git a/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java
index 1004952..9cdc14e 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/XUserServiceBase.java
@@ -25,15 +25,20 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import org.apache.ranger.common.SearchCriteria;
import org.apache.ranger.entity.XXUser;
+import org.apache.ranger.plugin.model.UserInfo;
import org.apache.ranger.view.VXUser;
import org.apache.ranger.view.VXUserList;
public abstract class XUserServiceBase<T extends XXUser, V extends VXUser>
extends AbstractBaseResourceService<T, V> {
public static final String NAME = "XUser";
+ private static final Gson gsonBuilder = new GsonBuilder().create();
public XUserServiceBase() {
@@ -84,4 +89,19 @@ public abstract class XUserServiceBase<T extends XXUser, V extends VXUser>
return returnList;
}
+ public List<UserInfo> getUsers() {
+ List<UserInfo> returnList = new ArrayList<>();
+
+ @SuppressWarnings("unchecked")
+ List<XXUser> resultList = daoManager.getXXUser().getAll();
+
+ // Iterate over the result list and create the return list
+ for (XXUser gjXUser : resultList) {
+ UserInfo userInfo = new UserInfo(gjXUser.getName(), gjXUser.getDescription(), gsonBuilder.fromJson(gjXUser.getOtherAttributes(), Map.class));
+ returnList.add(userInfo);
+ }
+
+ return returnList;
+ }
+
}
diff --git a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java
index ca50f09..bea91c4 100644
--- a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java
+++ b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapDeltaUserGroupBuilder.java
@@ -33,6 +33,7 @@ import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.HashMap;
+import java.util.UUID;
import javax.naming.Context;
import javax.naming.InvalidNameException;
@@ -51,6 +52,7 @@ import javax.naming.ldap.StartTlsResponse;
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
+import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
import org.apache.ranger.unixusersync.model.LdapSyncSourceInfo;
@@ -65,6 +67,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
private static final Logger LOG = Logger.getLogger(LdapDeltaUserGroupBuilder.class);
+ private static final String DATA_TYPE_BYTEARRAY = "byte[]";
private static final int PAGE_SIZE = 500;
private static long deltaSyncUserTime = 0; // Used for AD uSNChanged
private static long deltaSyncGroupTime = 0; // Used for AD uSNChanged
@@ -80,12 +83,14 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
private String[] userSearchBase;
private String userNameAttribute;
+ private String userCloudIdAttribute;
private int userSearchScope;
private String userObjectClass;
private String userSearchFilter;
private String extendedUserSearchFilter;
private SearchControls userSearchControls;
private Set<String> userGroupNameAttributeSet;
+ private Set<String> otherUserAttributes;
private boolean pagedResultsEnabled = true;
private int pagedResultsSize = PAGE_SIZE;
@@ -102,6 +107,8 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
private SearchControls groupSearchControls;
private String groupMemberAttributeName;
private String groupNameAttribute;
+ private String groupCloudIdAttribute;
+ private Set<String> otherGroupAttributes;
private int groupHierarchyLevels;
private LdapContext ldapContext;
@@ -126,6 +133,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
int noOfNewGroups;
int noOfModifiedUsers;
int noOfModifiedGroups;
+ private Map<String, Map<String, String>> groupInfoMap;
public static void main(String[] args) throws Throwable {
LdapDeltaUserGroupBuilder ugBuilder = new LdapDeltaUserGroupBuilder();
@@ -188,6 +196,32 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
env.put("java.naming.ldap.factory.socket", "org.apache.ranger.ldapusersync.process.CustomSSLSocketFactory");
}
+ if (StringUtils.isNotEmpty(userCloudIdAttribute)) {
+ if (config.getUserCloudIdAttributeDataType().equals(DATA_TYPE_BYTEARRAY)) {
+ env.put("java.naming.ldap.attributes.binary", userCloudIdAttribute);
+ }
+ }
+
+ if (StringUtils.isNotEmpty(groupCloudIdAttribute)) {
+ if (config.getGroupCloudIdAttributeDataType().equals(DATA_TYPE_BYTEARRAY)) {
+ env.put("java.naming.ldap.attributes.binary", groupCloudIdAttribute);
+ }
+ }
+
+ for (String otherUserAttribute : otherUserAttributes) {
+ String attrType = config.getOtherUserAttributeDataType(otherUserAttribute);
+ if (attrType.equals(DATA_TYPE_BYTEARRAY)) {
+ env.put("java.naming.ldap.attributes.binary", otherUserAttribute);
+ }
+ }
+
+ for (String otherGroupAttribute : otherGroupAttributes) {
+ String attrType = config.getOtherGroupAttributeDataType(otherGroupAttribute);
+ if (attrType.equals(DATA_TYPE_BYTEARRAY)) {
+ env.put("java.naming.ldap.attributes.binary", otherGroupAttribute);
+ }
+ }
+
ldapContext = new InitialLdapContext(env, null);
if (!ldapUrl.startsWith("ldaps")) {
if (config.isStartTlsEnabled()) {
@@ -227,9 +261,11 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
userSearchFilter = config.getUserSearchFilter();
userNameAttribute = config.getUserNameAttribute();
+ userCloudIdAttribute = config.getUserCloudIdAttribute();
Set<String> userSearchAttributes = new HashSet<String>();
userSearchAttributes.add(userNameAttribute);
+ userSearchAttributes.add(userCloudIdAttribute);
// For Group based search, user's group name attribute should not be added to the user search attributes
if (!groupSearchFirstEnabled && !groupSearchEnabled) {
userGroupNameAttributeSet = config.getUserGroupNameAttributeSet();
@@ -237,6 +273,10 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
userSearchAttributes.add(useGroupNameAttribute);
}
}
+ otherUserAttributes = config.getOtherUserAttributes();
+ for (String otherUserAttribute : otherUserAttributes) {
+ userSearchAttributes.add(otherUserAttribute);
+ }
userSearchAttributes.add("uSNChanged");
userSearchAttributes.add("modifytimestamp");
userSearchControls = new SearchControls();
@@ -253,6 +293,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
groupSearchFilter = config.getGroupSearchFilter();
groupMemberAttributeName = config.getUserGroupMemberAttributeName();
groupNameAttribute = config.getGroupNameAttribute();
+ groupCloudIdAttribute = config.getGroupCloudIdAttribute();
groupHierarchyLevels = config.getGroupHierarchyLevels();
extendedGroupSearchFilter = "(&" + extendedGroupSearchFilter + "(|(" + groupMemberAttributeName + "={0})(" + groupMemberAttributeName + "={1})))";
@@ -263,9 +304,14 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
Set<String> groupSearchAttributes = new HashSet<String>();
groupSearchAttributes.add(groupNameAttribute);
+ groupSearchAttributes.add(groupCloudIdAttribute);
groupSearchAttributes.add(groupMemberAttributeName);
groupSearchAttributes.add("uSNChanged");
groupSearchAttributes.add("modifytimestamp");
+ otherGroupAttributes = config.getOtherGroupAttributes();
+ for (String otherGroupAttribute : otherGroupAttributes) {
+ groupSearchAttributes.add(otherGroupAttribute);
+ }
groupSearchControls.setReturningAttributes(groupSearchAttributes.toArray(
new String[groupSearchAttributes.size()]));
@@ -284,6 +330,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
+ ", userNameAttribute: " + userNameAttribute
+ ", userSearchAttributes: " + userSearchAttributes
+ ", userGroupNameAttributeSet: " + userGroupNameAttributeSet
+ + ", otherUserAttributes: " + otherUserAttributes
+ ", pagedResultsEnabled: " + pagedResultsEnabled
+ ", pagedResultsSize: " + pagedResultsSize
+ ", groupSearchEnabled: " + groupSearchEnabled
@@ -325,6 +372,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
LOG.info("LdapDeltaUserGroupBuilder updateSink started");
groupUserTable = HashBasedTable.create();
groupNameMap = new DualHashBidiMap();
+ groupInfoMap = new HashMap<>();
noOfNewUsers = 0;
noOfNewGroups = 0;
noOfModifiedUsers = 0;
@@ -386,7 +434,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
String transformGroupName = groupNameTransform(groupName);
LOG.debug("addOrUpdateGroup(): group = " + groupName + " users = " + userList);
try {
- sink.addOrUpdateGroup(transformGroupName, userList);
+ sink.addOrUpdateGroup(transformGroupName, groupInfoMap.get(groupName), userList);
} catch (Throwable t) {
LOG.error("sink.addOrUpdateGroup failed with exception: " + t.getMessage()
+ ", for group: " + transformGroupName
@@ -519,10 +567,22 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
}
+ Map<String, String> userAttrMap = new HashMap<>();
+ Attribute userCloudIdAttr = attributes.get(userCloudIdAttribute);
+ if (userCloudIdAttr != null) {
+ addToAttrMap(userAttrMap, "cloud_id", userCloudIdAttr, config.getUserCloudIdAttributeDataType());
+ }
+ for (String otherUserAttribute : otherUserAttributes) {
+ if (attributes.get(otherUserAttribute) != null) {
+ String attrType = config.getOtherUserAttributeDataType(otherUserAttribute);
+ addToAttrMap(userAttrMap, otherUserAttribute, attributes.get(otherUserAttribute), attrType);
+ }
+ }
+
if (!groupSearchFirstEnabled) {
String transformUserName = userNameTransform(userName);
try {
- sink.addOrUpdateUser(transformUserName);
+ sink.addOrUpdateUser(transformUserName, userAttrMap, null);
} catch (Throwable t) {
LOG.error("sink.addOrUpdateUser failed with exception: " + t.getMessage()
+ ", for user: " + transformUserName);
@@ -554,7 +614,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
List<String> groupList = new ArrayList<String>(groups);
try {
- sink.addOrUpdateUser(transformUserName, groupList);
+ sink.addOrUpdateUser(transformUserName, userAttrMap, groupList);
} catch (Throwable t) {
LOG.error("sink.addOrUpdateUserGroups failed with exception: " + t.getMessage()
@@ -569,7 +629,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
if (!userNameMap.containsKey(userFullName)) {
String transformUserName = userNameTransform(userName);
try {
- sink.addOrUpdateUser(transformUserName);
+ sink.addOrUpdateUser(transformUserName, userAttrMap, null);
} catch (Throwable t) {
LOG.error("sink.addOrUpdateUser failed with exception: " + t.getMessage()
+ ", for user: " + transformUserName);
@@ -640,7 +700,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
LOG.info("LdapDeltaUserGroupBuilder.getUsers() completed with user count: "
+ counter);
} catch (Exception t) {
- LOG.error("LdapDeltaUserGroupBuilder.getUsers() failed with exception: " + t);
+ LOG.error("LdapDeltaUserGroupBuilder.getUsers() failed with exception: ", t);
LOG.info("LdapDeltaUserGroupBuilder.getUsers() user count: "
+ counter);
}
@@ -704,7 +764,8 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
continue;
}
counter++;
- Attribute groupNameAttr = groupEntry.getAttributes().get(groupNameAttribute);
+ Attributes attributes = groupEntry.getAttributes();
+ Attribute groupNameAttr = attributes.get(groupNameAttribute);
if (groupNameAttr == null) {
if (LOG.isInfoEnabled()) {
LOG.info(groupNameAttribute + " empty for entry " + groupEntry.getNameInNamespace() +
@@ -714,15 +775,27 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
String gName = (String) groupNameAttr.get();
String transformGroupName = groupNameTransform(gName);
+ Map<String, String> groupAttrMap = new HashMap<>();
+ Attribute groupCloudIdAttr = attributes.get(groupCloudIdAttribute);
+ if (groupCloudIdAttr != null) {
+ addToAttrMap(groupAttrMap, "cloud_id", groupCloudIdAttr, config.getGroupCloudIdAttributeDataType());
+ }
+ for (String otherGroupAttribute : otherGroupAttributes) {
+ if (attributes.get(otherGroupAttribute) != null) {
+ String attrType = config.getOtherGroupAttributeDataType(otherGroupAttribute);
+ addToAttrMap(groupAttrMap, otherGroupAttribute, attributes.get(otherGroupAttribute), attrType);
+ }
+ }
+ groupInfoMap.put(gName, groupAttrMap);
// If group based search is enabled, then
// update the group name to ranger admin
// check for group members and populate userInfo object with user's full name and group mapping
if (groupSearchFirstEnabled) {
LOG.debug("Update Ranger admin with " + transformGroupName);
- sink.addOrUpdateGroup(transformGroupName);
+ sink.addOrUpdateGroup(transformGroupName, groupAttrMap);
}
- Attribute timeStampAttr = groupEntry.getAttributes().get("uSNChanged");
+ Attribute timeStampAttr = attributes.get("uSNChanged");
if (timeStampAttr != null) {
String uSNChangedVal = (String) timeStampAttr.get();
long currentDeltaSyncTime = Long.parseLong(uSNChangedVal);
@@ -730,7 +803,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
highestdeltaSyncGroupTime = currentDeltaSyncTime;
}
} else {
- timeStampAttr = groupEntry.getAttributes().get("modifytimestamp");
+ timeStampAttr = attributes.get("modifytimestamp");
if (timeStampAttr != null) {
String timeStampVal = (String) timeStampAttr.get();
Date parseDate = dateFormat.parse(timeStampVal);
@@ -742,7 +815,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
}
}
- Attribute groupMemberAttr = groupEntry.getAttributes().get(groupMemberAttributeName);
+ Attribute groupMemberAttr = attributes.get(groupMemberAttributeName);
int userCount = 0;
if (groupMemberAttr == null || groupMemberAttr.size() <= 0) {
LOG.info("No members available for " + gName);
@@ -769,7 +842,8 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
if (groupSearchFirstEnabled && !userSearchEnabled) {
String transformUserName = userNameTransform(userName);
try {
- sink.addOrUpdateUser(transformUserName);
+ Map<String, String> userAttrMap = new HashMap<>();
+ sink.addOrUpdateUser(transformUserName, userAttrMap, null);
} catch (Throwable t) {
LOG.error("sink.addOrUpdateUser failed with exception: " + t.getMessage()
+ ", for user: " + transformUserName);
@@ -789,6 +863,8 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
groupNameMap.put(groupEntry.getNameInNamespace().toLowerCase(), gName);
}
+
+
if (groupNames.contains(gName)) {
noOfModifiedGroups++;
} else {
@@ -1021,6 +1097,15 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
continue;
}
+ Map<String, String> groupAttrMap = new HashMap<>();
+ for (String otherGroupAttribute : otherGroupAttributes) {
+ Attribute otherGroupAttr = groupEntry.getAttributes().get(otherGroupAttribute);
+ if (otherGroupAttr != null) {
+ groupAttrMap.put(otherGroupAttribute, (String) otherGroupAttr.get());
+ }
+ }
+ groupInfoMap.put(gName, groupAttrMap);
+
NamingEnumeration<?> userEnum = groupMemberAttr.getAll();
while (userEnum.hasMore()) {
String originalUserFullName = (String) userEnum.next();
@@ -1035,6 +1120,7 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
groupUserTable.put(gName, originalUserFullName, originalUserFullName);
}
groupNameMap.put(groupEntry.getNameInNamespace().toLowerCase(), gName);
+
}
LOG.info("No. of members in the group " + gName + " = " + userCount);
}
@@ -1086,5 +1172,22 @@ public class LdapDeltaUserGroupBuilder extends AbstractUserGroupSource {
}
goUpGroupHierarchyLdap(nextLevelGroups, groupHierarchyLevels-1);
}
-}
+ private void addToAttrMap(Map<String, String> userAttrMap, String attrName, Attribute attr, String attrType) throws Throwable{
+ if (attrType.equals(DATA_TYPE_BYTEARRAY)) {
+ try {
+ byte[] otherUserAttrBytes = (byte[]) attr.get();
+ //Convert objectGUID into string and add to userAttrMap
+ String attrVal = UUID.nameUUIDFromBytes(otherUserAttrBytes).toString();
+ userAttrMap.put(attrName, attrVal);
+ } catch (ClassCastException e) {
+ LOG.error(attrName + " type is not set properly " + e.getMessage());
+ }
+ } else if (attrType.equals("String")) {
+ userAttrMap.put(attrName, (String) attr.get());
+ } else {
+ // This should not be reached.
+ LOG.warn("Attribute Type " + attrType + " not supported for " + attrName);
+ }
+ }
+}
diff --git a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapPolicyMgrUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapPolicyMgrUserGroupBuilder.java
index 8017395..31b4d3d 100644
--- a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapPolicyMgrUserGroupBuilder.java
+++ b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapPolicyMgrUserGroupBuilder.java
@@ -152,25 +152,14 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
@Override
public void addOrUpdateUser(String userName, List<String> groups) throws Throwable {
- //* Add user to groups mapping in the x_user table.
- //* Here the assumption is that the user already exists in x_portal_user table.
- if ( ! isMockRun ) {
- // If the rest call to ranger admin fails,
- // propagate the failure to the caller for retry in next sync cycle.
- if (addUserGroupInfo(userName, groups) == null ) {
- String msg = "Failed to add addorUpdate user group info";
- LOG.error(msg);
- throw new Exception(msg);
- }
- }
}
@Override
- public void addOrUpdateGroup(String groupName) throws Throwable {
+ public void addOrUpdateGroup(String groupName, Map<String, String> groupAttrs) throws Throwable {
//* Build the group info object and do the rest call
if ( ! isMockRun ) {
- if ( addGroupInfo(groupName) == null) {
+ if ( addGroupInfo(groupName, groupAttrs) == null) {
String msg = "Failed to add addorUpdate group info";
LOG.error(msg);
throw new Exception(msg);
@@ -179,13 +168,13 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
}
- private XGroupInfo addGroupInfo(final String groupName){
+ private XGroupInfo addGroupInfo(final String groupName, Map<String, String> groupAttrs){
XGroupInfo ret = null;
XGroupInfo group = null;
LOG.debug("INFO: addPMXAGroup(" + groupName + ")");
if (! isMockRun) {
- group = addXGroupInfo(groupName);
+ group = addXGroupInfo(groupName, groupAttrs);
}
if (authenticationType != null && AUTH_KERBEROS.equalsIgnoreCase(authenticationType) && SecureClientLogin.isKerberosCredentialExists(principal,keytab)) {
try {
@@ -213,7 +202,7 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
}
}
- private XGroupInfo addXGroupInfo(String aGroupName) {
+ private XGroupInfo addXGroupInfo(String aGroupName, Map<String, String> groupAttrs) {
XGroupInfo addGroup = new XGroupInfo();
@@ -224,6 +213,8 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
addGroup.setGroupType("1");
addGroup.setGroupSource(GROUP_SOURCE_EXTERNAL);
+ Gson gson = new Gson();
+ addGroup.setOtherAttributes(gson.toJson(groupAttrs));
groupuserInfo.setXgroupInfo(addGroup);
return addGroup;
@@ -272,30 +263,33 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
@Override
public void addOrUpdateUser(String userName) throws Throwable {
+
+ }
+
+ @Override
+ public void addOrUpdateUser(String userName, Map<String, String> userAttrs, List<String> groups) throws Throwable {
// First add to x_portal_user
LOG.debug("INFO: addPMAccount(" + userName + ")" );
if (! isMockRun) {
- if (addMUser(userName) == null) {
- String msg = "Failed to add portal user";
- LOG.error(msg);
- throw new Exception(msg);
+ if (addMUser(userName, userAttrs) == null) {
+ String msg = "Failed to add portal user";
+ LOG.error(msg);
+ throw new Exception(msg);
}
}
- List<String> groups = new ArrayList<String>();
//* Build the user group info object with empty groups and do the rest call
if ( ! isMockRun ) {
- // If the rest call to ranger admin fails,
+ // If the rest call to ranger admin fails,
// propagate the failure to the caller for retry in next sync cycle.
- if (addUserGroupInfo(userName, groups) == null ) {
+ if (addUserGroupInfo(userName, userAttrs, groups) == null ) {
String msg = "Failed to add addorUpdate user group info";
LOG.error(msg);
throw new Exception(msg);
}
}
-
}
-
- private UserGroupInfo addUserGroupInfo(String userName, List<String> groups){
+
+ private UserGroupInfo addUserGroupInfo(String userName, Map<String, String> userAttrs, List<String> groups){
if(LOG.isDebugEnabled()) {
LOG.debug("==> LdapPolicyMgrUserGroupBuilder.addUserGroupInfo " + userName + " and groups");
}
@@ -304,7 +298,7 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
LOG.debug("INFO: addPMXAUser(" + userName + ")");
if (! isMockRun) {
- user = addXUserInfo(userName);
+ user = addXUserInfo(userName, userAttrs);
}
for(String g : groups) {
LOG.debug("INFO: addPMXAGroupToUser(" + userName + "," + g + ")" );
@@ -337,13 +331,15 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
}
}
- private XUserInfo addXUserInfo(String aUserName) {
+ private XUserInfo addXUserInfo(String aUserName, Map<String, String> userAttrs) {
XUserInfo xuserInfo = new XUserInfo();
xuserInfo.setName(aUserName);
xuserInfo.setDescription(aUserName + " - add from Unix box");
+ Gson gson = new Gson();
+ xuserInfo.setOtherAttributes(gson.toJson(userAttrs));
if (userMap.containsKey(aUserName)) {
List<String> roleList = new ArrayList<String>();
roleList.add(userMap.get(aUserName));
@@ -359,7 +355,7 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
List<XGroupInfo> xGroupInfoList = new ArrayList<XGroupInfo>();
for(String groupName : aGroupList) {
- XGroupInfo group = addXGroupInfo(groupName);
+ XGroupInfo group = addXGroupInfo(groupName, null);
xGroupInfoList.add(group);
addXUserGroupInfo(aUserInfo, group);
}
@@ -421,6 +417,10 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
@Override
public void addOrUpdateGroup(String groupName, List<String> users) throws Throwable {
+ }
+
+ @Override
+ public void addOrUpdateGroup(String groupName, Map<String, String> groupAttrs, List<String> users) throws Throwable {
// First get the existing group user mappings from Ranger admin.
// Then compute the delta and send the updated group user mappings to ranger admin.
LOG.debug("addOrUpdateGroup for " + groupName + " with users: " + users);
@@ -484,7 +484,7 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
if ( ! isMockRun ) {
// If the rest call to ranger admin fails,
// propagate the failure to the caller for retry in next sync cycle.
- if (addGroupUserInfo(groupName, addUsers) == null ) {
+ if (addGroupUserInfo(groupName, groupAttrs, addUsers) == null ) {
String msg = "Failed to add addorUpdate group user info";
LOG.error(msg);
throw new Exception(msg);
@@ -654,7 +654,7 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
}
}
- private GroupUserInfo addGroupUserInfo(String groupName, List<String> users){
+ private GroupUserInfo addGroupUserInfo(String groupName, Map<String, String> groupAttrs, List<String> users){
if(LOG.isDebugEnabled()) {
LOG.debug("==> LdapPolicyMgrUserGroupBuilder.addGroupUserInfo " + groupName + " and " + users);
}
@@ -663,7 +663,7 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
LOG.debug("INFO: addPMXAGroup(" + groupName + ")" );
if (! isMockRun) {
- group = addXGroupInfo(groupName);
+ group = addXGroupInfo(groupName, groupAttrs);
}
for(String u : users) {
LOG.debug("INFO: addPMXAGroupToUser(" + groupName + "," + u + ")" );
@@ -701,7 +701,7 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
List<XUserInfo> xUserInfoList = new ArrayList<XUserInfo>();
for(String userName : aUserList) {
- XUserInfo user = addXUserInfo(userName);
+ XUserInfo user = addXUserInfo(userName, null);
xUserInfoList.add(user);
addXUserGroupInfo(user, aGroupInfo);
}
@@ -772,13 +772,15 @@ private static final Logger LOG = Logger.getLogger(LdapPolicyMgrUserGroupBuilder
}
- private MUserInfo addMUser(String aUserName) {
+ private MUserInfo addMUser(String aUserName, Map<String, String> userAttrs) {
MUserInfo ret = null;
MUserInfo userInfo = new MUserInfo();
userInfo.setLoginId(aUserName);
userInfo.setFirstName(aUserName);
userInfo.setLastName(aUserName);
+ Gson gson = new Gson();
+ userInfo.setOtherAttributes(gson.toJson(userAttrs));
String str[] = new String[1];
if (userMap.containsKey(aUserName)) {
str[0] = userMap.get(aUserName);
diff --git a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
index 8efa161..07cba9e 100644
--- a/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
+++ b/ugsync/src/main/java/org/apache/ranger/ldapusersync/process/LdapUserGroupBuilder.java
@@ -721,10 +721,10 @@ public class LdapUserGroupBuilder extends AbstractUserGroupSource {
int userCount = 0;
if (groupMemberAttr == null || groupMemberAttr.size() <= 0) {
LOG.info("No members available for " + gName);
- sink.addOrUpdateGroup(gName, null);
+ sink.addOrUpdateGroup(gName, new HashMap<String, String>(), null);
continue;
}
- sink.addOrUpdateGroup(gName);
+ sink.addOrUpdateGroup(gName, new HashMap<String, String>());
NamingEnumeration<?> userEnum = groupMemberAttr.getAll();
while (userEnum.hasMore()) {
String originalUserFullName = (String) userEnum.next();
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 ae4e474..f9f51d9 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
@@ -146,6 +146,15 @@ public class UserGroupSyncConfig {
private static final String LGSYNC_USER_GROUP_NAME_ATTRIBUTE = "ranger.usersync.ldap.user.groupnameattribute";
private static final String DEFAULT_USER_GROUP_NAME_ATTRIBUTE = "memberof,ismemberof";
+ private static final String LGSYNC_USER_CLOUDID_ATTRIBUTE = "ranger.usersync.ldap.user.cloudid.attribute";
+ private static final String DEFAULT_USER_CLOUDID_ATTRIBUTE = "objectid";
+
+ private static final String LGSYNC_USER_CLOUDID_ATTRIBUTE_DATATYPE = "ranger.usersync.ldap.user.cloudid.attribute.datatype";
+ private static final String DEFAULT_USER_CLOUDID_ATTRIBUTE_DATATYPE = "byte[]";
+
+ private static final String LGSYNC_OTHER_USER_ATTRIBUTES = "ranger.usersync.ldap.user.otherattributes";
+ private static final String DEFAULT_OTHER_USER_ATTRIBUTES = "userurincipaluame,";
+
public static final String UGSYNC_NONE_CASE_CONVERSION_VALUE = "none";
public static final String UGSYNC_LOWER_CASE_CONVERSION_VALUE = "lower";
public static final String UGSYNC_UPPER_CASE_CONVERSION_VALUE = "upper";
@@ -195,6 +204,15 @@ public class UserGroupSyncConfig {
private static final String LGSYNC_GROUP_MEMBER_ATTRIBUTE_NAME = "ranger.usersync.group.memberattributename";
private static final String DEFAULT_LGSYNC_GROUP_MEMBER_ATTRIBUTE_NAME = "member";
+ private static final String LGSYNC_GROUP_CLOUDID_ATTRIBUTE = "ranger.usersync.ldap.group.cloudid.attribute";
+ private static final String DEFAULT_GROUP_CLOUDID_ATTRIBUTE = "objectid";
+
+ private static final String LGSYNC_GROUP_CLOUDID_ATTRIBUTE_DATATYPE = "ranger.usersync.ldap.group.cloudid.attribute.datatype";
+ private static final String DEFAULT_GROUP_CLOUDID_ATTRIBUTE_DATATYPE = "byte[]";
+
+ private static final String LGSYNC_OTHER_GROUP_ATTRIBUTES = "ranger.usersync.ldap.group.otherattributes";
+ private static final String DEFAULT_OTHER_GROUP_ATTRIBUTES = "displayname,";
+
private static final String LGSYNC_GROUP_HIERARCHY_LEVELS = "ranger.usersync.ldap.grouphierarchylevels";
private static final int DEFAULT_LGSYNC_GROUP_HIERARCHY_LEVELS = 0;
@@ -648,6 +666,43 @@ public class UserGroupSyncConfig {
return userGroupNameAttributeSet;
}
+ public Set<String> getOtherUserAttributes() {
+ String otherAttributes = prop.getProperty(LGSYNC_OTHER_USER_ATTRIBUTES);
+ if(otherAttributes == null || otherAttributes.trim().isEmpty()) {
+ otherAttributes = DEFAULT_OTHER_USER_ATTRIBUTES;
+ }
+ StringTokenizer st = new StringTokenizer(otherAttributes, ",");
+ Set<String> otherUserAttributes = new HashSet<String>();
+ while (st.hasMoreTokens()) {
+ otherUserAttributes.add(st.nextToken().trim());
+ }
+ return otherUserAttributes;
+ }
+
+ public String getUserCloudIdAttribute() {
+ String val = prop.getProperty(LGSYNC_USER_CLOUDID_ATTRIBUTE);
+ if (val == null || val.trim().isEmpty()) {
+ return DEFAULT_USER_CLOUDID_ATTRIBUTE;
+ }
+ return val;
+ }
+
+ public String getUserCloudIdAttributeDataType() {
+ String val = prop.getProperty(LGSYNC_USER_CLOUDID_ATTRIBUTE_DATATYPE);
+ if (val == null || val.trim().isEmpty()) {
+ return DEFAULT_USER_CLOUDID_ATTRIBUTE_DATATYPE;
+ }
+ return val;
+ }
+
+ public String getOtherUserAttributeDataType(String attrName) {
+ String attrType = prop.getProperty(LGSYNC_OTHER_USER_ATTRIBUTES + "." + attrName + "datatype");
+ if (attrType == null || attrType.isEmpty()) {
+ attrType = "String";
+ }
+ return attrType.trim();
+ }
+
public String getUserNameCaseConversion() {
String ret = prop.getProperty(UGSYNC_USERNAME_CASE_CONVERSION_PARAM, DEFAULT_UGSYNC_USERNAME_CASE_CONVERSION_VALUE);
return ret.trim().toLowerCase();
@@ -789,6 +844,43 @@ public class UserGroupSyncConfig {
return val;
}
+ public String getGroupCloudIdAttribute() {
+ String val = prop.getProperty(LGSYNC_GROUP_CLOUDID_ATTRIBUTE);
+ if (val == null || val.trim().isEmpty()) {
+ return DEFAULT_GROUP_CLOUDID_ATTRIBUTE;
+ }
+ return val;
+ }
+
+ public String getGroupCloudIdAttributeDataType() {
+ String val = prop.getProperty(LGSYNC_GROUP_CLOUDID_ATTRIBUTE_DATATYPE);
+ if (val == null || val.trim().isEmpty()) {
+ return DEFAULT_GROUP_CLOUDID_ATTRIBUTE_DATATYPE;
+ }
+ return val;
+ }
+
+ public Set<String> getOtherGroupAttributes() {
+ String otherAttributes = prop.getProperty(LGSYNC_OTHER_GROUP_ATTRIBUTES);
+ if(otherAttributes == null || otherAttributes.trim().isEmpty()) {
+ otherAttributes = DEFAULT_OTHER_GROUP_ATTRIBUTES;
+ }
+ StringTokenizer st = new StringTokenizer(otherAttributes, ",");
+ Set<String> otherGroupAttributes = new HashSet<String>();
+ while (st.hasMoreTokens()) {
+ otherGroupAttributes.add(st.nextToken().trim());
+ }
+ return otherGroupAttributes;
+ }
+
+ public String getOtherGroupAttributeDataType(String attrName) {
+ String attrType = prop.getProperty(LGSYNC_OTHER_GROUP_ATTRIBUTES + "." + attrName + "datatype");
+ if (attrType == null || attrType.isEmpty()) {
+ attrType = "String";
+ }
+ return attrType.trim();
+ }
+
public int getGroupHierarchyLevels() {
int groupHierarchyLevels;
String val = prop.getProperty(LGSYNC_GROUP_HIERARCHY_LEVELS);
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/MUserInfo.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/MUserInfo.java
index 841bac6..4f865af 100644
--- a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/MUserInfo.java
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/MUserInfo.java
@@ -26,6 +26,7 @@ public class MUserInfo {
private String lastName;
private String emailAddress;
private String[] userRoleList = { "ROLE_USER" };
+ private String otherAttributes;
public String getLoginId() {
@@ -58,5 +59,12 @@ public class MUserInfo {
public void setUserRoleList(String[] userRoleList) {
this.userRoleList = userRoleList;
}
-
+
+ public String getOtherAttributes() {
+ return otherAttributes;
+ }
+
+ public void setOtherAttributes(String otherAttributes) {
+ this.otherAttributes = otherAttributes;
+ }
}
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XGroupInfo.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XGroupInfo.java
index cbe0eb0..b61f39c 100644
--- a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XGroupInfo.java
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XGroupInfo.java
@@ -26,6 +26,7 @@ public class XGroupInfo {
private String description;
private String groupType;
private String groupSource;
+ private String otherAttributes;
public String getId() {
return id;
}
@@ -57,7 +58,15 @@ public class XGroupInfo {
public void setGroupSource(String groupSource) {
this.groupSource = groupSource;
}
-
+
+ public String getOtherAttributes() {
+ return otherAttributes;
+ }
+
+ public void setOtherAttributes(String otherAttributes) {
+ this.otherAttributes = otherAttributes;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XUserInfo.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XUserInfo.java
index e2f36b2..bee6323 100644
--- a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XUserInfo.java
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/XUserInfo.java
@@ -26,6 +26,7 @@ public class XUserInfo {
private String id;
private String name;
private String description;
+ private String otherAttributes;
private List<String> groupNameList = new ArrayList<String>();
private List<String> userRoleList = new ArrayList<String>();
@@ -74,7 +75,15 @@ public class XUserInfo {
this.userRoleList = userRoleList;
}
- @Override
+ public String getOtherAttributes() {
+ return otherAttributes;
+ }
+
+ public void setOtherAttributes(String otherAttributes) {
+ this.otherAttributes = otherAttributes;
+ }
+
+ @Override
public String toString() {
return "XUserInfo [id=" + id + ", name=" + name + ", description="
+ description + ", groupNameList=" + groupNameList
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 f08c511..7402b69 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
@@ -1374,7 +1374,7 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
}
@Override
- public void addOrUpdateGroup(String groupName) throws Throwable{
+ public void addOrUpdateGroup(String groupName, Map<String, String> groupAttrs) throws Throwable{
XGroupInfo group = groupName2XGroupInfoMap.get(groupName);
if (group == null) { // Does not exists
@@ -1478,7 +1478,7 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
newGroupList.add(groupName);
}
}
- addOrUpdateGroup(groupName);
+ addOrUpdateGroup(groupName, new HashMap<String, String>());
}
@@ -1657,4 +1657,14 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
}
}
}
+
+ @Override
+ public void addOrUpdateUser(String user, Map<String, String> userAttrs, List<String> groups) throws Throwable {
+
+ }
+
+ @Override
+ public void addOrUpdateGroup(String group, Map<String, String> groupAttrs, List<String> users) throws Throwable {
+
+ }
}
diff --git a/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSink.java b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSink.java
index 77bd016..368c4f8 100644
--- a/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSink.java
+++ b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSink.java
@@ -22,6 +22,7 @@
import org.apache.ranger.unixusersync.model.UgsyncAuditInfo;
import java.util.List;
+import java.util.Map;
public interface UserGroupSink {
void init() throws Throwable;
@@ -30,9 +31,13 @@ public interface UserGroupSink {
void addOrUpdateUser(String user) throws Throwable;
- void addOrUpdateGroup(String group) throws Throwable;
+ void addOrUpdateGroup(String group, Map<String, String> groupAttrs) throws Throwable;
void addOrUpdateGroup(String group, List<String> users) throws Throwable;
void postUserGroupAuditInfo(UgsyncAuditInfo ugsyncAuditInfo) throws Throwable;
+
+ void addOrUpdateUser(String user, Map<String, String> userAttrs, List<String> groups) throws Throwable;
+
+ void addOrUpdateGroup(String group, Map<String, String> groupAttrs, List<String> users) throws Throwable;
}
diff --git a/ugsync/src/test/java/org/apache/ranger/usergroupsync/LdapPolicyMgrUserGroupBuilderTest.java b/ugsync/src/test/java/org/apache/ranger/usergroupsync/LdapPolicyMgrUserGroupBuilderTest.java
index 99bc2b4..e10f632 100644
--- a/ugsync/src/test/java/org/apache/ranger/usergroupsync/LdapPolicyMgrUserGroupBuilderTest.java
+++ b/ugsync/src/test/java/org/apache/ranger/usergroupsync/LdapPolicyMgrUserGroupBuilderTest.java
@@ -21,6 +21,7 @@ package org.apache.ranger.usergroupsync;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.ranger.ldapusersync.process.LdapPolicyMgrUserGroupBuilder;
@@ -36,14 +37,13 @@ public class LdapPolicyMgrUserGroupBuilderTest extends LdapPolicyMgrUserGroupBui
}
@Override
- public void addOrUpdateUser(String user, List<String> groups) {
- allGroups.addAll(groups);
- //allUsers.add(user);
+ public void addOrUpdateUser(String user, Map<String, String> userAttrs, List<String> groups) {
+ allUsers.add(user);
//System.out.println("Username: " + user + " and associated groups: " + groups);
}
@Override
- public void addOrUpdateGroup(String group) {
+ public void addOrUpdateGroup(String group, Map<String, String> groupAttrs) {
allGroups.add(group);
//System.out.println("Groupname: " + group);
}
@@ -55,7 +55,7 @@ public class LdapPolicyMgrUserGroupBuilderTest extends LdapPolicyMgrUserGroupBui
}
@Override
- public void addOrUpdateGroup(String group, List<String> users) {
+ public void addOrUpdateGroup(String group, Map<String, String> groupAttrs, List<String> users) {
boolean addGroup = false;
for (String user : users) {
if (allUsers.contains(user)) {
diff --git a/ugsync/src/test/java/org/apache/ranger/usergroupsync/PolicyMgrUserGroupBuilderTest.java b/ugsync/src/test/java/org/apache/ranger/usergroupsync/PolicyMgrUserGroupBuilderTest.java
index 2bc3951..b0ce872 100644
--- a/ugsync/src/test/java/org/apache/ranger/usergroupsync/PolicyMgrUserGroupBuilderTest.java
+++ b/ugsync/src/test/java/org/apache/ranger/usergroupsync/PolicyMgrUserGroupBuilderTest.java
@@ -19,9 +19,7 @@
package org.apache.ranger.usergroupsync;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import org.apache.ranger.unixusersync.process.PolicyMgrUserGroupBuilder;
@@ -43,13 +41,13 @@ public class PolicyMgrUserGroupBuilderTest extends PolicyMgrUserGroupBuilder {
}
@Override
- public void addOrUpdateGroup(String group) {
+ public void addOrUpdateGroup(String group, Map<String, String> groupAttrs ) {
allGroups.add(group);
}
@Override
public void addOrUpdateGroup(String group, List<String> users) {
- addOrUpdateGroup(group);
+ addOrUpdateGroup(group, new HashMap<String, String>());
}
public int getTotalUsers() {