• 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

80.57
/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.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.user;
20

21
import org.apache.iotdb.commons.auth.AuthException;
22
import org.apache.iotdb.commons.auth.entity.User;
23
import org.apache.iotdb.commons.concurrent.HashLock;
24
import org.apache.iotdb.commons.conf.CommonDescriptor;
25
import org.apache.iotdb.commons.path.PartialPath;
26
import org.apache.iotdb.commons.utils.AuthUtils;
27
import org.apache.iotdb.rpc.TSStatusCode;
28

29
import org.slf4j.Logger;
30
import org.slf4j.LoggerFactory;
31

32
import java.io.File;
33
import java.io.IOException;
34
import java.util.HashMap;
35
import java.util.HashSet;
36
import java.util.List;
37
import java.util.Map;
38
import java.util.Map.Entry;
39
import java.util.Set;
40

41
/**
42
 * This class stores information of each user in a separate file within a directory, and cache them
43
 * in memory when a user is accessed.
44
 */
45
public abstract class BasicUserManager implements IUserManager {
46

47
  private static final Logger logger = LoggerFactory.getLogger(BasicUserManager.class);
1✔
48
  private static final String NO_SUCH_USER_ERROR = "No such user %s";
49

50
  protected Map<String, User> userMap;
51
  protected IUserAccessor accessor;
52
  protected HashLock lock;
53

54
  /**
55
   * BasicUserManager Constructor.
56
   *
57
   * @param accessor user accessor
58
   * @throws AuthException Authentication Exception
59
   */
60
  protected BasicUserManager(IUserAccessor accessor) throws AuthException {
1✔
61
    this.userMap = new HashMap<>();
1✔
62
    this.accessor = accessor;
1✔
63
    this.lock = new HashLock();
1✔
64

65
    reset();
1✔
66
  }
1✔
67

68
  /**
69
   * Try to load admin. If it doesn't exist, automatically create one
70
   *
71
   * @throws AuthException if an exception is raised when interacting with the lower storage.
72
   */
73
  private void initAdmin() throws AuthException {
74
    User admin;
75
    try {
76
      admin = getUser(CommonDescriptor.getInstance().getConfig().getAdminName());
1✔
77
    } catch (AuthException e) {
×
78
      logger.warn("Cannot load admin, Creating a new one", e);
×
79
      admin = null;
×
80
    }
1✔
81

82
    if (admin == null) {
1✔
83
      createUser(
1✔
84
          CommonDescriptor.getInstance().getConfig().getAdminName(),
1✔
85
          CommonDescriptor.getInstance().getConfig().getAdminPassword());
1✔
86
      setUserUseWaterMark(CommonDescriptor.getInstance().getConfig().getAdminName(), false);
1✔
87
    }
88
    logger.info("Admin initialized");
1✔
89
  }
1✔
90

91
  @Override
92
  public User getUser(String username) throws AuthException {
93
    lock.readLock(username);
1✔
94
    User user = userMap.get(username);
1✔
95
    try {
96
      if (user == null) {
1✔
97
        user = accessor.loadUser(username);
1✔
98
        if (user != null) {
1✔
99
          userMap.put(username, user);
1✔
100
        }
101
      }
102
    } catch (IOException e) {
×
103
      throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
104
    } finally {
105
      lock.readUnlock(username);
1✔
106
    }
107
    if (user != null) {
1✔
108
      user.setLastActiveTime(System.currentTimeMillis());
1✔
109
    }
110
    return user;
1✔
111
  }
112

113
  @Override
114
  public boolean createUser(String username, String password) throws AuthException {
115
    AuthUtils.validateUsername(username);
1✔
116
    AuthUtils.validatePassword(password);
1✔
117

118
    User user = getUser(username);
1✔
119
    if (user != null) {
1✔
120
      return false;
1✔
121
    }
122
    lock.writeLock(username);
1✔
123
    try {
124
      user = new User(username, AuthUtils.encryptPassword(password));
1✔
125
      File userDirPath = new File(accessor.getDirPath());
1✔
126
      if (!userDirPath.exists()) {
1✔
127
        reset();
×
128
      }
129
      accessor.saveUser(user);
1✔
130
      userMap.put(username, user);
1✔
131
      return true;
1✔
132
    } catch (IOException e) {
×
133
      throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
134
    } finally {
135
      lock.writeUnlock(username);
1✔
136
    }
137
  }
138

139
  @Override
140
  public boolean deleteUser(String username) throws AuthException {
141
    lock.writeLock(username);
1✔
142
    try {
143
      if (accessor.deleteUser(username)) {
1✔
144
        userMap.remove(username);
1✔
145
        return true;
1✔
146
      } else {
147
        return false;
1✔
148
      }
149
    } catch (IOException e) {
×
150
      throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
151
    } finally {
152
      lock.writeUnlock(username);
1✔
153
    }
154
  }
155

156
  @Override
157
  public boolean grantPrivilegeToUser(String username, PartialPath path, int privilegeId)
158
      throws AuthException {
159
    AuthUtils.validatePrivilegeOnPath(path, privilegeId);
1✔
160
    lock.writeLock(username);
1✔
161
    try {
162
      User user = getUser(username);
1✔
163
      if (user == null) {
1✔
164
        throw new AuthException(
1✔
165
            TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR, username));
1✔
166
      }
167
      if (user.hasPrivilege(path, privilegeId)) {
1✔
168
        return false;
1✔
169
      }
170
      Set<Integer> privilegesCopy = new HashSet<>(user.getPrivileges(path));
1✔
171
      user.addPrivilege(path, privilegeId);
1✔
172
      try {
173
        accessor.saveUser(user);
1✔
174
      } catch (IOException e) {
×
175
        user.setPrivileges(path, privilegesCopy);
×
176
        throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
177
      }
1✔
178
      return true;
1✔
179
    } finally {
180
      lock.writeUnlock(username);
1✔
181
    }
182
  }
