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

apache / iotdb / #10040

08 Sep 2023 03:44PM UTC coverage: 47.677% (-0.01%) from 47.69%
#10040

push

travis_ci

web-flow
[AUTH].fix IT's grammar. (#11102)

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

80747 of 169363 relevant lines covered (47.68%)

0.48 hits per line

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

63.56
/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.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
package org.apache.iotdb.commons.auth.authorizer;
20

21
import org.apache.iotdb.commons.auth.AuthException;
22
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
23
import org.apache.iotdb.commons.auth.entity.Role;
24
import org.apache.iotdb.commons.auth.entity.User;
25
import org.apache.iotdb.commons.auth.role.IRoleManager;
26
import org.apache.iotdb.commons.auth.user.IUserManager;
27
import org.apache.iotdb.commons.conf.CommonDescriptor;
28
import org.apache.iotdb.commons.exception.StartupException;
29
import org.apache.iotdb.commons.path.PartialPath;
30
import org.apache.iotdb.commons.service.IService;
31
import org.apache.iotdb.commons.service.ServiceType;
32
import org.apache.iotdb.commons.utils.AuthUtils;
33
import org.apache.iotdb.rpc.TSStatusCode;
34

35
import org.apache.thrift.TException;
36
import org.slf4j.Logger;
37
import org.slf4j.LoggerFactory;
38

39
import java.io.File;
40
import java.io.IOException;
41
import java.util.HashMap;
42
import java.util.HashSet;
43
import java.util.List;
44
import java.util.Map;
45
import java.util.Set;
46

