• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apache / iotdb / #9733

pending completion
#9733

push

travis_ci

web-flow
[To rel/1.2] Add compression and encoding type check for FastCompactionPerformer (#10712)

32 of 32 new or added lines in 4 files covered. (100.0%)

79232 of 165563 relevant lines covered (47.86%)

0.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

39.63
/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19

20
package org.apache.iotdb.db.auth;
21

22
import org.apache.iotdb.common.rpc.thrift.TSStatus;
23
import org.apache.iotdb.commons.auth.AuthException;
24
import org.apache.iotdb.commons.auth.authorizer.BasicAuthorizer;
25
import org.apache.iotdb.commons.auth.authorizer.IAuthorizer;
26
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
27
import org.apache.iotdb.commons.auth.entity.Role;
28
import org.apache.iotdb.commons.auth.entity.User;
29
import org.apache.iotdb.commons.client.IClientManager;
30
import org.apache.iotdb.commons.client.exception.ClientManagerException;
31
import org.apache.iotdb.commons.consensus.ConfigRegionId;
32
import org.apache.iotdb.commons.exception.IoTDBException;
33
import org.apache.iotdb.commons.exception.MetadataException;
34
import org.apache.iotdb.commons.path.PartialPath;
35
import org.apache.iotdb.commons.utils.AuthUtils;
36
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerReq;
37
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerResp;
38
import org.apache.iotdb.confignode.rpc.thrift.TCheckUserPrivilegesReq;
39
import org.apache.iotdb.confignode.rpc.thrift.TLoginReq;
40
import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp;
41
import org.apache.iotdb.db.protocol.client.ConfigNodeClient;
42
import org.apache.iotdb.db.protocol.client.ConfigNodeClientManager;
43
import org.apache.iotdb.db.protocol.client.ConfigNodeInfo;
44
import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult;
45
import org.apache.iotdb.db.queryengine.plan.statement.AuthorType;
46
import org.apache.iotdb.db.queryengine.plan.statement.sys.AuthorStatement;
47
import org.apache.iotdb.rpc.RpcUtils;
48
import org.apache.iotdb.rpc.TSStatusCode;
49

50
import com.google.common.util.concurrent.SettableFuture;
51
import org.apache.thrift.TException;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

55
import java.util.ArrayList;
56
import java.util.HashSet;
57
import java.util.List;
58
import java.util.Locale;
59
import java.util.Set;
60

61
public class ClusterAuthorityFetcher implements IAuthorityFetcher {
62
  private static final Logger logger = LoggerFactory.getLogger(ClusterAuthorityFetcher.class);
1✔
63

64
  private final IAuthorCache iAuthorCache;
65
  private IAuthorizer authorizer;
66

67
  private static final IClientManager<ConfigRegionId, ConfigNodeClient> CONFIG_NODE_CLIENT_MANAGER =
1✔
68
      ConfigNodeClientManager.getInstance();
1✔
69

70
  public ClusterAuthorityFetcher(IAuthorCache iAuthorCache) {
1✔
71
    this.iAuthorCache = iAuthorCache;
1✔
72
    try {
73
      authorizer = BasicAuthorizer.getInstance();
1✔
74
    } catch (AuthException e) {
×
75
      logger.error("get user or role permissionInfo failed because ", e);
×
76
    }
1✔
77
  }
1✔
78

79
  @Override
80
  public TSStatus checkUserPrivileges(String username, List<PartialPath> allPath, int permission) {
81
    User user = iAuthorCache.getUserCache(username);
1✔
82
    if (user != null) {
1✔
83
      for (PartialPath path : allPath) {
1✔
84
        try {
85
          if (!user.isOpenIdUser() || !authorizer.checkUserPrivileges(username, path, permission)) {
1✔
86
            if (!user.checkPrivilege(path, permission)) {
1✔
87
              if (user.getRoleList().isEmpty()) {
1✔
88
                return RpcUtils.getStatus(TSStatusCode.NO_PERMISSION);
1✔
89
              }
90
              boolean status = false;
1✔
91
              for (String roleName : user.getRoleList()) {
1✔
92
                Role role = iAuthorCache.getRoleCache(roleName);
1✔
93
                // It is detected that the role of the user does not exist in the cache, indicating
94
                // that the permission information of the role has changed.
95
                // The user cache needs to be initialized
96
                if (role == null) {
1✔
97
                  iAuthorCache.invalidateCache(username, "");
×
98
                  return checkPath(username, allPath, permission);
×
99
                }
100
                status = role.checkPrivilege(path, permission);
1✔
101
                if (status) {
1✔
102
                  break;
1✔
103
                }
104
              }
1✔
105
              if (!status) {
1✔
106
                return RpcUtils.getStatus(TSStatusCode.NO_PERMISSION);
1✔
107
              }
108
            }
109
          }
110
        } catch (AuthException e) {
×
111
          return RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR, e.getMessage());
×
112
        }
1✔
113
      }
1✔
114
      return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
1✔
115
    } else {
116
      return checkPath(username, allPath, permission);
×
117
    }
118
  }
119

120
  @Override
121
  public SettableFuture<ConfigTaskResult> operatePermission(AuthorStatement authorStatement) {
122
    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
×
123
    try (ConfigNodeClient configNodeClient =
×
124
        CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
×
125
      // Construct request using statement
126
      TAuthorizerReq authorizerReq = statementToAuthorizerReq(authorStatement);
×
127
      // Send request to some API server
128
      TSStatus tsStatus = configNodeClient.operatePermission(authorizerReq);
×
129
      // Get response or throw exception
130
      if (TSStatusCode.SUCCESS_STATUS.getStatusCode() != tsStatus.getCode()) {
×
131
        logger.error(
×
132
            "Failed to execute {} in config node, status is {}.",
133
            AuthorType.values()[authorizerReq.getAuthorType()].toString().toLowerCase(Locale.ROOT),
×
134
            tsStatus);
135
        future.setException(new IoTDBException(tsStatus.message, tsStatus.code));
×
136
      } else {
137
        future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
×
138
      }
139
    } catch (ClientManagerException | TException e) {
×
140
      logger.error("Failed to connect to config node.");
×
141
      future.setException(e);
×
142
    } catch (AuthException e) {
×
143
      future.setException(e);
×
144
    }
×
145
    // If the action is executed successfully, return the Future.
146
    // If your operation is async, you can return the corresponding future directly.
147
    return future;
×
148
  }
149

150
  @Override
151
  public SettableFuture<ConfigTaskResult> queryPermission(AuthorStatement authorStatement) {
152
    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
×
153
    TAuthorizerResp authorizerResp = new TAuthorizerResp();
×
154

155
    try (ConfigNodeClient configNodeClient =
×
156
        CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
×
157
      // Construct request using statement
158
      TAuthorizerReq authorizerReq = statementToAuthorizerReq(authorStatement);
×
159
      // Send request to some API server
160
      authorizerResp = configNodeClient.queryPermission(authorizerReq);
×
161
      // Get response or throw exception
162
      if (TSStatusCode.SUCCESS_STATUS.getStatusCode() != authorizerResp.getStatus().getCode()) {
×
163
        logger.error(
×
164
            "Failed to execute {} in config node, status is {}.",
165
            AuthorType.values()[authorizerReq.getAuthorType()].toString().toLowerCase(Locale.ROOT),
×
166
            authorizerResp.getStatus());
×
167
        future.setException(
×
168
            new IoTDBException(
169
                authorizerResp.getStatus().message, authorizerResp.getStatus().code));
×
170
      } else {
171
        AuthorizerManager.getInstance().buildTSBlock(authorizerResp.getAuthorizerInfo(), future);
×
172
      }
173
    } catch (ClientManagerException | TException e) {
×
174
      logger.error("Failed to connect to config node.");
×
175
      authorizerResp.setStatus(
×
176
          RpcUtils.getStatus(
×
177
              TSStatusCode.EXECUTE_STATEMENT_ERROR, "Failed to connect to config node."));
178
      future.setException(
×
179
          new IoTDBException(authorizerResp.getStatus().message, authorizerResp.getStatus().code));
×
180
    } catch (AuthException e) {
×
181
      future.setException(e);
×
182
    }
×
183
    return future;
×
184
  }
185

186
  @Override
187
  public IAuthorCache getAuthorCache() {
188
    return iAuthorCache;
1✔
189
  }
190

191
  @Override
192
  public TSStatus checkUser(String username, String password) {
193
    User user = iAuthorCache.getUserCache(username);
×
194
    if (user != null) {
×
195
      if (user.isOpenIdUser()) {
×
196
        return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
×
197
      } else if (password != null && AuthUtils.validatePassword(password, user.getPassword())) {
×
198
        return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
×
199
      } else {
200
        return RpcUtils.getStatus(TSStatusCode.WRONG_LOGIN_PASSWORD, "Authentication failed.");
×
201
      }
202
    } else {
203
      TLoginReq req = new TLoginReq(username, password);
×
204
      TPermissionInfoResp status = null;
×
205
      try (ConfigNodeClient configNodeClient =
×
206
          CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
×
207
        // Send request to some API server
208
        status = configNodeClient.login(req);
×
209
      } catch (ClientManagerException | TException e) {
×
210
        logger.error("Failed to connect to config node.");
×
211
        status = new TPermissionInfoResp();
×
212
        status.setStatus(
×
213
            RpcUtils.getStatus(
×
214
                TSStatusCode.EXECUTE_STATEMENT_ERROR, "Failed to connect to config node."));
215
      } finally {
216
        if (status == null) {
×
217
          status = new TPermissionInfoResp();
×
218
        }
219
      }
220
      if (status.getStatus().getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
×
221
        iAuthorCache.putUserCache(username, cacheUser(status));
×
222
        return status.getStatus();
×
223
      } else {
224
        return status.getStatus();
×
225
      }
226
    }
227
  }
228

229
  public TSStatus checkPath(String username, List<PartialPath> allPath, int permission) {
230
    TCheckUserPrivilegesReq req =
×
231
        new TCheckUserPrivilegesReq(
232
            username, AuthUtils.serializePartialPathList(allPath), permission);
×
233
    TPermissionInfoResp permissionInfoResp;
234
    try (ConfigNodeClient configNodeClient =
×
235
        CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
×
236
      // Send request to some API server
237
      permissionInfoResp = configNodeClient.checkUserPrivileges(req);
×
238
    } catch (ClientManagerException | TException e) {
×
239
      logger.error("Failed to connect to config node.");
×
240
      permissionInfoResp = new TPermissionInfoResp();
×
241
      permissionInfoResp.setStatus(
×
242
          RpcUtils.getStatus(
×
243
              TSStatusCode.EXECUTE_STATEMENT_ERROR, "Failed to connect to config node."));
244
    }
×
245
    if (permissionInfoResp.getStatus().getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
×
246
      iAuthorCache.putUserCache(username, cacheUser(permissionInfoResp));
×
247
      return permissionInfoResp.getStatus();
×
248
    } else {
249
      return permissionInfoResp.getStatus();
×
250
    }
251
  }
252

253
  /** Cache user. */
254
  public User cacheUser(TPermissionInfoResp tPermissionInfoResp) {
255
    User user = new User();
1✔
256
    List<String> privilegeList = tPermissionInfoResp.getUserInfo().getPrivilegeList();
1✔
257
    List<PathPrivilege> pathPrivilegeList = new ArrayList<>();
1✔
258
    user.setName(tPermissionInfoResp.getUserInfo().getUsername());
1✔
259
    user.setPassword(tPermissionInfoResp.getUserInfo().getPassword());
1✔
260
    for (int i = 0; i < privilegeList.size(); i += 2) {
1✔
261
      String path = privilegeList.get(i);
1✔
262
      String privilege = privilegeList.get(i + 1);
1✔
263
      try {
264
        pathPrivilegeList.add(toPathPrivilege(new PartialPath(path), privilege));
1✔
265
      } catch (MetadataException e) {
×
266
        logger.error("Failed to parse path {}.", path, e);
×
267
      }
1✔
268
    }
269
    user.setOpenIdUser(tPermissionInfoResp.getUserInfo().isIsOpenIdUser());
1✔
270
    user.setPrivilegeList(pathPrivilegeList);
1✔
271
    user.setRoleList(tPermissionInfoResp.getUserInfo().getRoleList());
1✔
272
    for (String roleName : tPermissionInfoResp.getRoleInfo().keySet()) {
1✔
273
      iAuthorCache.putRoleCache(roleName, cacheRole(roleName, tPermissionInfoResp));
1✔
274
    }
1✔
275
    return user;
1✔
276
  }
277

278
  /** Cache role. */
279
  public Role cacheRole(String roleName, TPermissionInfoResp tPermissionInfoResp) {
280
    Role role = new Role();
1✔
281
    List<String> privilegeList = tPermissionInfoResp.getRoleInfo().get(roleName).getPrivilegeList();
1✔
282
    List<PathPrivilege> pathPrivilegeList = new ArrayList<>();
1✔
283
    role.setName(tPermissionInfoResp.getRoleInfo().get(roleName).getRoleName());
1✔
284
    for (int i = 0; i < privilegeList.size(); i += 2) {
1✔
285
      String path = privilegeList.get(i);
1✔
286
      String privilege = privilegeList.get(i + 1);
1✔
287
      try {
288
        pathPrivilegeList.add(toPathPrivilege(new PartialPath(path), privilege));
1✔
289
      } catch (MetadataException e) {
×
290
        logger.error("Failed to parse path {}.", path, e);
×
291
      }
1✔
292
    }
293
    role.setPrivilegeList(pathPrivilegeList);
1✔
294
    return role;
1✔
295
  }
296

297
  /**
298
   * Convert user privilege information obtained from confignode to {@link PathPrivilege}.
299
   *
300
   * @param path permission path
301
   * @param privilege privilegeIds
302
   * @return
303
   */
304
  private PathPrivilege toPathPrivilege(PartialPath path, String privilege) {
305
    PathPrivilege pathPrivilege = new PathPrivilege();
1✔
306
    String[] privileges = privilege.replace(" ", "").split(",");
1✔
307
    Set<Integer> privilegeIds = new HashSet<>();
1✔
308
    for (String p : privileges) {
1✔
309
      privilegeIds.add(Integer.parseInt(p));
1✔
310
    }
311
    pathPrivilege.setPrivileges(privilegeIds);
1✔
312
    pathPrivilege.setPath(path);
1✔
313
    return pathPrivilege;
1✔
314
  }
315

316
  private TAuthorizerReq statementToAuthorizerReq(AuthorStatement authorStatement)
317
      throws AuthException {
318
    if (authorStatement.getAuthorType() == null) {
×
319
      authorStatement.setNodeNameList(new ArrayList<>());
×
320
    }
321
    return new TAuthorizerReq(
×
322
        authorStatement.getAuthorType().ordinal(),
×
323
        authorStatement.getUserName() == null ? "" : authorStatement.getUserName(),
×
324
        authorStatement.getRoleName() == null ? "" : authorStatement.getRoleName(),
×
325
        authorStatement.getPassWord() == null ? "" : authorStatement.getPassWord(),
×
326
        authorStatement.getNewPassword() == null ? "" : authorStatement.getNewPassword(),
×
327
        AuthUtils.strToPermissions(authorStatement.getPrivilegeList()),
×
328
        AuthUtils.serializePartialPathList(authorStatement.getNodeNameList()));
×
329
  }
330
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc