mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-17 03:48:15 +00:00
refactor(authorization): Add authorizedActor function to Authorizer interface (#4678)
This commit is contained in:
parent
b9a0f3c60e
commit
0f669d5622
@ -0,0 +1,17 @@
|
||||
package com.datahub.authorization;
|
||||
|
||||
import com.linkedin.common.urn.Urn;
|
||||
import java.util.List;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
|
||||
|
||||
@Value
|
||||
@Builder
|
||||
public class AuthorizedActors {
|
||||
String privilege;
|
||||
List<Urn> users;
|
||||
List<Urn> groups;
|
||||
boolean allUsers;
|
||||
boolean allGroups;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.datahub.authorization;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
@ -20,4 +21,12 @@ public interface Authorizer {
|
||||
* Authorizes an action based on the actor, the resource, & required privileges.
|
||||
*/
|
||||
AuthorizationResult authorize(AuthorizationRequest request);
|
||||
|
||||
/**
|
||||
* Retrieves the current list of actors authorized to for a particular privilege against
|
||||
* an optional resource
|
||||
*/
|
||||
AuthorizedActors authorizedActors(
|
||||
final String privilege,
|
||||
final Optional<ResourceSpec> resourceSpec);
|
||||
}
|
||||
|
@ -1,12 +1,19 @@
|
||||
package com.datahub.authorization;
|
||||
|
||||
import com.linkedin.common.urn.Urn;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
/**
|
||||
* A configurable chain of {@link Authorizer}s executed in series to attempt to authenticate an inbound request.
|
||||
*
|
||||
@ -43,11 +50,11 @@ public class AuthorizerChain implements Authorizer {
|
||||
// Authorization was successful - Short circuit
|
||||
return result;
|
||||
} else {
|
||||
log.debug("Received DENY result from Authorizer with class name {}. message: {}", authorizer.getClass().getCanonicalName(), result.getMessage());
|
||||
log.debug("Received DENY result from Authorizer with class name {}. message: {}",
|
||||
authorizer.getClass().getCanonicalName(), result.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"Caught exception while attempting to authorize request using Authorizer {}. Skipping authorizer.",
|
||||
log.error("Caught exception while attempting to authorize request using Authorizer {}. Skipping authorizer.",
|
||||
authorizer.getClass().getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
@ -55,6 +62,59 @@ public class AuthorizerChain implements Authorizer {
|
||||
return new AuthorizationResult(request, AuthorizationResult.Type.DENY, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizedActors authorizedActors(String privilege, Optional<ResourceSpec> resourceSpec) {
|
||||
if (this.authorizers.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AuthorizedActors finalAuthorizedActors = this.authorizers.get(0).authorizedActors(privilege, resourceSpec);
|
||||
for (int i = 1; i < this.authorizers.size(); i++) {
|
||||
finalAuthorizedActors = mergeAuthorizedActors(finalAuthorizedActors,
|
||||
this.authorizers.get(i).authorizedActors(privilege, resourceSpec));
|
||||
}
|
||||
return finalAuthorizedActors;
|
||||
}
|
||||
|
||||
private AuthorizedActors mergeAuthorizedActors(@Nullable AuthorizedActors original,
|
||||
@Nullable AuthorizedActors other) {
|
||||
if (original == null) {
|
||||
return other;
|
||||
}
|
||||
if (other == null) {
|
||||
return original;
|
||||
}
|
||||
|
||||
boolean isAllUsers = original.isAllUsers() || other.isAllUsers();
|
||||
List<Urn> mergedUsers;
|
||||
if (isAllUsers) {
|
||||
// If enabled for all users, no need to check users
|
||||
mergedUsers = Collections.emptyList();
|
||||
} else {
|
||||
Set<Urn> users = new HashSet<>(original.getUsers());
|
||||
users.addAll(other.getUsers());
|
||||
mergedUsers = new ArrayList<>(users);
|
||||
}
|
||||
|
||||
boolean isAllGroups = original.isAllGroups() || other.isAllGroups();
|
||||
List<Urn> mergedGroups;
|
||||
if (isAllGroups) {
|
||||
// If enabled for all users, no need to check users
|
||||
mergedGroups = Collections.emptyList();
|
||||
} else {
|
||||
Set<Urn> groups = new HashSet<>(original.getGroups());
|
||||
groups.addAll(other.getGroups());
|
||||
mergedGroups = new ArrayList<>(groups);
|
||||
}
|
||||
|
||||
return AuthorizedActors.builder()
|
||||
.allUsers(original.isAllUsers() || other.isAllUsers())
|
||||
.allGroups(original.isAllGroups() || other.isAllGroups())
|
||||
.users(mergedUsers)
|
||||
.groups(mergedGroups)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of {@link DataHubAuthorizer} if it is present in the Authentication chain,
|
||||
* or null if it cannot be found.
|
||||
|
@ -131,7 +131,7 @@ public class DataHubAuthorizer implements Authorizer {
|
||||
*/
|
||||
public AuthorizedActors authorizedActors(
|
||||
final String privilege,
|
||||
final Optional<ResourceSpec> resourceSpec) throws RuntimeException {
|
||||
final Optional<ResourceSpec> resourceSpec) {
|
||||
// Step 1: Find policies granting the privilege.
|
||||
final List<DataHubPolicyInfo> policiesToEvaluate = _policyCache.getOrDefault(privilege, new ArrayList<>());
|
||||
|
||||
@ -309,44 +309,4 @@ public class DataHubAuthorizer implements Authorizer {
|
||||
.map(Owner::getOwner)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used to represent all users authorized to perform a particular privilege.
|
||||
*/
|
||||
public static class AuthorizedActors {
|
||||
final String _privilege;
|
||||
final List<Urn> _users;
|
||||
final List<Urn> _groups;
|
||||
final Boolean _allUsers;
|
||||
final Boolean _allGroups;
|
||||
|
||||
public AuthorizedActors(final String privilege, final List<Urn> users, final List<Urn> groups, final Boolean allUsers, final Boolean allGroups) {
|
||||
_privilege = privilege;
|
||||
_users = users;
|
||||
_groups = groups;
|
||||
_allUsers = allUsers;
|
||||
_allGroups = allGroups;
|
||||
}
|
||||
|
||||
public String getPrivilege() {
|
||||
return _privilege;
|
||||
}
|
||||
|
||||
public List<Urn> getUsers() {
|
||||
return _users;
|
||||
}
|
||||
|
||||
public List<Urn> getGroups() {
|
||||
return _groups;
|
||||
}
|
||||
|
||||
public Boolean allUsers() {
|
||||
return _allUsers;
|
||||
}
|
||||
|
||||
public Boolean allGroups() {
|
||||
return _allGroups;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -209,12 +209,12 @@ public class DataHubAuthorizerTest {
|
||||
|
||||
@Test
|
||||
public void testAuthorizedActorsActivePolicy() throws Exception {
|
||||
final DataHubAuthorizer.AuthorizedActors actors =
|
||||
final AuthorizedActors actors =
|
||||
_dataHubAuthorizer.authorizedActors("EDIT_ENTITY_TAGS", // Should be inside the active policy.
|
||||
Optional.of(new ResourceSpec("dataset", "urn:li:dataset:1")));
|
||||
|
||||
assertTrue(actors.allUsers());
|
||||
assertTrue(actors.allGroups());
|
||||
assertTrue(actors.isAllUsers());
|
||||
assertTrue(actors.isAllGroups());
|
||||
|
||||
assertEquals(new HashSet<>(actors.getUsers()), ImmutableSet.of(
|
||||
Urn.createFromString("urn:li:corpuser:user1"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user