47
public abstract class BasicAuthorizer implements IAuthorizer, IService {
48
  // works at config node.
49
  private static final Logger logger = LoggerFactory.getLogger(BasicAuthorizer.class);
1✔
50
  private static final Set<Integer> ADMIN_PRIVILEGES;
51
  private static final String NO_SUCH_ROLE_EXCEPTION = "No such role : %s";
52
  private static final String NO_SUCH_USER_EXCEPTION = "No such user : %s";
53

54
  // TODO: add cache
55
  static {
56
    ADMIN_PRIVILEGES = new HashSet<>();
1✔
57
    for (int i = 0; i < PrivilegeType.values().length; i++) {
1✔
58
      ADMIN_PRIVILEGES.add(i);
1✔
59
    }
60
  }
1✔
61

62
  IUserManager userManager;
63
  IRoleManager roleManager;
64

65
  BasicAuthorizer(IUserManager userManager, IRoleManager roleManager) throws AuthException {
1✔
66
    this.userManager = userManager;
1✔
67
    this.roleManager = roleManager;
1✔
68
    init();
1✔
69
  }
1✔
70

71
  protected void init() throws AuthException {
72
    userManager.reset();
1✔
73
    roleManager.reset();
1✔
74
    logger.info("Initialization of Authorizer completes");
1✔
75
  }
1✔
76

77
  /**
78
   * Function for getting the instance of the local file authorizer.
79
   *
80
   * @exception AuthException Failed to initialize authorizer
81
   */
82
  public static IAuthorizer getInstance() throws AuthException {
83
    if (InstanceHolder.instance == null) {
1✔
84
      throw new AuthException(TSStatusCode.INIT_AUTH_ERROR, "Authorizer uninitialized");
×
85
    }
86
    return InstanceHolder.instance;
1✔
87
  }
88

89
  private static class InstanceHolder {
90
    private static final IAuthorizer instance;
91

92
    static {
93
      Class<BasicAuthorizer> c;
94
      try {
95
        c =
96
            (Class<BasicAuthorizer>)
97
                Class.forName(CommonDescriptor.getInstance().getConfig().getAuthorizerProvider());
1✔
98
        logger.info(
1✔
99
            "Authorizer provider class: {}",
100
            CommonDescriptor.getInstance().getConfig().getAuthorizerProvider());
1✔
101
        instance = c.getDeclaredConstructor().newInstance();
1✔
102
      } catch (Exception e) {
×
103
        // startup failed.
104
        throw new IllegalStateException("Authorizer could not be initialized!", e);
×
105
      }
1✔
106
    }
1✔
107
  }
108

109
  /** Checks if a user has admin privileges */
110
  abstract boolean isAdmin(String username);
111

112
  @Override
113
  public boolean login(String username, String password) throws AuthException {
114
    User user = userManager.getUser(username);
1✔
115
    return user != null
1✔
116
        && password != null
117
        && AuthUtils.validatePassword(password, user.getPassword());
1✔
118
  }
119

120
  @Override
121
  public void createUser(String username, String password) throws AuthException {
122
    if (!userManager.createUser(username, password, false)) {
1✔
123
      throw new AuthException(
1✔
124
          TSStatusCode.USER_ALREADY_EXIST, String.format("User %s already exists", username));
1✔
125
    }
126
  }
1✔
127

128
  public void createOpenIdUser(String username, String password) throws AuthException {
129
    if (!userManager.createUser(username, password, true)) {
1✔
130
      throw new AuthException(
×
131
          TSStatusCode.USER_ALREADY_EXIST, String.format("User %s already exists", username));
×
132
    }
133
  }
1✔
134

135
  @Override
136
  public void deleteUser(String username) throws AuthException {
137
    if (isAdmin(username)) {
1✔
138
      throw new AuthException(
1✔
139
          TSStatusCode.NO_PERMISSION, "Default administrator cannot be deleted");
140
    }
141
    if (!userManager.deleteUser(username)) {
1✔
142
      throw new AuthException(
×
143
          TSStatusCode.USER_NOT_EXIST, String.format("User %s does not exist", username));
×
144
    }
145
  }
1✔
146

147
  @Override
148
  public void grantPrivilegeToUser(
149
      String username, PartialPath path, int privilegeId, boolean grantOpt) throws AuthException {
150
    if (isAdmin(username)) {
1✔
151
      throw new AuthException(
1✔
152
          TSStatusCode.NO_PERMISSION,
153
          "Invalid operation, administrator already has all privileges");
154
    }
155
    userManager.grantPrivilegeToUser(username, path, privilegeId, grantOpt);
1✔
156
  }
1✔
157

158
  @Override
159
  public void revokePrivilegeFromUser(String username, PartialPath path, int privilegeId)
160
      throws AuthException {
161
    if (isAdmin(username)) {
1✔
162
      throw new AuthException(
1✔
163
          TSStatusCode.NO_PERMISSION, "Invalid operation, administrator must have all privileges");
164
    }
165
    if (!userManager.revokePrivilegeFromUser(username, path, privilegeId)) {
1✔
166
      throw new AuthException(
1✔
167
          TSStatusCode.NOT_HAS_PRIVILEGE,
168
          String.format(
1✔
169
              "User %s does not have %s on %s",
170
              username, PrivilegeType.values()[privilegeId], path != null ? path : "system"));
1✔
171
    }
172
  }
1✔
173

174
  @Override
175
  public void createRole(String roleName) throws AuthException {
176
    if (!roleManager.createRole(roleName)) {
1✔
177
      logger.error("Role {} already exists", roleName);
1✔
178
      throw new AuthException(
1✔
179
          TSStatusCode.ROLE_ALREADY_EXIST, String.format("Role %s already exists", roleName));
1✔
180
    }
181
  }
1✔
182

183
  @Override
184
  public void deleteRole(String roleName) throws AuthException {
185
    boolean success = roleManager.deleteRole(roleName);
1✔
186
    if (!success) {
1✔
187
      throw new AuthException(
1✔
188
          TSStatusCode.ROLE_NOT_EXIST, String.format("Role %s does not exist", roleName));
1✔
189
    } else {
190
      // proceed to revoke the role in all users
191
      List<String> users = userManager.listAllUsers();
1✔
192
      for (String user : users) {
1✔
193
        try {
194
          userManager.revokeRoleFromUser(roleName, user);
1✔
195
        } catch (AuthException e) {
×
196
          logger.warn(
×
197
              "Error encountered when revoking a role {} from user {} after deletion",
198
              roleName,
199
              user,
200
              e);
201
        }
1✔
202
      }
1✔
203
    }
204
  }
1✔
205

206
  @Override
207
  public void grantPrivilegeToRole(
208
      String roleName, PartialPath path, int privilegeId, boolean grantOpt) throws AuthException {
209
    if (!roleManager.grantPrivilegeToRole(roleName, path, privilegeId, grantOpt)) {
1✔
210
      throw new AuthException(
×
211
          TSStatusCode.ALREADY_HAS_PRIVILEGE,
212
          String.format(
×
213
              "Role %s already has %s on %s", roleName, PrivilegeType.values()[privilegeId], path));
×
214
    }
215
  }
1✔
216

217
  @Override
218
  public void revokePrivilegeFromRole(String roleName, PartialPath path, int privilegeId)
219
      throws AuthException {
220
    if (!roleManager.revokePrivilegeFromRole(roleName, path, privilegeId)) {
1✔
221
      throw new AuthException(
1✔
222
          TSStatusCode.NOT_HAS_PRIVILEGE,
223
          String.format(
1✔
224
              "Role %s does not have %s on %s",
225
              roleName, PrivilegeType.values()[privilegeId], path));
1✔
226
    }
227
  }
1✔
228

229
  @Override
230
  public void grantRoleToUser(String roleName, String username) throws AuthException {
231
    Role role = roleManager.getRole(roleName);
1✔
232
    if (role == null) {
1✔
233
      throw new AuthException(
1✔
234
          TSStatusCode.ROLE_NOT_EXIST, String.format(NO_SUCH_ROLE_EXCEPTION, roleName));
1✔
235
    }
236
    // the role may be deleted before it ts granted to the user, so a double check is necessary.
237
    boolean success = userManager.grantRoleToUser(roleName, username);
1✔
238
    if (success) {
1✔
239
      role = roleManager.getRole(roleName);
1✔
240
      if (role == null) {
1✔
241
        throw new AuthException(
×
242
            TSStatusCode.ROLE_NOT_EXIST, String.format(NO_SUCH_ROLE_EXCEPTION, roleName));
×
243
      }
244
    } else {
245
      throw new AuthException(
1✔
246
          TSStatusCode.USER_ALREADY_HAS_ROLE,
247
          String.format("User %s already has role %s", username, roleName));
1✔
248
    }
249
  }
1✔
250

251
  @Override
252
  public void revokeRoleFromUser(String roleName, String username) throws AuthException {
253
    Role role = roleManager.getRole(roleName);
1✔
254
    if (role == null) {
1✔
255
      throw new AuthException(
×
256
          TSStatusCode.ROLE_NOT_EXIST, String.format(NO_SUCH_ROLE_EXCEPTION, roleName));
×
257
    }
258
    if (!userManager.revokeRoleFromUser(roleName, username)) {
1✔
259
      throw new AuthException(
×
260
          TSStatusCode.USER_NOT_HAS_ROLE,
261
          String.format("User %s does not have role %s", username, roleName));
×
262
    }
263
  }
1✔
264

265
  @Override
266
  public Set<Integer> getPrivileges(String username, PartialPath path) throws AuthException {
267
    if (isAdmin(username)) {
1✔
268
      return ADMIN_PRIVILEGES;
×
269
    }
270
    User user = userManager.getUser(username);
1✔
271
    if (user == null) {
1✔
272
      throw new AuthException(
×
273
          TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_EXCEPTION, username));
×
274
    }
275
    // get privileges of the user
276
    Set<Integer> privileges = user.getPathPrivileges(path);
1✔
277
    // merge the privileges of the roles of the user
278
    for (String roleName : user.getRoleList()) {
1✔
279
      Role role = roleManager.getRole(roleName);
1✔
280
      if (role != null) {
1✔
281
        privileges.addAll(role.getPathPrivileges(path));
1✔
282
      }
283
    }
1✔
284
    return privileges;
1✔
285
  }
