|
5 | 5 | */ |
6 | 6 | package org.elasticsearch.xpack.security.action.user; |
7 | 7 |
|
8 | | -import org.apache.logging.log4j.message.ParameterizedMessage; |
9 | | -import org.apache.lucene.util.automaton.Operations; |
10 | 8 | import org.elasticsearch.action.ActionListener; |
11 | 9 | import org.elasticsearch.action.support.ActionFilters; |
12 | 10 | import org.elasticsearch.action.support.HandledTransportAction; |
13 | | -import org.elasticsearch.common.bytes.BytesReference; |
14 | | -import org.elasticsearch.common.collect.Tuple; |
15 | 11 | import org.elasticsearch.common.inject.Inject; |
16 | | -import org.elasticsearch.common.settings.Settings; |
17 | 12 | import org.elasticsearch.tasks.Task; |
18 | 13 | import org.elasticsearch.threadpool.ThreadPool; |
19 | 14 | import org.elasticsearch.transport.TransportService; |
20 | 15 | import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesAction; |
21 | 16 | import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesRequest; |
22 | 17 | import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse; |
23 | 18 | import org.elasticsearch.xpack.core.security.authc.Authentication; |
24 | | -import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; |
25 | | -import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissionsCache; |
26 | | -import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissionsDefinition; |
27 | | -import org.elasticsearch.xpack.core.security.authz.permission.IndicesPermission; |
28 | | -import org.elasticsearch.xpack.core.security.authz.permission.Role; |
29 | | -import org.elasticsearch.xpack.core.security.authz.privilege.ApplicationPrivilege; |
30 | | -import org.elasticsearch.xpack.core.security.authz.privilege.ClusterPrivilege; |
31 | | -import org.elasticsearch.xpack.core.security.authz.privilege.ConditionalClusterPrivilege; |
32 | | -import org.elasticsearch.xpack.core.security.authz.privilege.Privilege; |
33 | 19 | import org.elasticsearch.xpack.core.security.user.User; |
34 | | -import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore; |
35 | | - |
36 | | -import java.util.Arrays; |
37 | | -import java.util.Collections; |
38 | | -import java.util.HashSet; |
39 | | -import java.util.LinkedHashSet; |
40 | | -import java.util.Set; |
41 | | -import java.util.TreeSet; |
42 | | - |
43 | | -import static org.elasticsearch.common.Strings.arrayToCommaDelimitedString; |
| 20 | +import org.elasticsearch.xpack.security.authz.AuthorizationService; |
44 | 21 |
|
45 | 22 | /** |
46 | 23 | * Transport action for {@link GetUserPrivilegesAction} |
47 | 24 | */ |
48 | 25 | public class TransportGetUserPrivilegesAction extends HandledTransportAction<GetUserPrivilegesRequest, GetUserPrivilegesResponse> { |
49 | 26 |
|
50 | 27 | private final ThreadPool threadPool; |
51 | | - private final CompositeRolesStore rolesStore; |
| 28 | + private final AuthorizationService authorizationService; |
52 | 29 |
|
53 | 30 | @Inject |
54 | 31 | public TransportGetUserPrivilegesAction(ThreadPool threadPool, TransportService transportService, |
55 | | - ActionFilters actionFilters, CompositeRolesStore rolesStore) { |
| 32 | + ActionFilters actionFilters, AuthorizationService authorizationService) { |
56 | 33 | super(GetUserPrivilegesAction.NAME, transportService, actionFilters, GetUserPrivilegesRequest::new); |
57 | 34 | this.threadPool = threadPool; |
58 | | - this.rolesStore = rolesStore; |
| 35 | + this.authorizationService = authorizationService; |
59 | 36 | } |
60 | 37 |
|
61 | 38 | @Override |
62 | 39 | protected void doExecute(Task task, GetUserPrivilegesRequest request, ActionListener<GetUserPrivilegesResponse> listener) { |
63 | 40 | final String username = request.username(); |
64 | 41 |
|
65 | | - final User user = Authentication.getAuthentication(threadPool.getThreadContext()).getUser(); |
| 42 | + final Authentication authentication = Authentication.getAuthentication(threadPool.getThreadContext()); |
| 43 | + final User user = authentication.getUser(); |
66 | 44 | if (user.principal().equals(username) == false) { |
67 | 45 | listener.onFailure(new IllegalArgumentException("users may only list the privileges of their own account")); |
68 | 46 | return; |
69 | 47 | } |
70 | 48 |
|
71 | | - // FIXME reuse field permissions cache! |
72 | | - rolesStore.getRoles(user, new FieldPermissionsCache(Settings.EMPTY), ActionListener.wrap( |
73 | | - role -> listener.onResponse(buildResponseObject(role)), |
74 | | - listener::onFailure)); |
75 | | - } |
76 | | - |
77 | | - // package protected for testing |
78 | | - GetUserPrivilegesResponse buildResponseObject(Role userRole) { |
79 | | - logger.trace(() -> new ParameterizedMessage("List privileges for role [{}]", arrayToCommaDelimitedString(userRole.names()))); |
80 | | - |
81 | | - // We use sorted sets for Strings because they will typically be small, and having a predictable order allows for simpler testing |
82 | | - final Set<String> cluster = new TreeSet<>(); |
83 | | - // But we don't have a meaningful ordering for objects like ConditionalClusterPrivilege, so the tests work with "random" ordering |
84 | | - final Set<ConditionalClusterPrivilege> conditionalCluster = new HashSet<>(); |
85 | | - for (Tuple<ClusterPrivilege, ConditionalClusterPrivilege> tup : userRole.cluster().privileges()) { |
86 | | - if (tup.v2() == null) { |
87 | | - if (ClusterPrivilege.NONE.equals(tup.v1()) == false) { |
88 | | - cluster.addAll(tup.v1().name()); |
89 | | - } |
90 | | - } else { |
91 | | - conditionalCluster.add(tup.v2()); |
92 | | - } |
93 | | - } |
94 | | - |
95 | | - final Set<GetUserPrivilegesResponse.Indices> indices = new LinkedHashSet<>(); |
96 | | - for (IndicesPermission.Group group : userRole.indices().groups()) { |
97 | | - final Set<BytesReference> queries = group.getQuery() == null ? Collections.emptySet() : group.getQuery(); |
98 | | - final Set<FieldPermissionsDefinition.FieldGrantExcludeGroup> fieldSecurity = group.getFieldPermissions().hasFieldLevelSecurity() |
99 | | - ? group.getFieldPermissions().getFieldPermissionsDefinition().getFieldGrantExcludeGroups() : Collections.emptySet(); |
100 | | - indices.add(new GetUserPrivilegesResponse.Indices( |
101 | | - Arrays.asList(group.indices()), |
102 | | - group.privilege().name(), |
103 | | - fieldSecurity, |
104 | | - queries, |
105 | | - group.allowRestrictedIndices() |
106 | | - )); |
107 | | - } |
108 | | - |
109 | | - final Set<RoleDescriptor.ApplicationResourcePrivileges> application = new LinkedHashSet<>(); |
110 | | - for (String applicationName : userRole.application().getApplicationNames()) { |
111 | | - for (ApplicationPrivilege privilege : userRole.application().getPrivileges(applicationName)) { |
112 | | - final Set<String> resources = userRole.application().getResourcePatterns(privilege); |
113 | | - if (resources.isEmpty()) { |
114 | | - logger.trace("No resources defined in application privilege {}", privilege); |
115 | | - } else { |
116 | | - application.add(RoleDescriptor.ApplicationResourcePrivileges.builder() |
117 | | - .application(applicationName) |
118 | | - .privileges(privilege.name()) |
119 | | - .resources(resources) |
120 | | - .build()); |
121 | | - } |
122 | | - } |
123 | | - } |
124 | | - |
125 | | - final Privilege runAsPrivilege = userRole.runAs().getPrivilege(); |
126 | | - final Set<String> runAs; |
127 | | - if (Operations.isEmpty(runAsPrivilege.getAutomaton())) { |
128 | | - runAs = Collections.emptySet(); |
129 | | - } else { |
130 | | - runAs = runAsPrivilege.name(); |
131 | | - } |
132 | | - |
133 | | - return new GetUserPrivilegesResponse(cluster, conditionalCluster, indices, application, runAs); |
| 49 | + authorizationService.retrieveUserPrivileges(authentication, request, listener); |
134 | 50 | } |
135 | | - |
136 | 51 | } |
0 commit comments