183

184
  @Override
185
  public boolean revokePrivilegeFromUser(String username, PartialPath path, int privilegeId)
186
      throws AuthException {
187
    AuthUtils.validatePrivilegeOnPath(path, privilegeId);
1✔
188
    lock.writeLock(username);
1✔
189
    try {
190
      User user = getUser(username);
1✔
191
      if (user == null) {
1✔
192
        throw new AuthException(
1✔
193
            TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR, username));
1✔
194
      }
195
      if (!user.hasPrivilege(path, privilegeId)) {
1✔
196
        return false;
1✔
197
      }
198
      user.removePrivilege(path, privilegeId);
1✔
199
      try {
200
        accessor.saveUser(user);
1✔
201
      } catch (IOException e) {
×
202
        user.addPrivilege(path, privilegeId);
×
203
        throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
204
      }
1✔
205
      return true;
1✔
206
    } finally {
207
      lock.writeUnlock(username);
1✔
208
    }
209
  }
210

211
  @Override
212
  public boolean updateUserPassword(String username, String newPassword) throws AuthException {
213
    try {
214
      AuthUtils.validatePassword(newPassword);
1✔
215
    } catch (AuthException e) {
1✔
216
      logger.debug("An illegal password detected ", e);
1✔
217
      return false;
1✔
218
    }
1✔
219

220
    lock.writeLock(username);
1✔
221
    try {
222
      User user = getUser(username);
1✔
223
      if (user == null) {
1✔
224
        throw new AuthException(
1✔
225
            TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR, username));
1✔
226
      }
227
      String oldPassword = user.getPassword();
1✔
228
      user.setPassword(AuthUtils.encryptPassword(newPassword));
1✔
229
      try {
230
        accessor.saveUser(user);
1✔
231
      } catch (IOException e) {
×
232
        user.setPassword(oldPassword);
×
233
        throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
234
      }
1✔
235
      return true;
1✔
236
    } finally {
237
      lock.writeUnlock(username);
1✔
238
    }
