Author: angela
Date: Thu Nov 15 13:58:42 2018
New Revision: 1846652

URL: http://svn.apache.org/viewvc?rev=1846652&view=rev
Log:
OAK-7900 : Allow to spot User.disable with a new, dedicated UserAction

Added:
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/action/UserActionTest.java
    jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/useraction.md
    
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/UserAction.java
Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
    jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/overview.md
    
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/authorizableaction.md
    
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java?rev=1846652&r1=1846651&r2=1846652&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java
 Thu Nov 15 13:58:42 2018
@@ -91,6 +91,7 @@ class ImpersonationImpl implements Imper
         if (!isValidPrincipal(principal)) {
             return false;
         }
+
         String principalName = principal.getName();
         // make sure user does not impersonate himself
         Tree userTree = user.getTree();
@@ -100,6 +101,8 @@ class ImpersonationImpl implements Imper
             return false;
         }
 
+        user.getUserManager().onImpersonation(user, principal, true);
+
         Set<String> impersonators = getImpersonatorNames(userTree);
         if (impersonators.add(principalName)) {
             updateImpersonatorNames(userTree, impersonators);
@@ -116,6 +119,8 @@ class ImpersonationImpl implements Imper
     public boolean revokeImpersonation(@NotNull Principal principal) throws 
RepositoryException {
         String pName = principal.getName();
 
+        user.getUserManager().onImpersonation(user, principal, false);
+
         Tree userTree = user.getTree();
         Set<String> impersonators = getImpersonatorNames(userTree);
         if (impersonators.remove(pName)) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java?rev=1846652&r1=1846651&r2=1846652&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java
 Thu Nov 15 13:58:42 2018
@@ -131,6 +131,9 @@ class UserImpl extends AuthorizableImpl
         if (isAdmin) {
             throw new RepositoryException("The administrator user cannot be 
disabled.");
         }
+
+        getUserManager().onDisable(this, reason);
+
         Tree tree = getTree();
         if (reason == null) {
             if (tree.hasProperty(REP_DISABLED)) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java?rev=1846652&r1=1846651&r2=1846652&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
 Thu Nov 15 13:58:42 2018
@@ -20,13 +20,12 @@ import java.io.UnsupportedEncodingExcept
 import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Set;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 
 import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
+import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;
@@ -39,6 +38,7 @@ import org.apache.jackrabbit.oak.api.Tre
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
 import org.apache.jackrabbit.oak.plugins.value.jcr.PartialValueFactory;
 import org.apache.jackrabbit.oak.security.user.query.UserQueryManager;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
@@ -53,9 +53,9 @@ import org.apache.jackrabbit.oak.spi.sec
 import 
org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
 import 
org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider;
 import org.apache.jackrabbit.oak.spi.security.user.action.GroupAction;
+import org.apache.jackrabbit.oak.spi.security.user.action.UserAction;
 import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtil;
 import org.apache.jackrabbit.oak.spi.security.user.util.UserUtil;
-import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -315,6 +315,22 @@ public class UserManagerImpl implements
         }
     }
 
+    void onDisable(@NotNull User user, @Nullable String disableReason) throws 
RepositoryException {
+        for (UserAction action : filterUserActions()) {
+            action.onDisable(user, disableReason, root, namePathMapper);
+        }
+    }
+
+    void onImpersonation(@NotNull User user, @NotNull Principal principal, 
boolean granting) throws RepositoryException {
+        for (UserAction action : filterUserActions()) {
+            if (granting) {
+                action.onGrantImpersonation(user, principal, root, 
namePathMapper);
+            } else {
+                action.onRevokeImpersonation(user, principal, root, 
namePathMapper);
+            }
+        }
+    }
+
     /**
      * Upon a group being updated (single {@code Authorizable} successfully 
added or removed),
      * call available {@code GroupAction}s and execute the method specific to 
removal or addition.
@@ -326,7 +342,7 @@ public class UserManagerImpl implements
      * @throws RepositoryException If an error occurs.
      */
     void onGroupUpdate(@NotNull Group group, boolean isRemove, @NotNull 
Authorizable member) throws RepositoryException {
-        for (GroupAction action : selectGroupActions()) {
+        for (GroupAction action : filterGroupActions()) {
             if (isRemove) {
                 action.onMemberRemoved(group, member, root, namePathMapper);
             } else {
@@ -348,7 +364,7 @@ public class UserManagerImpl implements
      * @throws RepositoryException If an error occurs.
      */
     void onGroupUpdate(@NotNull Group group, boolean isRemove, boolean 
isContentId, @NotNull Set<String> memberIds, @NotNull Set<String> failedIds) 
throws RepositoryException {
-        for (GroupAction action : selectGroupActions()) {
+        for (GroupAction action : filterGroupActions()) {
             if (isRemove) {
                 action.onMembersRemoved(group, memberIds, failedIds, root, 
namePathMapper);
             } else {
@@ -506,13 +522,12 @@ public class UserManagerImpl implements
      * @return A {@code List} of {@code GroupAction}s. List may be empty.
      */
     @NotNull
-    private List<GroupAction> selectGroupActions() {
-        List<GroupAction> actions = Lists.newArrayList();
-        for (AuthorizableAction action : 
actionProvider.getAuthorizableActions(securityProvider)) {
-            if (action instanceof GroupAction) {
-                actions.add((GroupAction) action);
-            }
-        }
-        return actions;
+    private Iterable<GroupAction> filterGroupActions() {
+        return 
Iterables.filter(actionProvider.getAuthorizableActions(securityProvider), 
GroupAction.class);
+    }
+
+    @NotNull
+    private Iterable<UserAction> filterUserActions() {
+        return 
Iterables.filter(actionProvider.getAuthorizableActions(securityProvider), 
UserAction.class);
     }
 }

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/action/UserActionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/action/UserActionTest.java?rev=1846652&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/action/UserActionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/action/UserActionTest.java
 Thu Nov 15 13:58:42 2018
@@ -0,0 +1,174 @@
+/*
+ * 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.jackrabbit.oak.security.user.action;
+
+import java.security.Principal;
+import java.util.List;
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFactory;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import 
org.apache.jackrabbit.oak.spi.security.user.action.AbstractAuthorizableAction;
+import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction;
+import 
org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
+import org.apache.jackrabbit.oak.spi.security.user.action.UserAction;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class UserActionTest extends AbstractSecurityTest {
+
+    private CountingUserAction cntAction = new CountingUserAction();
+    private ClearProfileAction clearProfileAction = new ClearProfileAction();
+
+    private final AuthorizableActionProvider actionProvider = new 
AuthorizableActionProvider() {
+        @Override
+        public @NotNull List<? extends AuthorizableAction> 
getAuthorizableActions(@NotNull SecurityProvider securityProvider) {
+            return ImmutableList.of(cntAction, clearProfileAction);
+        }
+    };
+
+    @Override
+    protected ConfigurationParameters getSecurityConfigParameters() {
+        ConfigurationParameters userParams = 
ConfigurationParameters.of(UserConstants.PARAM_AUTHORIZABLE_ACTION_PROVIDER, 
actionProvider);
+        return ConfigurationParameters.of(UserConfiguration.NAME, userParams);
+    }
+
+    @Test
+    public void testDisableUserCnt() throws Exception {
+        User user = getTestUser();
+        user.disable("disabled");
+
+        assertEquals(1, cntAction.onDisabledCnt);
+        assertEquals(0, cntAction.onGrantImpCnt);
+        assertEquals(0, cntAction.onRevokeImpCnt);
+
+        user.disable(null);
+        assertEquals(2, cntAction.onDisabledCnt);
+        assertEquals(0, cntAction.onGrantImpCnt);
+        assertEquals(0, cntAction.onRevokeImpCnt);
+    }
+
+    @Test
+    public void testGrantImpCnt() throws Exception {
+        User user = getTestUser();
+        Principal p2 = getUserManager(root).createUser("tmpUser", 
null).getPrincipal();
+
+        user.getImpersonation().grantImpersonation(p2);
+
+        assertEquals(0, cntAction.onDisabledCnt);
+        assertEquals(1, cntAction.onGrantImpCnt);
+        assertEquals(0, cntAction.onRevokeImpCnt);
+    }
+
+    @Test
+    public void testRevokeImpCnt() throws Exception {
+        User user = getTestUser();
+        Principal p2 = getUserManager(root).createUser("tmpUser", 
null).getPrincipal();
+
+        user.getImpersonation().revokeImpersonation(p2);
+
+        assertEquals(0, cntAction.onDisabledCnt);
+        assertEquals(0, cntAction.onGrantImpCnt);
+        assertEquals(1, cntAction.onRevokeImpCnt);
+    }
+
+    @Test
+    public void testDisableRemovesProfiles() throws Exception {
+        User user = getTestUser();
+        ValueFactory vf = getValueFactory();
+        user.setProperty("any", vf.createValue("value"));
+        user.setProperty("profiles/public/nickname", vf.createValue("amal"));
+        user.setProperty("profiles/private/age", vf.createValue(14));
+        root.commit();
+
+        user.disable("disabled");
+
+        assertTrue(user.hasProperty("any"));
+        assertFalse(user.hasProperty("profiles/public/nickname"));
+        assertFalse(user.hasProperty("profiles/private/age"));
+
+        Tree t = root.getTree(user.getPath());
+        assertTrue(t.hasProperty(UserConstants.REP_DISABLED));
+        assertFalse(t.hasChild("profiles"));
+
+        // it's transient:
+        root.refresh();
+        t = root.getTree(user.getPath());
+        assertFalse(t.hasProperty(UserConstants.REP_DISABLED));
+        assertTrue(t.hasChild("profiles"));
+    }
+
+
+    class CountingUserAction extends AbstractAuthorizableAction implements 
UserAction  {
+
+        int onDisabledCnt = 0;
+        int onGrantImpCnt = 0;
+        int onRevokeImpCnt = 0;
+
+        @Override
+        public void onDisable(@NotNull User user, @Nullable String 
disableReason, @NotNull Root root, @NotNull NamePathMapper namePathMapper) 
throws RepositoryException {
+            onDisabledCnt++;
+        }
+
+        @Override
+        public void onGrantImpersonation(@NotNull User user, @NotNull 
Principal principal, @NotNull Root root, @NotNull NamePathMapper 
namePathMapper) throws RepositoryException {
+            onGrantImpCnt++;
+        }
+
+        @Override
+        public void onRevokeImpersonation(@NotNull User user, @NotNull 
Principal principal, @NotNull Root root, @NotNull NamePathMapper 
namePathMapper) throws RepositoryException {
+            onRevokeImpCnt++;
+        }
+    }
+
+    class ClearProfileAction extends AbstractAuthorizableAction implements 
UserAction {
+
+        @Override
+        public void onDisable(@NotNull User user, @Nullable String 
disableReason, @NotNull Root root, @NotNull NamePathMapper namePathMapper) 
throws RepositoryException {
+            if (disableReason != null) {
+                Tree t = root.getTree(user.getPath());
+                if (t.exists() && t.hasChild("profiles")) {
+                    t.getChild("profiles").remove();
+                }
+            }
+        }
+
+        @Override
+        public void onGrantImpersonation(@NotNull User user, @NotNull 
Principal principal, @NotNull Root root, @NotNull NamePathMapper 
namePathMapper) throws RepositoryException {
+            // nothing to do
+        }
+
+        @Override
+        public void onRevokeImpersonation(@NotNull User user, @NotNull 
Principal principal, @NotNull Root root, @NotNull NamePathMapper 
namePathMapper) throws RepositoryException {
+            // nothing to do
+        }
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/overview.md
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/overview.md?rev=1846652&r1=1846651&r2=1846652&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/overview.md 
(original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/overview.md Thu Nov 
15 13:58:42 2018
@@ -86,6 +86,7 @@ The Oak Security Layer
     * [Group Membership](user/membership.html)
     * [Authorizable Actions](user/authorizableaction.html)
     * [Group Actions](user/groupaction.html)
+    * [User Actions](user/useraction.html)
     * [Authorizable Node Name Generation](user/authorizablenodename.html)
     * [Password Expiry and Force Initial Password Change](user/expiry.html)
     * [Password History](user/history.html) 

Modified: 
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/authorizableaction.md
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/authorizableaction.md?rev=1846652&r1=1846651&r2=1846652&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/authorizableaction.md
 (original)
+++ 
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/authorizableaction.md
 Thu Nov 15 13:58:42 2018
@@ -51,7 +51,8 @@ to adhere to this rule and perform trans
 They must not force changes to be persisted by calling 
`org.apache.jackrabbit.oak.api.Root.commit()`.
 
 See section [Group Actions](groupaction.html) for a related extension to
-monitor group specific operations.
+monitor group specific operations and [User Actions](useraction.html) for 
+user specific operations.
 
 ### Default Implementations
 

Added: 
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/useraction.md
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/useraction.md?rev=1846652&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/useraction.md 
(added)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user/useraction.md 
Thu Nov 15 13:58:42 2018
@@ -0,0 +1,87 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+  -->
+
+User Actions
+------------
+
+### Overview
+
+Oak 1.10 comes with an extension to the Jackrabbit user management API that 
allows
+to perform additional actions or validations for user specific operations
+such as
+
+- disable (or enable) a user
+- allowing a given principal to impersonate the target user
+- revoke the ability to impersonate the target user for a given principal
+
+<a name="api_extensions"></a>
+### UserAction API
+
+The following public interface is provided by Oak in the package 
`org.apache.jackrabbit.oak.spi.security.user.action`:
+
+- [UserAction]
+
+The `UserAction` interface extends from `AuthorizableAction` and itself allows 
to perform validations or write
+additional application specific content while executing user specific 
operations. Therefore these actions are executed as part of the transient 
+user management modifications. This contrasts to 
`org.apache.jackrabbit.oak.spi.commit.CommitHook`s
+which in turn are only triggered once modifications are persisted.
+
+Consequently, implementations of the `UserAction` interface are expected 
+to adhere to this rule and perform transient repository operations or 
validation.
+They must not force changes to be persisted by calling 
`org.apache.jackrabbit.oak.api.Root.commit()`.
+
+Any user actions are executed with the editing session and the
+target operation will fail if any of the configured actions fails (e.g. due to
+insufficient permissions by the editing Oak ContentSession).
+
+<a name="default_implementation"></a>
+### Default Implementations
+
+Oak 1.10 doesn't provide any base implementation for `UserAction`.
+
+<a name="xml_import"></a>
+### XML Import
+
+During import the user actions are called in the same way as when the 
corresponding API calls are invoked.
+
+<a name="pluggability"></a>
+### Pluggability
+
+Refer to [Authorizable Actions | Pluggability 
](authorizableaction.html#Pluggability) for details on how to plug
+a new user action into the system.
+
+##### Examples
+
+###### Example Action
+
+This example action removes the profile nodes upon disabling the user:
+
+    ClearProfilesAction extends AbstractAuthorizableAction implements 
UserAction {
+    
+        @Override
+        public void onDisable(@NotNull User user, @Nullable String 
disableReason, @NotNull Root root, @NotNull NamePathMapper namePathMapper) 
throws RepositoryException {
+            if (disableReason != null) {
+                Tree t = root.getTree(user.getPath());
+                if (t.exists() && t.hasChild("profiles")) {
+                    t.getChild("profiles").remove();
+                }
+            }
+        }
+    }
+
+<!-- hidden references -->
+[UserAction]: 
/oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/user/action/UserAction.html

Added: 
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/UserAction.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/UserAction.java?rev=1846652&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/UserAction.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/UserAction.java
 Thu Nov 15 13:58:42 2018
@@ -0,0 +1,80 @@
+/*
+ * 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.jackrabbit.oak.spi.security.user.action;
+
+import java.security.Principal;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * The {@code UserAction} interface allows for implementations to be informed
+ * about and react to the following changes to a {@link User}:
+ *
+ * <ul>
+ * <li>{@link #onDisable(User, String, Root, NamePathMapper)}</li>
+ * </ul>
+ *
+ * <p>
+ * See {@link AuthorizableAction} for details on persisting changes,
+ * configuring actions and the API through which actions are invoked.
+ * </p>
+ *
+ * @since OAK 1.10
+ */
+public interface UserAction extends AuthorizableAction {
+
+    /**
+     * Allows to add application specific behavior associated with disabling 
(or
+     * re-enabling) an user.
+     *
+     * @param user The user to be disabled or re-enabled.
+     * @param disableReason The reason passed to {@link User#disable(String)} 
or {@code null} if the user is to be enabled again.
+     * @param root The root associated with the user manager.
+     * @param namePathMapper The mapper associated with the user manager.
+     * @throws RepositoryException If an error occurs.
+     */
+    void onDisable(@NotNull User user, @Nullable String disableReason, 
@NotNull Root root, @NotNull NamePathMapper namePathMapper) throws 
RepositoryException;
+
+    /**
+     * Allows to add application specific behavior associated with granting a 
given
+     * principal the ability to impersonate the user.
+     *
+     * @param user The user associated with the given {@link 
org.apache.jackrabbit.api.security.user.Impersonation#grantImpersonation(Principal)}
 call.
+     * @param principal The target principal to be granted impersonation.
+     * @param root The root associated with the user manager.
+     * @param namePathMapper The mapper associated with the user manager.
+     * @throws RepositoryException If an error occurs.
+     */
+    void onGrantImpersonation(@NotNull User user, @NotNull Principal 
principal, @NotNull Root root, @NotNull NamePathMapper namePathMapper) throws 
RepositoryException;
+
+    /**
+     * Allows to add application specific behavior associated with revoking a 
given
+     * principal the ability to impersonate the user.
+     *
+     * @param user The user associated with the given {@link 
org.apache.jackrabbit.api.security.user.Impersonation#revokeImpersonation(Principal)}
 call.
+     * @param principal The target principal for which impersonation is 
revoked.
+     * @param root The root associated with the user manager.
+     * @param namePathMapper The mapper associated with the user manager.
+     * @throws RepositoryException If an error occurs.
+     */
+    void onRevokeImpersonation(@NotNull User user, @NotNull Principal 
principal, @NotNull Root root, @NotNull NamePathMapper namePathMapper) throws 
RepositoryException;
+}
\ No newline at end of file

Modified: 
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java?rev=1846652&r1=1846651&r2=1846652&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java
 Thu Nov 15 13:58:42 2018
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.1.2")
+@Version("1.2.0")
 package org.apache.jackrabbit.oak.spi.security.user.action;
 
 import org.osgi.annotation.versioning.Version;


Reply via email to