Skip to content

Commit

Permalink
Basic permissions checking from Subject
Browse files Browse the repository at this point in the history
Adds capability for subject to check if a permission is allowed or not
and creates a mechanism for actions to describe the permissinos
associated with them.

Signed-off-by: Peter Nied <[email protected]>
  • Loading branch information
peternied committed Nov 4, 2022
1 parent 1559e5e commit 014adb4
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.authn;

import java.io.IOException;
import java.util.Objects;

public class Permission {
private final String[] permissionChunks;

public Permission(final String permission) {
this.permissionChunks = permission.split("\\.");
}

public boolean matches(final String permissionRequired) {
Objects.nonNull(permissionRequired);

final Permission required = new Permission(permissionRequired);
for(int i = 0; i < this.permissionChunks.length; i++) {
if (!this.permissionChunks[i].equals(required.permissionChunks[i])) {
return false;
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.opensearch.authn;

import java.security.Principal;
import java.util.List;

/**
* An individual, process, or device that causes information to flow among objects or change to the system state.
Expand All @@ -30,4 +31,10 @@ public interface Subject {
*/
public void login(final AuthenticationToken token);

/**
* The subject will confirm if it has the permissions that are checked against, if it has those permissions it returns null, otherwise it returns the exception.
* Note; this method not throw the exception
* */
public UnauthorizedException checkPermission(List<String> permissions);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.opensearch.authn;

import org.opensearch.authn.Subject;
import org.opensearch.authn.Permission;

/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

public class UnauthorizedException extends RuntimeException {
public UnauthorizedException(final String message) {
super(message);
}
}
8 changes: 8 additions & 0 deletions server/src/main/java/org/opensearch/action/ActionRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@

import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.common.io.stream.StreamOutput;
import org.opensearch.authn.Permission;
import org.opensearch.transport.TransportRequest;

import java.io.IOException;
import java.util.List;

/**
* Base action request implemented by plugins.
Expand Down Expand Up @@ -65,6 +67,12 @@ public boolean getShouldStoreResult() {
return false;
}

/** What permissions are required for this request */
public List<String> requiredPermissions() {
// Default behavior is not to require any permissions
return List.of();
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
Expand Down
2 changes: 2 additions & 0 deletions server/src/main/java/org/opensearch/action/ActionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

package org.opensearch.action;

import java.util.List;

import org.opensearch.common.io.stream.Writeable;
import org.opensearch.common.settings.Settings;
import org.opensearch.transport.TransportRequestOptions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

package org.opensearch.action.admin.indices.create;

import java.util.List;

import org.opensearch.action.ActionType;

/**
Expand All @@ -47,5 +49,4 @@ public class CreateIndexAction extends ActionType<CreateIndexResponse> {
private CreateIndexAction() {
super(NAME, CreateIndexResponse::new);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.List;

import static org.opensearch.action.ValidateActions.addValidationError;
import static org.opensearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
Expand Down Expand Up @@ -154,6 +155,14 @@ public ActionRequestValidationException validate() {
return validationException;
}

@Override
public List<String> requiredPermissions() {
return List.of(
"opensearch.engine.index.create",
"opensearch.engine.index.create." + this.index
);
}

@Override
public String[] indices() {
return new String[] { index };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,17 @@
import org.opensearch.common.lease.Releasable;
import org.opensearch.common.lease.Releasables;
import org.opensearch.common.util.concurrent.ThreadContext;
import org.opensearch.identity.Identity;
import org.opensearch.authn.Subject;
import org.opensearch.authn.Permission;
import org.opensearch.authn.UnauthorizedException;
import org.opensearch.tasks.Task;
import org.opensearch.tasks.TaskCancelledException;
import org.opensearch.tasks.TaskId;
import org.opensearch.tasks.TaskListener;
import org.opensearch.tasks.TaskManager;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
Expand Down Expand Up @@ -180,6 +185,14 @@ public final void execute(Task task, Request request, ActionListener<Response> l
return;
}

final Subject currentSubject = Identity.getAuthManager().getSubject();
final UnauthorizedException unauthorizedException = currentSubject.checkPermission(request.requiredPermissions());
if (unauthorizedException != null) {
listener.onFailure(unauthorizedException);
return;
}


if (task != null && request.getShouldStoreResult()) {
listener = new TaskResultStoringActionListener<>(taskManager, task, listener);
}
Expand Down
10 changes: 10 additions & 0 deletions server/src/main/java/org/opensearch/identity/noop/NoopSubject.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@

import java.security.Principal;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.List;

import org.opensearch.authn.Subject;
import org.opensearch.authn.AuthenticationToken;
import org.opensearch.authn.Principals;
import org.opensearch.authn.Permission;
import org.opensearch.authn.UnauthorizedException;

/**
* Implementation of subject that is always authenticated
Expand Down Expand Up @@ -48,4 +52,10 @@ public String toString() {
public void login(final AuthenticationToken token) {
// Noop subject is always logged in, and all authentication tokens are accepted
}

@Override
public UnauthorizedException checkPermission(final List<String> permissions) {
System.err.println("Check for permission: " + permissions.stream().collect(Collectors.joining(", ")));
return null;
}
}

0 comments on commit 014adb4

Please sign in to comment.