286

287
  @Override
288
  public void updateUserPassword(String username, String newPassword) throws AuthException {
289
    if (!userManager.updateUserPassword(username, newPassword)) {
1✔
290
      throw new AuthException(
×
291
          TSStatusCode.ILLEGAL_PARAMETER, "password " + newPassword + " is illegal");
292
    }
293
  }
1✔
294

295
  @Override
296
  public boolean checkUserPrivileges(String username, PartialPath path, int privilegeId)
297
      throws AuthException {
298
    if (isAdmin(username)) {
1✔
299
      return true;
×
300
    }
301
    User user = userManager.getUser(username);
1✔
302
    if (user == null) {
1✔
303
      throw new AuthException(
×
304
          TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_EXCEPTION, username));
×
305
    }
306
    if (path != null) {
1✔
307
      // get privileges of the user
308
      if (user.checkPathPrivilege(path, privilegeId)) {
1✔
309
        return true;
1✔
310
      }
311
      // merge the privileges of the roles of the user
312
      for (String roleName : user.getRoleList()) {
1✔
313
        Role role = roleManager.getRole(roleName);
×
314
        if (role.checkPathPrivilege(path, privilegeId)) {
×
315
          return true;
×
316
        }
317
      }
1✔
318
    } else {
319
      if (user.checkSysPrivilege(privilegeId)) {
1✔
320
        return true;
1✔
321
      }
322
      for (String roleName : user.getRoleList()) {
×
323
        Role role = roleManager.getRole(roleName);
×
324
        if (role.checkSysPrivilege(privilegeId)) {
×
325
          return true;
×
326
        }
327
      }
×
328
    }
