http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetPreviousValues.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetPreviousValues.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetPreviousValues.java new file mode 100644 index 0000000..569439b --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetPreviousValues.java @@ -0,0 +1,43 @@ +/* + * 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.ActionDAO; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.history.PreviousValue; + +/** + * Gets the action with the specified id. + */ +public class GetPreviousValues implements AdministrationAction<Map<String, List<PreviousValue>>> { + + private final String componentId; + + public GetPreviousValues(String componentId) { + this.componentId = componentId; + } + + @Override + public Map<String, List<PreviousValue>> execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) { + ActionDAO actionDao = daoFactory.getActionDAO(); + return actionDao.getPreviousValues(componentId); + } + +}
http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUserGroupAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUserGroupAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUserGroupAction.java new file mode 100644 index 0000000..5377c46 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUserGroupAction.java @@ -0,0 +1,50 @@ +/* + * 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 org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.user.NiFiUserGroup; + +/** + * + */ +public class GetUserGroupAction implements AdministrationAction<NiFiUserGroup> { + + private final String group; + + public GetUserGroupAction(String group) { + this.group = group; + } + + @Override + public NiFiUserGroup execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + final UserDAO userDAO = daoFactory.getUserDAO(); + final NiFiUserGroup userGroup = new NiFiUserGroup(); + + // set the group + userGroup.setGroup(group); + + // get the users in this group + userGroup.setUsers(userDAO.findUsersForGroup(group)); + + // return the group + return userGroup; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUsersAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUsersAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUsersAction.java new file mode 100644 index 0000000..42d180e --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/GetUsersAction.java @@ -0,0 +1,39 @@ +/* + * 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.Collection; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.user.NiFiUser; + +/** + * + */ +public class GetUsersAction implements AdministrationAction<Collection<NiFiUser>> { + + @Override + public Collection<NiFiUser> execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + // get a UserDAO + UserDAO userDAO = daoFactory.getUserDAO(); + + // return the desired user + return userDAO.findUsers(); + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/HasPendingUserAccounts.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/HasPendingUserAccounts.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/HasPendingUserAccounts.java new file mode 100644 index 0000000..3325642 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/HasPendingUserAccounts.java @@ -0,0 +1,34 @@ +/* + * 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 org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.authorization.AuthorityProvider; + +/** + * Action for creating a NiFiUser account. + */ +public class HasPendingUserAccounts extends AbstractUserAction<Boolean> { + + @Override + public Boolean execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + UserDAO userDao = daoFactory.getUserDAO(); + return userDao.hasPendingUserAccounts(); + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserAccountAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserAccountAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserAccountAction.java new file mode 100644 index 0000000..14596b2 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserAccountAction.java @@ -0,0 +1,58 @@ +/* + * 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 org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.admin.service.AccountNotFoundException; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.user.NiFiUser; + +/** + * Invalidates a user account. + */ +public class InvalidateUserAccountAction implements AdministrationAction<Void> { + + private final String id; + + public InvalidateUserAccountAction(String id) { + this.id = id; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + UserDAO userDao = daoFactory.getUserDAO(); + + // get the current user details + NiFiUser user = userDao.findUserById(id); + + // ensure the user exists + if (user == null) { + throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", id)); + } + + // invalidate the user account + user.setLastVerified(null); + + // create the user entry + userDao.updateUser(user); + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserGroupAccountsAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserGroupAccountsAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserGroupAccountsAction.java new file mode 100644 index 0000000..0cb7e14 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/InvalidateUserGroupAccountsAction.java @@ -0,0 +1,45 @@ +/* + * 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 org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.authorization.AuthorityProvider; + +/** + * Invalidates a user account. + */ +public class InvalidateUserGroupAccountsAction implements AdministrationAction<Void> { + + private final String group; + + public InvalidateUserGroupAccountsAction(String group) { + this.group = group; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + UserDAO userDao = daoFactory.getUserDAO(); + + // create the user entry + userDao.updateGroupVerification(group, null); + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/PurgeActionsAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/PurgeActionsAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/PurgeActionsAction.java new file mode 100644 index 0000000..b5a2883 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/PurgeActionsAction.java @@ -0,0 +1,51 @@ +/* + * 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.Date; +import org.apache.nifi.action.Action; +import org.apache.nifi.admin.dao.ActionDAO; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.authorization.AuthorityProvider; + +/** + * Purges actions up to a specified end date. + */ +public class PurgeActionsAction implements AdministrationAction<Void> { + + private final Date end; + private final Action purgeAction; + + public PurgeActionsAction(Date end, Action purgeAction) { + this.end = end; + this.purgeAction = purgeAction; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) { + ActionDAO actionDao = daoFactory.getActionDAO(); + + // remove the corresponding actions + actionDao.deleteActions(end); + + // create a purge action + actionDao.createAction(purgeAction); + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/RequestUserAccountAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/RequestUserAccountAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/RequestUserAccountAction.java new file mode 100644 index 0000000..3dce6d9 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/RequestUserAccountAction.java @@ -0,0 +1,67 @@ +/* + * 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.Date; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.security.util.CertificateUtils; +import org.apache.nifi.user.AccountStatus; +import org.apache.nifi.user.NiFiUser; + +/** + * + */ +public class RequestUserAccountAction implements AdministrationAction<NiFiUser> { + + private final String dn; + private final String justification; + + public RequestUserAccountAction(String dn, String justification) { + this.dn = dn; + this.justification = justification; + } + + @Override + public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + UserDAO userDao = daoFactory.getUserDAO(); + + // determine if this user already exists + NiFiUser user = userDao.findUserByDn(dn); + if (user != null) { + throw new IllegalArgumentException(String.format("User account for %s already exists.", dn)); + } + + // create the user + user = new NiFiUser(); + user.setDn(dn); + user.setUserName(CertificateUtils.extractUsername(dn)); + user.setJustification(justification); + user.setStatus(AccountStatus.PENDING); + + // update user timestamps + Date now = new Date(); + user.setCreation(now); + + // create the new user account + userDao.createUser(user); + + return user; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/SeedUserAccountsAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/SeedUserAccountsAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/SeedUserAccountsAction.java new file mode 100644 index 0000000..6665ac0 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/SeedUserAccountsAction.java @@ -0,0 +1,164 @@ +/* + * 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.HashSet; +import java.util.Set; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.admin.service.AdministrationException; +import org.apache.nifi.authorization.Authority; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.authorization.exception.AuthorityAccessException; +import org.apache.nifi.authorization.exception.UnknownIdentityException; +import org.apache.nifi.security.util.CertificateUtils; +import org.apache.nifi.user.AccountStatus; +import org.apache.nifi.user.NiFiUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Seeds the user accounts. This action is performed at start up because it + * takes the users specified in the authority provider and makes them available + * to be seen in the UI. This happens because the UI loads the users from the + * cache. Without pre loading the users, the table in the UI would only show a + * given user once they have visited the application. + */ +public class SeedUserAccountsAction extends AbstractUserAction<Void> { + + private static final Logger logger = LoggerFactory.getLogger(SeedUserAccountsAction.class); + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + UserDAO userDao = daoFactory.getUserDAO(); + Set<String> authorizedDns = new HashSet<>(); + + // get the current user cache + final Set<NiFiUser> existingUsers; + try { + existingUsers = userDao.findUsers(); + } catch (Exception e) { + // unable to access local cache... start up failure + logger.error(String.format("Unable to get existing user base. Cannot proceed until these users can be " + + "verified against the current authority provider: %s", e)); + throw new AdministrationException(e); + } + + try { + // all users for all roles + for (final Authority authority : Authority.values()) { + authorizedDns.addAll(authorityProvider.getUsers(authority)); + } + } catch (AuthorityAccessException aae) { + // unable to access the authority provider... honor the cache + logger.warn("Unable to access authority provider due to " + aae); + return null; + } + + final Set<NiFiUser> accountsToRevoke = new HashSet<>(existingUsers); + + // persist the users + for (String dn : authorizedDns) { + NiFiUser user = null; + try { + // locate the user for this dn + user = userDao.findUserByDn(dn); + boolean newAccount = false; + + // if the user does not exist, create a new account + if (user == null) { + logger.info(String.format("Creating user account: %s", dn)); + newAccount = true; + + // create the user + user = new NiFiUser(); + user.setDn(dn); + user.setUserName(CertificateUtils.extractUsername(dn)); + user.setJustification("User details specified by authority provider."); + } else { + logger.info(String.format("User account already created: %s. Updating authorities...", dn)); + } + + // verify the account + verifyAccount(authorityProvider, user); + + // persist the account accordingly + if (newAccount) { + CreateUserAction createUser = new CreateUserAction(user); + createUser.execute(daoFactory, authorityProvider); + } else { + // this is not a new user and we have just verified their + // account, do not revoke... + accountsToRevoke.remove(user); + + // persist the user + UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user); + updateUser.execute(daoFactory, authorityProvider); + + // persist the user's authorities + UpdateUserAuthoritiesCacheAction updateUserAuthorities = new UpdateUserAuthoritiesCacheAction(user); + updateUserAuthorities.execute(daoFactory, authorityProvider); + } + } catch (DataAccessException dae) { + if (user != null) { + logger.warn(String.format("Unable to access account details in local cache for user %s: %s", user, dae.getMessage())); + } else { + logger.warn(String.format("Unable to access account details in local cache: %s", dae.getMessage())); + } + } catch (UnknownIdentityException uie) { + if (user != null) { + logger.warn(String.format("Unable to find account details in authority provider for user %s: %s", user, uie.getMessage())); + } else { + logger.warn(String.format("Unable to find account details in authority provider: %s", uie.getMessage())); + } + } catch (AuthorityAccessException aae) { + logger.warn("Unable to access authority provider due to " + aae); + + // unable to access authority provider for this user, honor the cache for now + accountsToRevoke.remove(user); + } + } + + // remove all users that are no longer in the provider + for (final NiFiUser user : accountsToRevoke) { + // allow pending requests to remain... + if (AccountStatus.PENDING.equals(user.getStatus())) { + continue; + } + + try { + logger.info(String.format("User not authorized with configured provider: %s. Disabling account...", user.getDn())); + + // disable the account and reset its last verified timestamp since it was not found + // in the current configured authority provider + user.setStatus(AccountStatus.DISABLED); + user.setLastVerified(null); + + // update the user record + UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user); + updateUser.execute(daoFactory, authorityProvider); + } catch (final Exception e) { + // unable to revoke access for someone we know is not authorized... fail start up + logger.error(String.format("Unable to revoke access for user %s that is no longer authorized: %s", user, e)); + throw new AdministrationException(e); + } + } + + return null; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserAction.java new file mode 100644 index 0000000..01eaf5f --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserAction.java @@ -0,0 +1,69 @@ +/* + * 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 org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.UserDAO; +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.exception.AuthorityAccessException; +import org.apache.nifi.authorization.exception.UnknownIdentityException; +import org.apache.nifi.user.NiFiUser; + +/** + * + */ +public class UngroupUserAction extends AbstractUserAction<Void> { + + private final String userId; + + public UngroupUserAction(String userId) { + this.userId = userId; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) { + final UserDAO userDao = daoFactory.getUserDAO(); + + // get the user in question + final NiFiUser user = userDao.findUserById(userId); + + // ensure the user exists + if (user == null) { + throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", userId)); + } + + // set the user group + user.setUserGroup(null); + + // update the user locally + userDao.updateUser(user); + + try { + // update the authority provider + authorityProvider.ungroupUser(user.getDn()); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to ungroup user '%s': %s", user.getDn(), uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to ungroup user '%s': %s", user.getDn(), aae.getMessage()), aae); + } + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserGroupAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserGroupAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserGroupAction.java new file mode 100644 index 0000000..fa24fbe --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UngroupUserGroupAction.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.admin.service.action; + +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.UserDAO; +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.exception.AuthorityAccessException; +import org.apache.nifi.authorization.exception.UnknownIdentityException; + +/** + * + */ +public class UngroupUserGroupAction extends AbstractUserAction<Void> { + + private final String group; + + public UngroupUserGroupAction(String group) { + this.group = group; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) { + final UserDAO userDao = daoFactory.getUserDAO(); + + // update the user locally + userDao.ungroup(group); + + try { + // update the authority provider + authorityProvider.ungroup(group); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to ungroup '%s': %s", group, uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to ungroup '%s': %s", group, aae.getMessage()), aae); + } + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAction.java new file mode 100644 index 0000000..cef21d7 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAction.java @@ -0,0 +1,124 @@ +/* + * 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.Date; +import java.util.Set; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.admin.service.AccountNotFoundException; +import org.apache.nifi.admin.service.AdministrationException; +import org.apache.nifi.authorization.Authority; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.authorization.exception.AuthorityAccessException; +import org.apache.nifi.authorization.exception.IdentityAlreadyExistsException; +import org.apache.nifi.authorization.exception.UnknownIdentityException; +import org.apache.nifi.user.AccountStatus; +import org.apache.nifi.user.NiFiUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Sets user authorities. + */ +public class UpdateUserAction extends AbstractUserAction<NiFiUser> { + + private static final Logger logger = LoggerFactory.getLogger(UpdateUserAction.class); + + private final String id; + private final Set<Authority> authorities; + + public UpdateUserAction(String id, Set<Authority> authorities) { + this.id = id; + this.authorities = authorities; + } + + @Override + public NiFiUser execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException, AdministrationException { + UserDAO userDao = daoFactory.getUserDAO(); + + // get the user + NiFiUser user = userDao.findUserById(id); + + // ensure the user exists + if (user == null) { + throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", id)); + } + + // determine whether this users exists + boolean doesDnExist = false; + try { + doesDnExist = authorityProvider.doesDnExist(user.getDn()); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access authority details: %s", aae.getMessage()), aae); + } + + // if the user already doesn't exist, add them + if (!doesDnExist) { + try { + // add the account account and group if necessary + authorityProvider.addUser(user.getDn(), user.getUserGroup()); + } catch (final IdentityAlreadyExistsException iaee) { + logger.warn(String.format("User '%s' already exists in the authority provider. Continuing with user update.", user.getDn())); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access authorities for '%s': %s", user.getDn(), aae.getMessage()), aae); + } + } + + try { + // update the authority provider as approprivate + authorityProvider.setAuthorities(user.getDn(), authorities); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to modify authorities for '%s': %s.", user.getDn(), uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access authorities for '%s': %s.", user.getDn(), aae.getMessage()), aae); + } + + try { + // get the user group + user.setUserGroup(authorityProvider.getGroupForUser(user.getDn())); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to determine the group for '%s': %s.", user.getDn(), uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access the group for '%s': %s.", user.getDn(), aae.getMessage()), aae); + } + + // since all the authorities were updated accordingly, set the authorities + user.getAuthorities().clear(); + user.getAuthorities().addAll(authorities); + + // update the users status in case they were previously pending or disabled + user.setStatus(AccountStatus.ACTIVE); + + // update the users last verified time - this timestamp shouldn't be recorded + // until the both the user's authorities and group have been synced + Date now = new Date(); + user.setLastVerified(now); + + // persist the user's updates + UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user); + updateUser.execute(daoFactory, authorityProvider); + + // persist the user's authorities + UpdateUserAuthoritiesCacheAction updateUserAuthorities = new UpdateUserAuthoritiesCacheAction(user); + updateUserAuthorities.execute(daoFactory, authorityProvider); + + // return the user + return user; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAuthoritiesCacheAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAuthoritiesCacheAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAuthoritiesCacheAction.java new file mode 100644 index 0000000..89661b2 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserAuthoritiesCacheAction.java @@ -0,0 +1,73 @@ +/* + * 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.Set; +import org.apache.nifi.admin.dao.AuthorityDAO; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.admin.service.AccountNotFoundException; +import org.apache.nifi.authorization.Authority; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.user.NiFiUser; +import org.apache.commons.collections4.CollectionUtils; + +/** + * Updates a NiFiUser's authorities. Prior to invoking this action, the user's + * authorities should be set according to the business logic of the service in + * question. This should not be invoked directly when attempting to set user + * authorities as the authorityProvider is not called from this action. + */ +public class UpdateUserAuthoritiesCacheAction extends AbstractUserAction<Void> { + + private final NiFiUser user; + + public UpdateUserAuthoritiesCacheAction(NiFiUser user) { + this.user = user; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + UserDAO userDao = daoFactory.getUserDAO(); + AuthorityDAO authorityDao = daoFactory.getAuthorityDAO(); + + // get the user + NiFiUser currentUser = userDao.findUserById(user.getId()); + + // ensure the user exists + if (currentUser == null) { + throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", user.getId())); + } + + // determine what authorities need to be added/removed + Set<Authority> authorities = user.getAuthorities(); + Set<Authority> authoritiesToAdd = determineAuthoritiesToAdd(currentUser, authorities); + Set<Authority> authoritiesToRemove = determineAuthoritiesToRemove(currentUser, authorities); + + // update the user authorities locally + if (CollectionUtils.isNotEmpty(authoritiesToAdd)) { + authorityDao.createAuthorities(authoritiesToAdd, user.getId()); + } + if (CollectionUtils.isNotEmpty(authoritiesToRemove)) { + authorityDao.deleteAuthorities(authoritiesToRemove, user.getId()); + } + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserCacheAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserCacheAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserCacheAction.java new file mode 100644 index 0000000..288e297 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserCacheAction.java @@ -0,0 +1,47 @@ +/* + * 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 org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.user.NiFiUser; + +/** + * Updates a NiFiUser. This will not update the user authorities, they must be + * updated with the UpdateUserAuthoritiesAction. + */ +public class UpdateUserCacheAction extends AbstractUserAction<Void> { + + private final NiFiUser user; + + public UpdateUserCacheAction(NiFiUser user) { + this.user = user; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + UserDAO userDao = daoFactory.getUserDAO(); + + // update the user + userDao.updateUser(user); + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserGroupAction.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserGroupAction.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserGroupAction.java new file mode 100644 index 0000000..56b214c --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/action/UpdateUserGroupAction.java @@ -0,0 +1,171 @@ +/* + * 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.Date; +import java.util.HashSet; +import java.util.Set; +import org.apache.nifi.admin.dao.DAOFactory; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.dao.UserDAO; +import org.apache.nifi.admin.service.AccountNotFoundException; +import org.apache.nifi.admin.service.AdministrationException; +import org.apache.nifi.authorization.Authority; +import org.apache.nifi.authorization.AuthorityProvider; +import org.apache.nifi.authorization.exception.AuthorityAccessException; +import org.apache.nifi.authorization.exception.UnknownIdentityException; +import org.apache.nifi.user.AccountStatus; +import org.apache.nifi.user.NiFiUser; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Updates all NiFiUser authorities in a specified group. + */ +public class UpdateUserGroupAction extends AbstractUserAction<Void> { + + private static final Logger logger = LoggerFactory.getLogger(UpdateUserGroupAction.class); + + private final String group; + private final Set<String> userIds; + private final Set<Authority> authorities; + + public UpdateUserGroupAction(String group, Set<String> userIds, Set<Authority> authorities) { + this.group = group; + this.userIds = userIds; + this.authorities = authorities; + } + + @Override + public Void execute(DAOFactory daoFactory, AuthorityProvider authorityProvider) throws DataAccessException { + if (userIds == null && authorities == null) { + throw new IllegalArgumentException("Must specify user Ids or authorities."); + } + + UserDAO userDao = daoFactory.getUserDAO(); + + // record the new users being added to this group + final Set<NiFiUser> newUsers = new HashSet<>(); + final Set<String> newUserDns = new HashSet<>(); + + // if the user ids have been specified we need to create/update a group using the specified group name + if (userIds != null) { + if (userIds.isEmpty()) { + throw new IllegalArgumentException("When creating a group, at least one user id must be specified."); + } + + // going to create a group using the specified user ids + for (final String userId : userIds) { + // get the user in question + final NiFiUser user = userDao.findUserById(userId); + + // ensure the user exists + if (user == null) { + throw new AccountNotFoundException(String.format("Unable to find account with ID %s.", userId)); + } + + try { + // if the user is unknown to the authority provider we cannot continue + if (!authorityProvider.doesDnExist(user.getDn()) || AccountStatus.DISABLED.equals(user.getStatus())) { + throw new IllegalStateException(String.format("Unable to group these users because access for '%s' is not %s.", user.getDn(), AccountStatus.ACTIVE.toString())); + } + + // record the user being added to this group + newUsers.add(user); + newUserDns.add(user.getDn()); + } catch (final AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access authority details: %s", aae.getMessage()), aae); + } + } + + try { + // update the authority provider + authorityProvider.setUsersGroup(newUserDns, group); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to set user group '%s': %s", StringUtils.join(newUserDns, ", "), uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to set user group '%s': %s", StringUtils.join(newUserDns, ", "), aae.getMessage()), aae); + } + } + + // get all the users that need to be updated + final Set<NiFiUser> users = new HashSet<>(userDao.findUsersForGroup(group)); + users.addAll(newUsers); + + // ensure the user exists + if (users.isEmpty()) { + throw new AccountNotFoundException(String.format("Unable to find user accounts with group id %s.", group)); + } + + // update each user in this group + for (final NiFiUser user : users) { + // if there are new authorities set them, otherwise refresh them according to the provider + if (authorities != null) { + try { + // update the authority provider as approprivate + authorityProvider.setAuthorities(user.getDn(), authorities); + + // since all the authorities were updated accordingly, set the authorities + user.getAuthorities().clear(); + user.getAuthorities().addAll(authorities); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to modify authorities for '%s': %s.", user.getDn(), uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access authorities for '%s': %s.", user.getDn(), aae.getMessage()), aae); + } + } else { + try { + // refresh the authorities according to the provider + user.getAuthorities().clear(); + user.getAuthorities().addAll(authorityProvider.getAuthorities(user.getDn())); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to determine the authorities for '%s': %s.", user.getDn(), uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access authorities for '%s': %s.", user.getDn(), aae.getMessage()), aae); + } + } + + try { + // get the user group + user.setUserGroup(authorityProvider.getGroupForUser(user.getDn())); + } catch (UnknownIdentityException uie) { + throw new AccountNotFoundException(String.format("Unable to determine the group for '%s': %s.", user.getDn(), uie.getMessage()), uie); + } catch (AuthorityAccessException aae) { + throw new AdministrationException(String.format("Unable to access the group for '%s': %s.", user.getDn(), aae.getMessage()), aae); + } + + // update the users status in case they were previously pending or disabled + user.setStatus(AccountStatus.ACTIVE); + + // update the users last verified time - this timestamp shouldn't be recorded + // until the both the user's authorities and group have been synced + Date now = new Date(); + user.setLastVerified(now); + + // persist the user's updates + UpdateUserCacheAction updateUser = new UpdateUserCacheAction(user); + updateUser.execute(daoFactory, authorityProvider); + + // persist the user's authorities + UpdateUserAuthoritiesCacheAction updateUserAuthorities = new UpdateUserAuthoritiesCacheAction(user); + updateUserAuthorities.execute(daoFactory, authorityProvider); + } + + return null; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/aa998847/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/impl/StandardAuditService.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/impl/StandardAuditService.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/impl/StandardAuditService.java new file mode 100644 index 0000000..e588841 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/src/main/java/org/apache/nifi/admin/service/impl/StandardAuditService.java @@ -0,0 +1,219 @@ +/* + * 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 java.io.IOException; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.apache.nifi.action.Action; +import org.apache.nifi.admin.dao.DataAccessException; +import org.apache.nifi.admin.service.AdministrationException; +import org.apache.nifi.admin.service.AuditService; +import org.apache.nifi.admin.service.action.AddActionsAction; +import org.apache.nifi.admin.service.action.GetActionAction; +import org.apache.nifi.admin.service.action.GetActionsAction; +import org.apache.nifi.admin.service.action.GetPreviousValues; +import org.apache.nifi.admin.service.action.PurgeActionsAction; +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.history.History; +import org.apache.nifi.history.HistoryQuery; +import org.apache.nifi.history.PreviousValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + */ +public class StandardAuditService implements AuditService { + + private static final Logger logger = LoggerFactory.getLogger(StandardAuditService.class); + + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final ReentrantReadWriteLock.ReadLock readLock = lock.readLock(); + private final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); + + private TransactionBuilder transactionBuilder; + + @Override + public void addActions(Collection<Action> actions) { + Transaction transaction = null; + + writeLock.lock(); + try { + // start the transaction + transaction = transactionBuilder.start(); + + // seed the accounts + AddActionsAction addActions = new AddActionsAction(actions); + transaction.execute(addActions); + + // commit the transaction + transaction.commit(); + } catch (TransactionException | DataAccessException te) { + rollback(transaction); + throw new AdministrationException(te); + } catch (Throwable t) { + rollback(transaction); + throw t; + } finally { + closeQuietly(transaction); + writeLock.unlock(); + } + } + + @Override + public Map<String, List<PreviousValue>> getPreviousValues(String componentId) { + Transaction transaction = null; + Map<String, List<PreviousValue>> previousValues = null; + + readLock.lock(); + try { + // start the transaction + transaction = transactionBuilder.start(); + + // seed the accounts + GetPreviousValues getActions = new GetPreviousValues(componentId); + previousValues = transaction.execute(getActions); + + // commit the transaction + transaction.commit(); + } catch (TransactionException | DataAccessException te) { + rollback(transaction); + throw new AdministrationException(te); + } catch (Throwable t) { + rollback(transaction); + throw t; + } finally { + closeQuietly(transaction); + readLock.unlock(); + } + + return previousValues; + } + + @Override + public History getActions(HistoryQuery query) { + Transaction transaction = null; + History history = null; + + readLock.lock(); + try { + // start the transaction + transaction = transactionBuilder.start(); + + // seed the accounts + GetActionsAction getActions = new GetActionsAction(query); + history = transaction.execute(getActions); + + // commit the transaction + transaction.commit(); + } catch (TransactionException | DataAccessException te) { + rollback(transaction); + throw new AdministrationException(te); + } catch (Throwable t) { + rollback(transaction); + throw t; + } finally { + closeQuietly(transaction); + readLock.unlock(); + } + + return history; + } + + @Override + public Action getAction(Integer actionId) { + Transaction transaction = null; + Action action = null; + + readLock.lock(); + try { + // start the transaction + transaction = transactionBuilder.start(); + + // seed the accounts + GetActionAction getAction = new GetActionAction(actionId); + action = transaction.execute(getAction); + + // commit the transaction + transaction.commit(); + } catch (TransactionException | DataAccessException te) { + rollback(transaction); + throw new AdministrationException(te); + } catch (Throwable t) { + rollback(transaction); + throw t; + } finally { + closeQuietly(transaction); + readLock.unlock(); + } + + return action; + } + + @Override + public void purgeActions(Date end, Action purgeAction) { + Transaction transaction = null; + + writeLock.lock(); + try { + // start the transaction + transaction = transactionBuilder.start(); + + // purge the action database + PurgeActionsAction purgeActions = new PurgeActionsAction(end, purgeAction); + transaction.execute(purgeActions); + + // commit the transaction + transaction.commit(); + } catch (TransactionException | DataAccessException te) { + rollback(transaction); + throw new AdministrationException(te); + } catch (Throwable t) { + rollback(transaction); + throw t; + } finally { + closeQuietly(transaction); + writeLock.unlock(); + } + } + + private void rollback(Transaction transaction) { + if (transaction != null) { + transaction.rollback(); + } + } + + private void closeQuietly(final Transaction transaction) { + if (transaction != null) { + try { + transaction.close(); + } catch (final IOException ioe) { + } + } + } + + public void setTransactionBuilder(TransactionBuilder transactionBuilder) { + this.transactionBuilder = transactionBuilder; + } + +}