mirror of https://github.com/apache/nifi.git
NIFI-65:
- Adding an authorizeDownload method to the UserService. - Removing an unused/deprecated unit test.
This commit is contained in:
parent
df9529c561
commit
1c9393032d
|
@ -17,8 +17,11 @@
|
|||
package org.apache.nifi.admin.service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.nifi.authorization.Authority;
|
||||
import org.apache.nifi.authorization.DownloadAuthorization;
|
||||
import org.apache.nifi.user.NiFiUser;
|
||||
import org.apache.nifi.user.NiFiUserGroup;
|
||||
|
||||
|
@ -43,6 +46,16 @@ public interface UserService {
|
|||
*/
|
||||
Boolean hasPendingUserAccount();
|
||||
|
||||
/**
|
||||
* Determines if the users in the dnChain are authorized to download content
|
||||
* with the specified attributes.
|
||||
*
|
||||
* @param dnChain
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes);
|
||||
|
||||
/**
|
||||
* Updates a user group using the specified group comprised of the specified
|
||||
* users. Returns all the users that are currently in the specified group.
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.nifi.admin.service.action;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.nifi.admin.dao.DAOFactory;
|
||||
import org.apache.nifi.admin.service.AccountNotFoundException;
|
||||
import org.apache.nifi.admin.service.AdministrationException;
|
||||
import org.apache.nifi.authorization.AuthorityProvider;
|
||||
import org.apache.nifi.authorization.DownloadAuthorization;
|
||||
import org.apache.nifi.authorization.exception.AuthorityAccessException;
|
||||
import org.apache.nifi.authorization.exception.UnknownIdentityException;
|
||||
|
||||
/**
|
||||
* Attempts to obtain authorization to download the content with the specified
|
||||
* attributes for the specified user.
|
||||
*/
|
||||
public class AuthorizeDownloadAction implements AdministrationAction<DownloadAuthorization> {
|
||||
|
||||
private final List<String> dnChain;
|
||||
private final Map<String, String> attributes;
|
||||
|
||||
public AuthorizeDownloadAction(List<String> dnChain, Map<String, String> attributes) {
|
||||
this.dnChain = dnChain;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAuthorization execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) {
|
||||
try {
|
||||
return authorityProvider.authorizeDownload(dnChain, attributes);
|
||||
} catch (UnknownIdentityException uie) {
|
||||
throw new AccountNotFoundException(uie.getMessage(), uie);
|
||||
} catch (AuthorityAccessException aae) {
|
||||
throw new AdministrationException(aae.getMessage(), aae);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -18,6 +18,8 @@ package org.apache.nifi.admin.service.impl;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
@ -27,6 +29,7 @@ import org.apache.nifi.admin.service.AccountDisabledException;
|
|||
import org.apache.nifi.admin.service.AccountPendingException;
|
||||
import org.apache.nifi.admin.service.AdministrationException;
|
||||
import org.apache.nifi.admin.service.UserService;
|
||||
import org.apache.nifi.admin.service.action.AuthorizeDownloadAction;
|
||||
import org.apache.nifi.admin.service.action.AuthorizeUserAction;
|
||||
import org.apache.nifi.admin.service.action.DeleteUserAction;
|
||||
import org.apache.nifi.admin.service.action.DisableUserAction;
|
||||
|
@ -48,6 +51,7 @@ import org.apache.nifi.admin.service.transaction.Transaction;
|
|||
import org.apache.nifi.admin.service.transaction.TransactionBuilder;
|
||||
import org.apache.nifi.admin.service.transaction.TransactionException;
|
||||
import org.apache.nifi.authorization.Authority;
|
||||
import org.apache.nifi.authorization.DownloadAuthorization;
|
||||
import org.apache.nifi.user.NiFiUser;
|
||||
import org.apache.nifi.user.NiFiUserGroup;
|
||||
import org.apache.nifi.util.FormatUtils;
|
||||
|
@ -440,7 +444,7 @@ public class StandardUserService implements UserService {
|
|||
* modifying a user account. This method should only be invoked from within
|
||||
* a write lock.
|
||||
*
|
||||
* @param id
|
||||
* @param group
|
||||
*/
|
||||
@Override
|
||||
public void invalidateUserGroupAccount(String group) {
|
||||
|
@ -500,6 +504,36 @@ public class StandardUserService implements UserService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAuthorization authorizeDownload(final List<String> dnChain, final Map<String, String> attributes) {
|
||||
Transaction transaction = null;
|
||||
|
||||
readLock.lock();
|
||||
try {
|
||||
// start the transaction
|
||||
transaction = transactionBuilder.start();
|
||||
|
||||
// authorize the download
|
||||
AuthorizeDownloadAction authorizeDownload = new AuthorizeDownloadAction(dnChain, attributes);
|
||||
DownloadAuthorization downloadAuthorization = transaction.execute(authorizeDownload);
|
||||
|
||||
// commit the transaction
|
||||
transaction.commit();
|
||||
|
||||
// return the authorization
|
||||
return downloadAuthorization;
|
||||
} catch (TransactionException | DataAccessException te) {
|
||||
rollback(transaction);
|
||||
throw new AdministrationException(te);
|
||||
} catch (Throwable t) {
|
||||
rollback(transaction);
|
||||
throw t;
|
||||
} finally {
|
||||
closeQuietly(transaction);
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<NiFiUser> getUsers() {
|
||||
Transaction transaction = null;
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.lang.reflect.Method;
|
|||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.xml.XMLConstants;
|
||||
|
@ -365,6 +366,11 @@ public class AuthorityProviderFactoryBean implements FactoryBean, ApplicationCon
|
|||
public void ungroup(String group) throws AuthorityAccessException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException {
|
||||
return DownloadAuthorization.approved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
||||
}
|
||||
|
@ -465,6 +471,13 @@ public class AuthorityProviderFactoryBean implements FactoryBean, ApplicationCon
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAuthorization authorizeDownload(List<String> dnChain, Map<String, String> attributes) throws UnknownIdentityException, AuthorityAccessException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
return baseProvider.authorizeDownload(dnChain, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(AuthorityProviderInitializationContext initializationContext) throws ProviderCreationException {
|
||||
try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) {
|
||||
|
|
|
@ -44,6 +44,8 @@ public class NiFiUser implements Serializable {
|
|||
private AccountStatus status;
|
||||
private EnumSet<Authority> authorities;
|
||||
|
||||
private NiFiUser chain;
|
||||
|
||||
/* getters / setters */
|
||||
public Date getCreation() {
|
||||
return creation;
|
||||
|
@ -117,6 +119,14 @@ public class NiFiUser implements Serializable {
|
|||
this.lastAccessed = lastAccessed;
|
||||
}
|
||||
|
||||
public NiFiUser getChain() {
|
||||
return chain;
|
||||
}
|
||||
|
||||
public void setChain(NiFiUser chain) {
|
||||
this.chain = chain;
|
||||
}
|
||||
|
||||
public Set<Authority> getAuthorities() {
|
||||
if (authorities == null) {
|
||||
authorities = EnumSet.noneOf(Authority.class);
|
||||
|
|
|
@ -1,284 +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.nifi.admin.service.impl;
|
||||
|
||||
import org.junit.Ignore;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Ignore
|
||||
public class NiFiAuthorizationServiceTest {
|
||||
|
||||
// private static final String UNKNOWN_USER_IN_CACHE_DN = "unknown-user-in-cache-dn";
|
||||
// private static final String PENDING_USER_DN = "pending-user-dn";
|
||||
// private static final String DISABLED_USER_DN = "disabled-user-dn";
|
||||
// private static final String UNKNOWN_USER_IN_IDENTITY_PROVIDER_DN = "unknown-user-in-identity-provider-dn";
|
||||
// private static final String ACCESS_EXCEPTION_IN_IDENTITY_PROVIDER_DN = "access-exception-in-identity-provider-dn";
|
||||
// private static final String UNABLE_TO_UPDATE_CACHE_DN = "unable-to-update-cache-dn";
|
||||
// private static final String VERIFICATION_REQUIRED_DN = "verification-required-dn";
|
||||
// private static final String VERIFICATION_NOT_REQUIRED_DN = "verification-not-required-dn";
|
||||
// private static final String NEW_USER_DN = "new-user-dn";
|
||||
//
|
||||
// private UserService userService;
|
||||
// private AuthorityProvider authorityProvider;
|
||||
// private UserDAO userDAO;
|
||||
//
|
||||
// @Before
|
||||
// public void setup() throws Exception {
|
||||
// // mock the web security properties
|
||||
// NiFiProperties properties = Mockito.mock(NiFiProperties.class);
|
||||
// Mockito.when(properties.getSupportNewAccountRequests()).thenReturn(Boolean.TRUE);
|
||||
// Mockito.when(properties.getUserCredentialCacheDurationSeconds()).thenReturn(60);
|
||||
//
|
||||
// // mock the authority provider
|
||||
//
|
||||
// // mock the admin service
|
||||
// userDAO = Mockito.mock(UserDAO.class);
|
||||
// Mockito.doAnswer(new Answer() {
|
||||
//
|
||||
// @Override
|
||||
// public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
// Object[] args = invocation.getArguments();
|
||||
// String dn = (String) args[0];
|
||||
//
|
||||
// NiFiUser user = null;
|
||||
// switch (dn) {
|
||||
// case PENDING_USER_DN:
|
||||
// user = new NiFiUser();
|
||||
// user.setDn(dn);
|
||||
// user.setStatus(AccountStatus.PENDING);
|
||||
// break;
|
||||
// case DISABLED_USER_DN:
|
||||
// user = new NiFiUser();
|
||||
// user.setDn(dn);
|
||||
// user.setStatus(AccountStatus.DISABLED);
|
||||
// break;
|
||||
// case UNKNOWN_USER_IN_IDENTITY_PROVIDER_DN:
|
||||
// case UNABLE_TO_UPDATE_CACHE_DN:
|
||||
// case ACCESS_EXCEPTION_IN_IDENTITY_PROVIDER_DN:
|
||||
// user = new NiFiUser();
|
||||
// user.setDn(dn);
|
||||
// user.setStatus(AccountStatus.ACTIVE);
|
||||
// break;
|
||||
// case VERIFICATION_REQUIRED_DN: {
|
||||
// Calendar calendar = Calendar.getInstance();
|
||||
// calendar.add(Calendar.SECOND, -65);
|
||||
// user = new NiFiUser();
|
||||
// user.setDn(dn);
|
||||
// user.setStatus(AccountStatus.ACTIVE);
|
||||
// user.setLastVerified(calendar.getTime());
|
||||
// user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_ADMIN, Authority.ROLE_DFM));
|
||||
// break;
|
||||
// }
|
||||
// case VERIFICATION_NOT_REQUIRED_DN: {
|
||||
// Calendar calendar = Calendar.getInstance();
|
||||
// calendar.add(Calendar.SECOND, -5);
|
||||
// user = new NiFiUser();
|
||||
// user.setDn(dn);
|
||||
// user.setStatus(AccountStatus.ACTIVE);
|
||||
// user.setLastVerified(calendar.getTime());
|
||||
// user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_ADMIN, Authority.ROLE_DFM));
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// return user;
|
||||
// }
|
||||
// }).when(userDAO).getUser(Mockito.anyString());
|
||||
// Mockito.doAnswer(new Answer() {
|
||||
//
|
||||
// @Override
|
||||
// public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
// Object[] args = invocation.getArguments();
|
||||
// NiFiUser user = (NiFiUser) args[0];
|
||||
//
|
||||
// if (UNABLE_TO_UPDATE_CACHE_DN.equals(user.getDn())) {
|
||||
// throw new AdministrationException();
|
||||
// }
|
||||
// return user;
|
||||
// }
|
||||
// }).when(userDAO).updateUser(Mockito.any(NiFiUser.class));
|
||||
// Mockito.doNothing().when(userDAO).createUser(Mockito.any(NiFiUser.class));
|
||||
//
|
||||
// // mock the authority provider
|
||||
// authorityProvider = Mockito.mock(AuthorityProvider.class);
|
||||
// Mockito.doAnswer(new Answer() {
|
||||
//
|
||||
// @Override
|
||||
// public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
// Object[] args = invocation.getArguments();
|
||||
// String dn = (String) args[0];
|
||||
//
|
||||
// boolean hasDn = false;
|
||||
// if (VERIFICATION_REQUIRED_DN.equals(dn) || NEW_USER_DN.equals(dn)) {
|
||||
// hasDn = true;
|
||||
// }
|
||||
// return hasDn;
|
||||
// }
|
||||
// }).when(authorityProvider).doesDnExist(Mockito.anyString());
|
||||
// Mockito.doAnswer(new Answer() {
|
||||
//
|
||||
// @Override
|
||||
// public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
// Object[] args = invocation.getArguments();
|
||||
// String dn = (String) args[0];
|
||||
//
|
||||
// Set<String> authorities = null;
|
||||
// switch (dn) {
|
||||
// case VERIFICATION_REQUIRED_DN:
|
||||
// case NEW_USER_DN:
|
||||
// authorities = new HashSet<>();
|
||||
// authorities.add("ROLE_MONITOR");
|
||||
// break;
|
||||
// case DISABLED_USER_DN:
|
||||
// throw new UnknownIdentityException("Unable to find user");
|
||||
// }
|
||||
// return authorities;
|
||||
// }
|
||||
// }).when(authorityProvider).getAuthorities(Mockito.anyString());
|
||||
//
|
||||
// // create an instance of the authorization service
|
||||
// userService = new UserServiceImpl();
|
||||
// ((UserServiceImpl) userService).setAuthorityProvider(authorityProvider);
|
||||
// ((UserServiceImpl) userService).set(authorityProvider);
|
||||
//
|
||||
//// authorizationService.setIdentityProvider(identityProvider);
|
||||
//// authorizationService.setAuthorityProvider(authorityProvider);
|
||||
//// authorizationService.setProperties(properties);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures the authorization service correctly handles users who are
|
||||
// * unknown.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test(expected = org.springframework.security.core.userdetails.UsernameNotFoundException.class)
|
||||
// public void testUnknownUserInCache() throws Exception {
|
||||
// authorizationService.loadUserByUsername(WebUtils.formatProxyDn(UNKNOWN_USER_IN_CACHE_DN));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures the authorization service correctly handles users whose accounts
|
||||
// * are PENDING.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test(expected = nifi.admin.service.AccountPendingException.class)
|
||||
// public void testPendingUser() throws Exception {
|
||||
// authorizationService.loadUserByUsername(WebUtils.formatProxyDn(PENDING_USER_DN));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures the authorization service correctly handles users whose accounts
|
||||
// * are DISABLED.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test(expected = org.springframework.security.authentication.DisabledException.class)
|
||||
// public void testDisabledUser() throws Exception {
|
||||
// authorizationService.loadUserByUsername(WebUtils.formatProxyDn(DISABLED_USER_DN));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures the authorization service correctly handles users whose are in
|
||||
// * the cache but have been removed from the identity provider.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test(expected = org.springframework.security.authentication.DisabledException.class)
|
||||
// public void testUnknownUserInIdentityProvider() throws Exception {
|
||||
// authorizationService.loadUserByUsername(WebUtils.formatProxyDn(UNKNOWN_USER_IN_IDENTITY_PROVIDER_DN));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures the authorization service correctly handles cases when the cache
|
||||
// * is unable to be updated.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test(expected = org.springframework.security.authentication.AuthenticationServiceException.class)
|
||||
// public void testUnableToUpdateCache() throws Exception {
|
||||
// authorizationService.loadUserByUsername(WebUtils.formatProxyDn(UNABLE_TO_UPDATE_CACHE_DN));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures the authorization service correctly handles cases when the
|
||||
// * identity provider has an access exception.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test(expected = org.springframework.security.authentication.AuthenticationServiceException.class)
|
||||
// public void testUnableToAccessIdentity() throws Exception {
|
||||
// authorizationService.loadUserByUsername(WebUtils.formatProxyDn(ACCESS_EXCEPTION_IN_IDENTITY_PROVIDER_DN));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures that user authorities are properly loaded from the authority
|
||||
// * provider.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test
|
||||
// public void testVerificationRequiredUser() throws Exception {
|
||||
// NiFiUserDetails userDetails = (NiFiUserDetails) authorizationService.loadUserByUsername(WebUtils.formatProxyDn(VERIFICATION_REQUIRED_DN));
|
||||
// NiFiUser user = userDetails.getNiFiUser();
|
||||
// Mockito.verify(authorityProvider).getAuthorities(VERIFICATION_REQUIRED_DN);
|
||||
//
|
||||
// // ensure the user details
|
||||
// Assert.assertEquals(VERIFICATION_REQUIRED_DN, user.getDn());
|
||||
// Assert.assertEquals(1, user.getAuthorities().size());
|
||||
// Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_MONITOR));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures that user authorities are not loaded when the cache is still
|
||||
// * valid.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test
|
||||
// public void testVerificationNotRequiredUser() throws Exception {
|
||||
// NiFiUserDetails userDetails = (NiFiUserDetails) authorizationService.loadUserByUsername(WebUtils.formatProxyDn(VERIFICATION_NOT_REQUIRED_DN));
|
||||
// NiFiUser user = userDetails.getNiFiUser();
|
||||
// Mockito.verify(authorityProvider, Mockito.never()).getAuthorities(VERIFICATION_NOT_REQUIRED_DN);
|
||||
//
|
||||
// // ensure the user details
|
||||
// Assert.assertEquals(VERIFICATION_NOT_REQUIRED_DN, user.getDn());
|
||||
// Assert.assertEquals(2, user.getAuthorities().size());
|
||||
// Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_ADMIN));
|
||||
// Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_DFM));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Ensures that new users are automatically created when the authority
|
||||
// * provider has their authorities.
|
||||
// *
|
||||
// * @throws Exception
|
||||
// */
|
||||
// @Test
|
||||
// public void testNewUser() throws Exception {
|
||||
// NiFiUserDetails userDetails = (NiFiUserDetails) authorizationService.loadUserByUsername(WebUtils.formatProxyDn(NEW_USER_DN));
|
||||
// NiFiUser user = userDetails.getNiFiUser();
|
||||
// Mockito.verify(authorityProvider).getAuthorities(NEW_USER_DN);
|
||||
//
|
||||
// // ensure the user details
|
||||
// Assert.assertEquals(NEW_USER_DN, user.getDn());
|
||||
// Assert.assertEquals(1, user.getAuthorities().size());
|
||||
// Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_MONITOR));
|
||||
// }
|
||||
}
|
Loading…
Reference in New Issue