329

330
    return false;
1✔
331
  }
332

333
  public boolean checkUserPrivilegeGrantOpt(String username, PartialPath path, int privilegeId)
334
      throws AuthException {
335
    User user = userManager.getUser(username);
×
336
    if (user == null) {
×
337
      throw new AuthException(
×
338
          TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_EXCEPTION, username));
×
339
    }
340
    if (path == null) {
×
341
      if (user.checkSysPrivilege(privilegeId)) {
×
342
        if (user.getSysPriGrantOpt().contains(privilegeId)) {
×
343
          return true;
×
344
        }
345
      }
346
      if (user.getRoleList().isEmpty()) {
×
347
        throw new AuthException(
×
348
            TSStatusCode.NOT_HAS_PRIVILEGE,
349
            String.format(
×
350
                "Dont have privilege: %s to grant",
351
                PrivilegeType.values()[privilegeId].toString()));
×
352
      }
353
      for (String roleName : user.getRoleList()) {
×
354
        Role role = roleManager.getRole(roleName);
×
355
        if (role.checkSysPrivilege(privilegeId) && role.getSysPriGrantOpt().contains(privilegeId)) {
×
356
          return true;
×
357
        }
358
      }
×
359
      throw new AuthException(
×
360
          TSStatusCode.NOT_HAS_PRIVILEGE,
361
          String.format(
×
362
              "Dont have privilege: %s to grant", PrivilegeType.values()[privilegeId].toString()));
×
363

364
    } else {
365
      if (user.checkPathPrivilegeGrantOpt(path, privilegeId)) {
×
366
        return true;
×
367
      }
368
      if (user.getRoleList().isEmpty()) {
×
369
        throw new AuthException(
×
370
            TSStatusCode.NOT_HAS_PRIVILEGE,
371
            String.format(
×
372
                "Dont have privilege: %s on path %s to grant",
373
                PrivilegeType.values()[privilegeId].toString(), path.toString()));
×
374
      }
375
      for (String roleName : user.getRoleList()) {
×
376
        Role role = roleManager.getRole(roleName);
×
377
        if (role.checkPathPrivilegeGrantOpt(path, privilegeId)) {
×
378
          return true;
×
379
        }
380
      }
×
381
      throw new AuthException(
×
382
          TSStatusCode.NOT_HAS_PRIVILEGE,
383
          String.format(
×
384
              "Dont have privilege: %s on path %s to grant",
385
              PrivilegeType.values()[privilegeId].toString(), path.toString()));
×
386
    }
387
  }
388

389
  @Override