239
  }
240

241
  @Override
242
  public boolean grantRoleToUser(String roleName, String username) throws AuthException {
243
    lock.writeLock(username);
1✔
244
    try {
245
      User user = getUser(username);
1✔
246
      if (user == null) {
1✔
247
        throw new AuthException(
1✔
248
            TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR, username));
1✔
249
      }
250
      if (user.hasRole(roleName)) {
1✔
251
        return false;
1✔
252
      }
253
      user.getRoleList().add(roleName);
1✔
254
      try {
255
        accessor.saveUser(user);
1✔
256
      } catch (IOException e) {
×
257
        user.getRoleList().remove(roleName);
×
258
        throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
259
      }
1✔
260
      return true;
1✔
261
    } finally {
262
      lock.writeUnlock(username);
1✔
263
    }
264
  }
265

266
  @Override
267
  public boolean revokeRoleFromUser(String roleName, String username) throws AuthException {
268
    lock.writeLock(username);
1✔
269
    try {
270
      User user = getUser(username);
1✔
271
      if (user == null) {
1✔
272
        throw new AuthException(
1✔
273
            TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR, username));
1✔
274
      }
275
      if (!user.hasRole(roleName)) {
1✔
276
        return false;
1✔
277
      }
278
      user.getRoleList().remove(roleName);
1✔
279
      try {
280
        accessor.saveUser(user);
1✔
281
      } catch (IOException e) {
×
282
        user.getRoleList().add(roleName);
×
283
        throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
284
      }
1✔
285
      return true;
1✔
286
    } finally {
287
      lock.writeUnlock(username);
1✔
288
    }
289
  }
290

291
  @Override
292
  public void reset() throws AuthException {
293
    accessor.reset();
1✔
294
    userMap.clear();
1✔
295
    initAdmin();
1✔
296
  }
1✔
297

298
  @Override
299
  public List<String> listAllUsers() {
300
    List<String> rtlist = accessor.listAllUsers();
1✔
301
    rtlist.sort(null);
1✔
302
    return rtlist;
1✔
303
  }
304

305
  @Override
306
  public boolean isUserUseWaterMark(String username) throws AuthException {
307
    User user = getUser(username);
1✔
308
    if (user == null) {
1✔
309
      throw new AuthException(
×
310
          TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR, username));
×
311
    }
312
    return user.isUseWaterMark();
1✔
313
  }
314

315
  @Override
316
  public void setUserUseWaterMark(String username, boolean useWaterMark) throws AuthException {
317
    User user = getUser(username);
1✔
318
    if (user == null) {
1✔
319
      throw new AuthException(
×
320
          TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR, username));
×
321
    }
322
    boolean oldFlag = user.isUseWaterMark();
1✔
323
    if (oldFlag == useWaterMark) {
1✔
324
      return;
1✔
325
    }
326
    user.setUseWaterMark(useWaterMark);
1✔
327
    try {
328
      accessor.saveUser(user);
1✔
329
    } catch (IOException e) {
×
330
      user.setUseWaterMark(oldFlag);
×
331
      throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
332
    }
1✔
333
  }
1✔
334

335
  @Override
336
  public void replaceAllUsers(Map<String, User> users) throws AuthException {
337
    synchronized (this) {
1✔
338
      reset();
1✔
339
      userMap = users;
1✔
340

341
      for (Entry<String, User> entry : userMap.entrySet()) {
1✔
342
        User user = entry.getValue();
1✔
343
        try {
344
          accessor.saveUser(user);
1✔
345
        } catch (IOException e) {
×
346
          throw new AuthException(TSStatusCode.AUTH_IO_EXCEPTION, e);
×
347
        }
1✔
348
      }
1✔
349
    }
1✔
350
  }
1✔
351
}
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