You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2017/06/29 05:48:37 UTC
[30/50] kylin git commit: minor,
introduce ManagedUser to replace Spring User
minor, introduce ManagedUser to replace Spring User
temp
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/cf2f27a3
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/cf2f27a3
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/cf2f27a3
Branch: refs/heads/master
Commit: cf2f27a3a8ffc41d5d909ff2b4fd38887305fe9d
Parents: 071f3b9
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 22 14:52:28 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 22 18:26:32 2017 +0800
----------------------------------------------------------------------
.../rest/controller2/QueryControllerV2.java | 6 +
.../security/KylinAuthenticationProvider.java | 16 +-
.../kylin/rest/security/LdapProvider.java | 107 ---------
.../apache/kylin/rest/security/ManagedUser.java | 235 +++++++++++++++++++
.../rest/service/AclTableMigrationTool.java | 64 ++---
.../rest/service/UserGrantedAuthority.java | 5 +
.../org/apache/kylin/rest/service/UserInfo.java | 82 -------
.../apache/kylin/rest/service/UserService.java | 48 ++--
server/src/main/resources/kylinSecurity.xml | 4 +-
.../rest/controller/UserControllerTest.java | 4 +-
.../kylin/rest/service/ServiceTestBase.java | 15 +-
.../kylin/rest/service/UserServiceTest.java | 8 +-
12 files changed, 318 insertions(+), 276 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
index a641a53..a1b65a0 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
@@ -23,10 +23,13 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.HttpServletResponse;
+import com.google.common.collect.Maps;
import org.apache.commons.io.IOUtils;
+import org.apache.kylin.common.debug.BackdoorToggles;
import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
import org.apache.kylin.rest.controller.BasicController;
import org.apache.kylin.rest.exception.InternalErrorException;
@@ -84,6 +87,9 @@ public class QueryControllerV2 extends BasicController {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
public EnvelopeResponse prepareQueryV2(@RequestBody PrepareSqlRequest sqlRequest) {
+ Map<String, String> toggles = Maps.newHashMap();
+ toggles.put(BackdoorToggles.DEBUG_TOGGLE_PREPARE_ONLY, "true");
+ BackdoorToggles.addToggles(toggles);
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, queryService.doQueryWithCache(sqlRequest), "");
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
index dc475c9..7322b84 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
@@ -18,8 +18,6 @@
package org.apache.kylin.rest.security;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
import org.apache.kylin.common.util.ByteArray;
import org.apache.kylin.rest.service.UserService;
import org.slf4j.Logger;
@@ -30,11 +28,13 @@ import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
@@ -87,17 +87,19 @@ public class KylinAuthenticationProvider implements AuthenticationProvider {
logger.debug("Authenticated user " + authed.toString());
- UserDetails user;
+ ManagedUser user;
if (authed.getDetails() == null) {
//authed.setAuthenticated(false);
- throw new UsernameNotFoundException("User not found in LDAP, check whether he/she has been added to the groups.");
+ throw new UsernameNotFoundException(
+ "User not found in LDAP, check whether he/she has been added to the groups.");
}
if (authed.getDetails() instanceof UserDetails) {
- user = (UserDetails) authed.getDetails();
+ UserDetails details = (UserDetails) authed.getDetails();
+ user = new ManagedUser(details.getUsername(), details.getPassword(), false, details.getAuthorities());
} else {
- user = new User(authentication.getName(), "skippped-ldap", authed.getAuthorities());
+ user = new ManagedUser(authentication.getName(), "skippped-ldap", false, authed.getAuthorities());
}
Assert.notNull(user, "The UserDetail is null.");
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java b/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java
deleted file mode 100644
index c76301b..0000000
--- a/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.kylin.rest.security;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-
-import org.apache.kylin.rest.service.UserService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
-import org.springframework.security.ldap.authentication.LdapAuthenticator;
-import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
-
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Element;
-
-/**
- * @author xduo
- * @deprecated replaced by KylinAuthenticationProvider
- *
- */
-public class LdapProvider extends LdapAuthenticationProvider {
-
- private static final Logger logger = LoggerFactory.getLogger(LdapProvider.class);
-
- @Autowired
- @Qualifier("userService")
- UserService userService;
-
- @Autowired
- private CacheManager cacheManager;
-
- MessageDigest md = null;
-
- /**
- * @param authenticator
- * @param authoritiesPopulator
- */
- public LdapProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) {
- super(authenticator, authoritiesPopulator);
-
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("Failed to init Message Digest ", e);
- }
- }
-
- @Override
- public Authentication authenticate(Authentication authentication) throws AuthenticationException {
- Authentication authed = null;
- Cache userCache = cacheManager.getCache("UserCache");
- md.reset();
- byte[] hashKey = md.digest((authentication.getName() + authentication.getCredentials()).getBytes());
- String userKey = Arrays.toString(hashKey);
-
- Element authedUser = userCache.get(userKey);
- if (null != authedUser) {
- authed = (Authentication) authedUser.getObjectValue();
- SecurityContextHolder.getContext().setAuthentication(authed);
- } else {
- try {
- authed = super.authenticate(authentication);
- userCache.put(new Element(userKey, authed));
- } catch (AuthenticationException e) {
- logger.error("Failed to auth user: " + authentication.getName(), e);
- throw e;
- }
-
- UserDetails user = new User(authentication.getName(), "skippped-ldap", authed.getAuthorities());
-
- if (!userService.userExists(authentication.getName())) {
- userService.createUser(user);
- } else {
- userService.updateUser(user);
- }
- }
-
- return authed;
- }
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
new file mode 100644
index 0000000..4805d5c
--- /dev/null
+++ b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
@@ -0,0 +1,235 @@
+/*
+ * 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.kylin.rest.security;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.apache.kylin.common.persistence.RootPersistentEntity;
+import org.apache.kylin.rest.service.UserGrantedAuthority;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+
+@SuppressWarnings("serial")
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
+public class ManagedUser extends RootPersistentEntity implements UserDetails {
+
+ @JsonProperty
+ private String username;
+ @JsonProperty
+ private String password;
+ @JsonProperty
+ private List<String> authorities = Lists.newArrayList();
+ @JsonProperty
+ private boolean disabled = false;
+ @JsonProperty
+ private boolean defaultPassword = false;
+ @JsonProperty
+ private boolean locked = false;
+ @JsonProperty
+ private long lockedTime = 0L;
+ @JsonProperty
+ private int wrongTime = 0;
+
+ private Boolean legacyCatered = false;
+ //DISABLED_ROLE is a ancient way to represent disabled user
+ //now we no longer support such way, however legacy metadata may still contain it
+ private static final String DISABLED_ROLE = "--disabled--";
+
+ //this is computed
+ private List<UserGrantedAuthority> grantedAuthorities = null;
+
+ public ManagedUser() {
+ }
+
+ public ManagedUser(String username, String password, Boolean defaultPassword, String... authorities) {
+ this.username = username;
+ this.password = password;
+ this.setDefaultPassword(defaultPassword);
+
+ this.authorities = Lists.newArrayList(authorities);
+ this.grantedAuthorities = null;
+ }
+
+ public ManagedUser(String username, String password, Boolean defaultPassword,
+ Collection<? extends GrantedAuthority> grantedAuthorities) {
+ this.username = username;
+ this.password = password;
+ this.setDefaultPassword(defaultPassword);
+
+ this.setGrantedAuthorities(grantedAuthorities);
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String userName) {
+ this.username = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ private void caterLegacy() {
+ if (!legacyCatered) {
+ synchronized (legacyCatered) {
+ Iterator<String> iterator = authorities.iterator();
+ while (iterator.hasNext()) {
+ if (DISABLED_ROLE.equals(iterator.next())) {
+ iterator.remove();
+ this.disabled = true;
+ }
+ }
+ legacyCatered = true;
+ }
+ }
+ }
+
+ public List<UserGrantedAuthority> getAuthorities() {
+ caterLegacy();
+ if (grantedAuthorities == null) {
+ grantedAuthorities = Lists.newArrayList();
+ for (String a : authorities) {
+ this.grantedAuthorities.add(new UserGrantedAuthority(a));
+ }
+ }
+ return grantedAuthorities;
+ }
+
+ public void setGrantedAuthorities(Collection<? extends GrantedAuthority> grantedAuthorities) {
+ this.authorities = Lists
+ .newArrayList(Collections2.transform(grantedAuthorities, new Function<GrantedAuthority, String>() {
+ @Nullable
+ @Override
+ public String apply(@Nullable GrantedAuthority input) {
+ return input.getAuthority();
+ }
+ }));
+ this.grantedAuthorities = null;
+ }
+
+ public boolean isDisabled() {
+ caterLegacy();
+ return disabled;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ }
+
+ public boolean isDefaultPassword() {
+ return defaultPassword;
+ }
+
+ public void setDefaultPassword(boolean defaultPassword) {
+ this.defaultPassword = defaultPassword;
+ }
+
+ public boolean isLocked() {
+ return locked;
+ }
+
+ public void setLocked(boolean locked) {
+ this.locked = locked;
+ }
+
+ public int getWrongTime() {
+ return wrongTime;
+ }
+
+ public long getLockedTime() {
+ return lockedTime;
+ }
+
+ public void increaseWrongTime() {
+ int wrongTime = this.getWrongTime();
+ if (wrongTime == 2) {
+ this.setLocked(true);
+ this.lockedTime = System.currentTimeMillis();
+ this.wrongTime = 0;
+ } else {
+ this.wrongTime = wrongTime + 1;
+ }
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return !locked;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return !disabled;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((username == null) ? 0 : username.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ManagedUser other = (ManagedUser) obj;
+ if (username == null) {
+ if (other.username != null)
+ return false;
+ } else if (!username.equals(other.username))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "KapManagedUser [username=" + username + ", authorities=" + grantedAuthorities + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
index fc50410..64bac23 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
@@ -19,7 +19,6 @@
package org.apache.kylin.rest.service;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -40,6 +39,7 @@ import org.apache.kylin.common.persistence.ResourceStore;
import org.apache.kylin.common.persistence.StringEntity;
import org.apache.kylin.common.util.Bytes;
import org.apache.kylin.rest.security.AclConstant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.apache.kylin.rest.util.Serializer;
import org.apache.kylin.storage.hbase.HBaseConnection;
import org.apache.kylin.storage.hbase.HBaseResourceStore;
@@ -53,11 +53,13 @@ public class AclTableMigrationTool {
private static final Serializer<SidInfo> sidSerializer = new Serializer<SidInfo>(SidInfo.class);
- private static final Serializer<DomainObjectInfo> domainObjSerializer = new Serializer<DomainObjectInfo>(DomainObjectInfo.class);
+ private static final Serializer<DomainObjectInfo> domainObjSerializer = new Serializer<DomainObjectInfo>(
+ DomainObjectInfo.class);
private static final Serializer<AceInfo> aceSerializer = new Serializer<AceInfo>(AceInfo.class);
- private static final Serializer<UserGrantedAuthority[]> ugaSerializer = new Serializer<UserGrantedAuthority[]>(UserGrantedAuthority[].class);
+ private static final Serializer<UserGrantedAuthority[]> ugaSerializer = new Serializer<UserGrantedAuthority[]>(
+ UserGrantedAuthority[].class);
public static final String MIGRATE_OK_PREFIX = "MIGRATE_OK_";
@@ -69,7 +71,8 @@ public class AclTableMigrationTool {
return;
} else {
if (!kylinConfig.getServerMode().equals("all")) {
- throw new IllegalStateException("Please make sure that you have config kylin.server.mode=all before migrating data");
+ throw new IllegalStateException(
+ "Please make sure that you have config kylin.server.mode=all before migrating data");
}
logger.info("Start to migrate acl table data");
ResourceStore store = ResourceStore.getStore(kylinConfig);
@@ -144,11 +147,9 @@ public class AclTableMigrationTool {
return;
Result result = rs.next();
while (result != null) {
- User user = hbaseRowToUser(result);
- UserInfo userInfo = convert(user);
- store.deleteResource(UserService.getId(userInfo.getUsername()));
- store.putResource(UserService.getId(userInfo.getUsername()), userInfo, 0,
- UserService.SERIALIZER);
+ ManagedUser user = hbaseRowToUser(result);
+ store.deleteResource(UserService.getId(user.getUsername()));
+ store.putResource(UserService.getId(user.getUsername()), user, 0, UserService.SERIALIZER);
result = rs.next();
}
}
@@ -172,7 +173,8 @@ public class AclTableMigrationTool {
return store.exists(MIGRATE_OK_PREFIX + tableName);
}
- private void convertToResourceStore(KylinConfig kylinConfig, String tableName, ResourceStore store, ResultConverter converter) throws IOException {
+ private void convertToResourceStore(KylinConfig kylinConfig, String tableName, ResourceStore store,
+ ResultConverter converter) throws IOException {
Table table = null;
ResultScanner rs = null;
@@ -181,7 +183,8 @@ public class AclTableMigrationTool {
table = HBaseConnection.get(kylinConfig.getStorageUrl()).getTable(TableName.valueOf(tableName));
rs = table.getScanner(scan);
converter.convertResult(rs, store);
- store.putResource(MIGRATE_OK_PREFIX + tableName, new StringEntity(tableName + " migrated"), StringEntity.serializer);
+ store.putResource(MIGRATE_OK_PREFIX + tableName, new StringEntity(tableName + " migrated"),
+ StringEntity.serializer);
} finally {
IOUtils.closeQuietly(rs);
IOUtils.closeQuietly(table);
@@ -190,7 +193,8 @@ public class AclTableMigrationTool {
}
private DomainObjectInfo getDomainObjectInfoFromRs(Result result) {
- String type = String.valueOf(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_TYPE_COLUMN)));
+ String type = String.valueOf(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_TYPE_COLUMN)));
String id = new String(result.getRow());
DomainObjectInfo newInfo = new DomainObjectInfo();
newInfo.setId(id);
@@ -199,17 +203,20 @@ public class AclTableMigrationTool {
}
private DomainObjectInfo getParentDomainObjectInfoFromRs(Result result) throws IOException {
- DomainObjectInfo parentInfo = domainObjSerializer.deserialize(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_PARENT_COLUMN)));
+ DomainObjectInfo parentInfo = domainObjSerializer.deserialize(result.getValue(
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_PARENT_COLUMN)));
return parentInfo;
}
private boolean getInheriting(Result result) {
- boolean entriesInheriting = Bytes.toBoolean(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_ENTRY_INHERIT_COLUMN)));
+ boolean entriesInheriting = Bytes.toBoolean(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_ENTRY_INHERIT_COLUMN)));
return entriesInheriting;
}
private SidInfo getOwnerSidInfo(Result result) throws IOException {
- SidInfo owner = sidSerializer.deserialize(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_OWNER_COLUMN)));
+ SidInfo owner = sidSerializer.deserialize(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_OWNER_COLUMN)));
return owner;
}
@@ -226,27 +233,14 @@ public class AclTableMigrationTool {
return allAceInfoMap;
}
- private UserInfo convert(User user) {
- if (user == null)
- return null;
- UserInfo newInfo = new UserInfo();
- newInfo.setUsername(user.getUserName());
- newInfo.setPassword(user.getPassword());
- List<String> authorities = new ArrayList<>();
- for (String auth : user.getAuthorities()) {
- authorities.add(auth);
- }
- newInfo.setAuthorities(authorities);
- return newInfo;
- }
-
- private User hbaseRowToUser(Result result) throws JsonParseException, JsonMappingException, IOException {
+ private ManagedUser hbaseRowToUser(Result result) throws JsonParseException, JsonMappingException, IOException {
if (null == result || result.isEmpty())
return null;
String username = Bytes.toString(result.getRow());
- byte[] valueBytes = result.getValue(Bytes.toBytes(AclConstant.USER_AUTHORITY_FAMILY), Bytes.toBytes(AclConstant.USER_AUTHORITY_COLUMN));
+ byte[] valueBytes = result.getValue(Bytes.toBytes(AclConstant.USER_AUTHORITY_FAMILY),
+ Bytes.toBytes(AclConstant.USER_AUTHORITY_COLUMN));
UserGrantedAuthority[] deserialized = ugaSerializer.deserialize(valueBytes);
String password = "";
@@ -261,13 +255,7 @@ public class AclTableMigrationTool {
authorities = Arrays.asList(deserialized);
}
}
- List<String> authoritiesStr = new ArrayList<>();
- for (UserGrantedAuthority auth : authorities) {
- if (auth != null) {
- authoritiesStr.add(auth.getAuthority());
- }
- }
- return new User(username, password, authoritiesStr);
+ return new ManagedUser(username, password, false, authorities);
}
interface ResultConverter {
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
index 4c2a392..1227177 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
@@ -20,10 +20,15 @@ package org.apache.kylin.rest.service;
import org.springframework.security.core.GrantedAuthority;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonProperty;
+@SuppressWarnings("serial")
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class UserGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = -5128905636841891058L;
+ @JsonProperty
private String authority;
public UserGrantedAuthority() {
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java
deleted file mode 100644
index 644883d..0000000
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.kylin.rest.service;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.kylin.common.persistence.RootPersistentEntity;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-
-@SuppressWarnings("serial")
-public class UserInfo extends RootPersistentEntity {
-
- @JsonProperty()
- private String username;
- @JsonProperty()
- private String password;
- @JsonProperty()
- private List<String> authorities = new ArrayList<>();
-
- public UserInfo(String username, String password, List<String> authorities) {
- this.username = username;
- this.password = password;
- this.authorities = authorities;
- }
-
- public UserInfo(UserDetails user) {
- this.username = user.getUsername();
- this.password = user.getPassword();
- for (GrantedAuthority a : user.getAuthorities()) {
- this.authorities.add(a.getAuthority());
- }
- }
-
- public UserInfo() {
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public List<String> getAuthorities() {
- return authorities;
- }
-
- public void setAuthorities(List<String> authorities) {
- this.authorities = authorities;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
index e803040..504c035 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
@@ -31,15 +31,17 @@ import org.apache.kylin.common.persistence.Serializer;
import org.apache.kylin.rest.exception.InternalErrorException;
import org.apache.kylin.rest.msg.Message;
import org.apache.kylin.rest.msg.MsgPicker;
+import org.apache.kylin.rest.security.ManagedUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Component;
+import com.google.common.base.Preconditions;
+
/**
*/
@Component("userService")
@@ -49,7 +51,7 @@ public class UserService implements UserDetailsManager {
public static final String DIR_PREFIX = "/user/";
- public static final Serializer<UserInfo> SERIALIZER = new JsonSerializer<>(UserInfo.class);
+ public static final Serializer<ManagedUser> SERIALIZER = new JsonSerializer<>(ManagedUser.class);
protected ResourceStore aclStore;
@@ -67,11 +69,13 @@ public class UserService implements UserDetailsManager {
@Override
//@PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN) --- DON'T DO THIS, CAUSES CIRCULAR DEPENDENCY BETWEEN UserService & AclService
public void updateUser(UserDetails user) {
+ Preconditions.checkState(user instanceof ManagedUser, "User {} is not ManagedUser", user);
+ ManagedUser managedUser = (ManagedUser) user;
try {
deleteUser(user.getUsername());
String id = getId(user.getUsername());
- aclStore.putResource(id, new UserInfo(user), 0, SERIALIZER);
- logger.debug("update user : {}", user.getUsername());
+ aclStore.putResource(id, managedUser, 0, SERIALIZER);
+ logger.trace("update user : {}", user.getUsername());
} catch (IOException e) {
throw new InternalErrorException(e);
}
@@ -82,7 +86,7 @@ public class UserService implements UserDetailsManager {
try {
String id = getId(userName);
aclStore.deleteResource(id);
- logger.debug("delete user : {}", userName);
+ logger.trace("delete user : {}", userName);
} catch (IOException e) {
throw new InternalErrorException(e);
}
@@ -96,23 +100,27 @@ public class UserService implements UserDetailsManager {
@Override
public boolean userExists(String userName) {
try {
- logger.debug("judge user exist: {}", userName);
+ logger.trace("judge user exist: {}", userName);
return aclStore.exists(getId(userName));
} catch (IOException e) {
throw new InternalErrorException(e);
}
}
+ /**
+ *
+ * @return a ManagedUser
+ */
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
Message msg = MsgPicker.getMsg();
try {
- UserInfo userInfo = aclStore.getResource(getId(userName), UserInfo.class, SERIALIZER);
- if (userInfo == null) {
+ ManagedUser managedUser = aclStore.getResource(getId(userName), ManagedUser.class, SERIALIZER);
+ if (managedUser == null) {
throw new UsernameNotFoundException(String.format(msg.getUSER_NOT_FOUND(), userName));
}
- logger.debug("load user : {}", userName);
- return wrap(userInfo);
+ logger.trace("load user : {}", userName);
+ return managedUser;
} catch (IOException e) {
throw new InternalErrorException(e);
}
@@ -130,28 +138,12 @@ public class UserService implements UserDetailsManager {
return all;
}
- public List<UserDetails> listUsers() throws IOException {
- List<UserDetails> all = new ArrayList<UserDetails>();
- List<UserInfo> userInfos = aclStore.getAllResources(DIR_PREFIX, UserInfo.class, SERIALIZER);
- for (UserInfo info : userInfos) {
- all.add(wrap(info));
- }
- return all;
+ public List<ManagedUser> listUsers() throws IOException {
+ return aclStore.getAllResources(DIR_PREFIX, ManagedUser.class, SERIALIZER);
}
public static String getId(String userName) {
return DIR_PREFIX + userName;
}
- protected User wrap(UserInfo userInfo) {
- if (userInfo == null)
- return null;
- List<GrantedAuthority> authorities = new ArrayList<>();
- List<String> auths = userInfo.getAuthorities();
- for (String str : auths) {
- authorities.add(new UserGrantedAuthority(str));
- }
- return new User(userInfo.getUsername(), userInfo.getPassword(), authorities);
- }
-
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/main/resources/kylinSecurity.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/kylinSecurity.xml b/server/src/main/resources/kylinSecurity.xml
index 039bded..53ed511 100644
--- a/server/src/main/resources/kylinSecurity.xml
+++ b/server/src/main/resources/kylinSecurity.xml
@@ -246,7 +246,7 @@
<scr:intercept-url pattern="/api/admin*/**" access="hasRole('ROLE_ADMIN')"/>
<scr:intercept-url pattern="/api/**" access="isAuthenticated()"/>
- <scr:logout invalidate-session="true" delete-cookies="JSESSIONID"/>
+ <scr:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-url="/j_spring_security_logout" logout-success-url="/." />
<scr:session-management session-fixation-protection="newSession"/>
</scr:http>
</beans>
@@ -288,7 +288,7 @@
<scr:intercept-url pattern="/api/admin*/**" access="hasRole('ROLE_ADMIN')"/>
<scr:intercept-url pattern="/api/**" access="isAuthenticated()"/>
- <scr:logout invalidate-session="true" delete-cookies="JSESSIONID"/>
+ <scr:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-url="/j_spring_security_logout" logout-success-url="/." />
<scr:session-management session-fixation-protection="newSession"/>
</scr:http>
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java b/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
index 767aaf1..f6b4ae1 100644
--- a/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.kylin.rest.constant.Constant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.apache.kylin.rest.service.ServiceTestBase;
import org.junit.Assert;
import org.junit.Before;
@@ -32,7 +33,6 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
/**
@@ -46,7 +46,7 @@ public class UserControllerTest extends ServiceTestBase {
public static void setupResource() {
staticCreateTestMetadata();
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
- User user = new User("ADMIN", "ADMIN", authorities);
+ ManagedUser user = new ManagedUser("ADMIN", "ADMIN", false, authorities);
Authentication authentication = new TestingAuthenticationToken(user, "ADMIN", Constant.ROLE_ADMIN);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java b/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
index b45b27b..1d60a53 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
@@ -24,6 +24,7 @@ import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.LocalFileMetadataTestCase;
import org.apache.kylin.metadata.cachesync.Broadcaster;
import org.apache.kylin.rest.constant.Constant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -35,7 +36,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -71,18 +71,19 @@ public class ServiceTestBase extends LocalFileMetadataTestCase {
Broadcaster.getInstance(config).notifyClearAll();
if (!userService.userExists("ADMIN")) {
- userService.createUser(new User("ADMIN", "KYLIN", Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ADMIN), new UserGrantedAuthority(Constant.ROLE_ANALYST), new UserGrantedAuthority(Constant.ROLE_MODELER))));
+ userService.createUser(new ManagedUser("ADMIN", "KYLIN", false, Arrays.asList(//
+ new UserGrantedAuthority(Constant.ROLE_ADMIN), new UserGrantedAuthority(Constant.ROLE_ANALYST),
+ new UserGrantedAuthority(Constant.ROLE_MODELER))));
}
if (!userService.userExists("MODELER")) {
- userService.createUser(new User("MODELER", "MODELER", Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ANALYST), new UserGrantedAuthority(Constant.ROLE_MODELER))));
+ userService.createUser(new ManagedUser("MODELER", "MODELER", false, Arrays.asList(//
+ new UserGrantedAuthority(Constant.ROLE_ANALYST), new UserGrantedAuthority(Constant.ROLE_MODELER))));
}
if (!userService.userExists("ANALYST")) {
- userService.createUser(new User("ANALYST", "ANALYST", Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ANALYST))));
+ userService.createUser(new ManagedUser("ANALYST", "ANALYST", false, Arrays.asList(//
+ new UserGrantedAuthority(Constant.ROLE_ANALYST))));
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java b/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
index 0d4b580..c49b552 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
@@ -23,13 +23,13 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.kylin.rest.constant.Constant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
/**
@@ -44,11 +44,12 @@ public class UserServiceTest extends ServiceTestBase {
@Test
public void testBasics() throws IOException {
userService.deleteUser("ADMIN");
+
Assert.assertTrue(!userService.userExists("ADMIN"));
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority(Constant.ROLE_ADMIN));
- User user = new User("ADMIN", "PWD", authorities);
+ ManagedUser user = new ManagedUser("ADMIN", "PWD", false, authorities);
userService.createUser(user);
Assert.assertTrue(userService.userExists("ADMIN"));
@@ -59,7 +60,8 @@ public class UserServiceTest extends ServiceTestBase {
Assert.assertEquals(Constant.ROLE_ADMIN, ud.getAuthorities().iterator().next().getAuthority());
Assert.assertEquals(1, ud.getAuthorities().size());
- Assert.assertTrue(userService.listUserAuthorities().contains(Constant.ROLE_ADMIN));
+ List<String> strings = userService.listUserAuthorities();
+ Assert.assertTrue(strings.contains(Constant.ROLE_ADMIN));
}
}