390
  public Map<String, Boolean> getAllUserWaterMarkStatus() {
391
    Map<String, Boolean> userWaterMarkStatus = new HashMap<>();
1✔
392
    List<String> allUsers = listAllUsers();
1✔
393
    for (String user : allUsers) {
1✔
394
      try {
395
        userWaterMarkStatus.put(user, isUserUseWaterMark(user));
1✔
396
      } catch (AuthException e) {
×
397
        logger.error(String.format(NO_SUCH_USER_EXCEPTION, user));
×
398
      }
1✔
399
    }
1✔
400
    return userWaterMarkStatus;
1✔
401
  }
402

403
  @Override
404
  public Map<String, User> getAllUsers() {
405
    Map<String, User> allUsers = new HashMap<>();
1✔
406
    List<String> userNames = listAllUsers();
1✔
407
    for (String userName : userNames) {
1✔
408
      try {
409
        allUsers.put(userName, getUser(userName));
1✔
410
      } catch (AuthException e) {
×
411
        logger.error(String.format("get all users failed, No such user : %s", userName));
×
412
      }
1✔
413
    }
1✔
414
    return allUsers;
1✔
415
  }
416

417
  @Override
418
  public Map<String, Role> getAllRoles() {
419
    Map<String, Role> allRoles = new HashMap<>();
1✔
420
    List<String> roleNames = listAllRoles();
1✔
421
    for (String roleName : roleNames) {
1✔
422
      try {
423
        allRoles.put(roleName, getRole(roleName));
1✔
424
      } catch (AuthException e) {
×
425
        logger.error(String.format("get all roles failed, No such role : %s", roleName));
×
426
      }
1✔
427
    }
1✔
428
    return allRoles;
1✔
429
  }
430

431
  @Override
432
  public void reset() throws AuthException {
433
    init();
1✔
434
  }
1✔
435

436
  @Override
437
  public void start() throws StartupException {
438
    try {
439
      init();
×
440
    } catch (AuthException e) {
×
441
      throw new StartupException(e);
×
442
    }
×
443
  }
×
444

445
  @Override
446
  public void stop() {
447
    // Nothing to do
448
  }
×
449

450
  @Override
451
  public ServiceType getID() {
452
    return ServiceType.AUTHORIZATION_SERVICE;
×
453
  }
454

455
  @Override
456
  public List<String> listAllUsers() {
457
    return userManager.listAllUsers();
1✔
458
  }
459

460
  @Override
461
  public List<String> listAllRoles() {
462
    return roleManager.listAllRoles();
1✔
463
  }
464

465
  @Override
466
  public Role getRole(String roleName) throws AuthException {
467
    return roleManager.getRole(roleName);
1✔
468
  }
469

470
  @Override
471
  public User getUser(String username) throws AuthException {
472
    return userManager.getUser(username);
1✔
473
  }
474

475
  @Override
476
  public boolean isUserUseWaterMark(String userName) throws AuthException {
477
    return userManager.isUserUseWaterMark(userName);
1✔
478
  }
479

480
  @Override
481
  public void setUserUseWaterMark(String userName, boolean useWaterMark) throws AuthException {
482
    userManager.setUserUseWaterMark(userName, useWaterMark);
1✔
483
  }
1✔
484

485
  @Override
486
  public void replaceAllUsers(Map<String, User> users) throws AuthException {
487
    userManager.replaceAllUsers(users);
×
488
  }
×
489

490
  @Override
491
  public void replaceAllRoles(Map<String, Role> roles) throws AuthException {
492
    roleManager.replaceAllRoles(roles);
1✔
493
  }
1✔
494

495
  @Override
496
  public boolean processTakeSnapshot(File snapshotDir) throws TException, IOException {
497
    return userManager.processTakeSnapshot(snapshotDir)
1✔
498
        && roleManager.processTakeSnapshot(snapshotDir);
1✔
499
  }
500

501
  @Override
502
  public void processLoadSnapshot(File snapshotDir) throws TException, IOException {
503
    userManager.processLoadSnapshot(snapshotDir);
1✔
504
    roleManager.processLoadSnapshot(snapshotDir);
1✔
505
  }
1✔
506
}
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

© 2025 Coveralls, Inc