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

19 20
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
21 22
import org.apache.dolphinscheduler.api.dto.resources.ResourceComponent;
import org.apache.dolphinscheduler.api.dto.resources.visitor.ResourceTreeVisitor;
Q
qiaozhanwei 已提交
23
import org.apache.dolphinscheduler.api.enums.Status;
24
import org.apache.dolphinscheduler.api.exceptions.ServiceException;
Q
qiaozhanwei 已提交
25 26 27
import org.apache.dolphinscheduler.api.utils.CheckUtils;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
28
import org.apache.dolphinscheduler.common.Constants;
S
sky 已提交
29
import org.apache.dolphinscheduler.common.enums.Flag;
Q
qiaozhanwei 已提交
30 31
import org.apache.dolphinscheduler.common.enums.ResourceType;
import org.apache.dolphinscheduler.common.enums.UserType;
32
import org.apache.dolphinscheduler.common.utils.*;
Q
qiaozhanwei 已提交
33 34
import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.dao.mapper.*;
35
import org.apache.dolphinscheduler.dao.utils.ResourceProcessDefinitionUtils;
L
ligang 已提交
36 37 38 39 40 41
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

42
import java.io.IOException;
S
sky 已提交
43
import java.text.MessageFormat;
L
ligang 已提交
44
import java.util.*;
45
import java.util.stream.Collectors;
L
ligang 已提交
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

/**
 * user service
 */
@Service
public class UsersService extends BaseService {

    private static final Logger logger = LoggerFactory.getLogger(UsersService.class);

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private ProjectUserMapper projectUserMapper;

    @Autowired
B
bao liang 已提交
65
    private ResourceUserMapper resourcesUserMapper;
L
ligang 已提交
66 67 68 69 70

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
B
bao liang 已提交
71
    private DataSourceUserMapper datasourceUserMapper;
L
ligang 已提交
72 73 74 75 76 77 78

    @Autowired
    private UDFUserMapper udfUserMapper;

    @Autowired
    private AlertGroupMapper alertGroupMapper;

79 80 81
    @Autowired
    private ProcessDefinitionMapper processDefinitionMapper;

L
ligang 已提交
82 83 84 85

    /**
     * create user, only system admin have permission
     *
B
bao liang 已提交
86 87 88 89 90 91 92 93 94
     * @param loginUser login user
     * @param userName user name
     * @param userPassword user password
     * @param email email
     * @param tenantId tenant id
     * @param phone phone
     * @param queue queue
     * @return create result code
     * @throws Exception exception
L
ligang 已提交
95
     */
96
    @Transactional(rollbackFor = Exception.class)
L
ligang 已提交
97 98 99 100 101
    public Map<String, Object> createUser(User loginUser,
                                          String userName,
                                          String userPassword,
                                          String email,
                                          int tenantId,
102
                                          String phone,
R
Rubik-W 已提交
103 104
                                          String queue,
                                          int state) throws Exception {
L
ligang 已提交
105

_和's avatar
_和 已提交
106
        Map<String, Object> result = new HashMap<>();
B
bao liang 已提交
107 108 109 110 111 112

        //check all user params
        String msg = this.checkUserParams(userName, userPassword, email, phone);

        if (!StringUtils.isEmpty(msg)) {
            putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,msg);
L
ligang 已提交
113 114
            return result;
        }
115 116
        if (!isAdmin(loginUser)) {
            putMsg(result, Status.USER_NO_OPERATION_PERM);
L
ligang 已提交
117 118 119
            return result;
        }

B
bao liang 已提交
120
        if (!checkTenantExists(tenantId)) {
121
            putMsg(result, Status.TENANT_NOT_EXIST);
L
ligang 已提交
122 123 124
            return result;
        }

R
Rubik-W 已提交
125
        User user = createUser(userName, userPassword, email, tenantId, phone, queue, state);
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

        Tenant tenant = tenantMapper.queryById(tenantId);
        // resource upload startup
        if (PropertyUtils.getResUploadStartupState()){
            // if tenant not exists
            if (!HadoopUtils.getInstance().exists(HadoopUtils.getHdfsTenantDir(tenant.getTenantCode()))){
                createTenantDirIfNotExists(tenant.getTenantCode());
            }
            String userPath = HadoopUtils.getHdfsUserDir(tenant.getTenantCode(),user.getId());
            HadoopUtils.getInstance().mkdir(userPath);
        }

        putMsg(result, Status.SUCCESS);
        return result;

    }

143
    @Transactional(rollbackFor = RuntimeException.class)
144 145 146 147 148
    public User createUser(String userName,
                                          String userPassword,
                                          String email,
                                          int tenantId,
                                          String phone,
R
Rubik-W 已提交
149
                                          String queue,
150
                                          int state) {
L
ligang 已提交
151 152 153 154 155 156 157 158
        User user = new User();
        Date now = new Date();

        user.setUserName(userName);
        user.setUserPassword(EncryptionUtils.getMd5(userPassword));
        user.setEmail(email);
        user.setTenantId(tenantId);
        user.setPhone(phone);
R
Rubik-W 已提交
159
        user.setState(state);
L
ligang 已提交
160 161 162 163
        // create general users, administrator users are currently built-in
        user.setUserType(UserType.GENERAL_USER);
        user.setCreateTime(now);
        user.setUpdateTime(now);
Q
qiaozhanwei 已提交
164 165 166
        if (StringUtils.isEmpty(queue)){
            queue = "";
        }
167
        user.setQueue(queue);
L
ligang 已提交
168 169 170

        // save user
        userMapper.insert(user);
171 172
        return user;
    }
L
ligang 已提交
173

174 175 176 177 178 179 180 181
    /**
     * query user by id
     * @param id id
     * @return user info
     */
    public User queryUser(int id) {
        return userMapper.selectById(id);
    }
L
ligang 已提交
182

183 184 185 186 187 188 189
    /**
     * query user
     * @param name name
     * @return user info
     */
    public User queryUser(String name) {
        return userMapper.queryByUserNameAccurately(name);
L
ligang 已提交
190 191 192 193 194
    }

    /**
     * query user
     *
B
bao liang 已提交
195 196 197
     * @param name name
     * @param password password
     * @return user info
L
ligang 已提交
198 199 200
     */
    public User queryUser(String name, String password) {
        String md5 = EncryptionUtils.getMd5(password);
B
bao liang 已提交
201
        return userMapper.queryUserByNamePassword(name, md5);
L
ligang 已提交
202 203
    }

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    /**
     * get user id by user name
     * @param name user name
     * @return if name empty 0, user not exists -1, user exist user id
     */
    public int getUserIdByName(String name) {
        //executor name query
        int executorId = 0;
        if (StringUtils.isNotEmpty(name)) {
            User executor = queryUser(name);
            if (null != executor) {
                executorId = executor.getId();
            } else {
                executorId = -1;
            }
        }

        return executorId;
    }

L
ligang 已提交
224 225 226
    /**
     * query user list
     *
B
bao liang 已提交
227 228 229 230 231
     * @param loginUser login user
     * @param pageNo page number
     * @param searchVal search avlue
     * @param pageSize page size
     * @return user list page
L
ligang 已提交
232 233
     */
    public Map<String, Object> queryUserList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
_和's avatar
_和 已提交
234
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
235

L
lgcareer 已提交
236
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
237 238 239
            return result;
        }

B
bao liang 已提交
240
        Page<User> page = new Page(pageNo, pageSize);
L
ligang 已提交
241

B
bao liang 已提交
242
        IPage<User> scheduleList = userMapper.queryUserPaging(page, searchVal);
L
ligang 已提交
243

B
bao liang 已提交
244 245 246
        PageInfo<User> pageInfo = new PageInfo<>(pageNo, pageSize);
        pageInfo.setTotalCount((int)scheduleList.getTotal());
        pageInfo.setLists(scheduleList.getRecords());
L
ligang 已提交
247 248 249 250 251 252 253 254 255
        result.put(Constants.DATA_LIST, pageInfo);
        putMsg(result, Status.SUCCESS);

        return result;
    }

    /**
     * updateProcessInstance user
     *
B
bao liang 已提交
256 257 258 259 260 261 262 263 264
     * @param userId user id
     * @param userName user name
     * @param userPassword user password
     * @param email email
     * @param tenantId tennat id
     * @param phone phone
     * @param queue  queue
     * @return update result code
     * @throws Exception exception
L
ligang 已提交
265
     */
266 267 268 269 270 271
    public Map<String, Object> updateUser(int userId,
                                          String userName,
                                          String userPassword,
                                          String email,
                                          int tenantId,
                                          String phone,
R
Rubik-W 已提交
272 273
                                          String queue,
                                          int state) throws Exception {
_和's avatar
_和 已提交
274
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
275 276
        result.put(Constants.STATUS, false);

B
bao liang 已提交
277
        User user = userMapper.selectById(userId);
L
ligang 已提交
278 279 280 281 282 283 284

        if (user == null) {
            putMsg(result, Status.USER_NOT_EXIST, userId);
            return result;
        }

        if (StringUtils.isNotEmpty(userName)) {
S
samz406 已提交
285 286 287 288 289 290

            if (!CheckUtils.checkUserName(userName)){
                putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,userName);
                return result;
            }

B
bao liang 已提交
291
            User tempUser = userMapper.queryByUserNameAccurately(userName);
292
            if (tempUser != null && tempUser.getId() != userId) {
293
                putMsg(result, Status.USER_NAME_EXIST);
294 295
                return result;
            }
L
ligang 已提交
296 297 298 299
            user.setUserName(userName);
        }

        if (StringUtils.isNotEmpty(userPassword)) {
S
samz406 已提交
300 301 302 303
            if (!CheckUtils.checkPassword(userPassword)){
                putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,userPassword);
                return result;
            }
L
ligang 已提交
304 305 306 307
            user.setUserPassword(EncryptionUtils.getMd5(userPassword));
        }

        if (StringUtils.isNotEmpty(email)) {
S
samz406 已提交
308 309 310 311
            if (!CheckUtils.checkEmail(email)){
                putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,email);
                return result;
            }
L
ligang 已提交
312 313
            user.setEmail(email);
        }
S
samz406 已提交
314

315 316 317
        if (StringUtils.isNotEmpty(phone) && !CheckUtils.checkPhone(phone)) {
            putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,phone);
            return result;
S
samz406 已提交
318
        }
319
        user.setPhone(phone);
320
        user.setQueue(queue);
R
Rubik-W 已提交
321
        user.setState(state);
S
samz406 已提交
322
        Date now = new Date();
L
ligang 已提交
323 324 325 326 327 328 329 330 331
        user.setUpdateTime(now);

        //if user switches the tenant, the user's resources need to be copied to the new tenant
        if (user.getTenantId() != tenantId) {
            Tenant oldTenant = tenantMapper.queryById(user.getTenantId());
            //query tenant
            Tenant newTenant = tenantMapper.queryById(tenantId);
            if (newTenant != null) {
                // if hdfs startup
journey2018's avatar
journey2018 已提交
332
                if (PropertyUtils.getResUploadStartupState() && oldTenant != null){
L
ligang 已提交
333
                    String newTenantCode = newTenant.getTenantCode();
334
                    String oldResourcePath = HadoopUtils.getHdfsResDir(oldTenant.getTenantCode());
L
ligang 已提交
335 336
                    String oldUdfsPath = HadoopUtils.getHdfsUdfDir(oldTenant.getTenantCode());

337
                    // if old tenant dir exists
journey2018's avatar
journey2018 已提交
338
                    if (HadoopUtils.getInstance().exists(oldResourcePath)){
339
                        String newResourcePath = HadoopUtils.getHdfsResDir(newTenantCode);
journey2018's avatar
journey2018 已提交
340 341 342
                        String newUdfsPath = HadoopUtils.getHdfsUdfDir(newTenantCode);

                        //file resources list
B
bao liang 已提交
343 344
                        List<Resource> fileResourcesList = resourceMapper.queryResourceList(
                                null, userId, ResourceType.FILE.ordinal());
journey2018's avatar
journey2018 已提交
345
                        if (CollectionUtils.isNotEmpty(fileResourcesList)) {
346 347
                            ResourceTreeVisitor resourceTreeVisitor = new ResourceTreeVisitor(fileResourcesList);
                            ResourceComponent resourceComponent = resourceTreeVisitor.visit();
348
                            copyResourceFiles(resourceComponent, oldResourcePath, newResourcePath);
L
ligang 已提交
349 350
                        }

journey2018's avatar
journey2018 已提交
351
                        //udf resources
B
bao liang 已提交
352 353
                        List<Resource> udfResourceList = resourceMapper.queryResourceList(
                                null, userId, ResourceType.UDF.ordinal());
journey2018's avatar
journey2018 已提交
354
                        if (CollectionUtils.isNotEmpty(udfResourceList)) {
355 356
                            ResourceTreeVisitor resourceTreeVisitor = new ResourceTreeVisitor(udfResourceList);
                            ResourceComponent resourceComponent = resourceTreeVisitor.visit();
357
                            copyResourceFiles(resourceComponent, oldUdfsPath, newUdfsPath);
L
ligang 已提交
358 359
                        }

journey2018's avatar
journey2018 已提交
360
                        //Delete the user from the old tenant directory
361
                        String oldUserPath = HadoopUtils.getHdfsUserDir(oldTenant.getTenantCode(),userId);
journey2018's avatar
journey2018 已提交
362
                        HadoopUtils.getInstance().delete(oldUserPath, true);
363 364 365 366 367 368 369 370 371 372 373 374
                    }else {
                        // if old tenant dir not exists , create
                        createTenantDirIfNotExists(oldTenant.getTenantCode());
                    }

                    if (HadoopUtils.getInstance().exists(HadoopUtils.getHdfsTenantDir(newTenant.getTenantCode()))){
                        //create user in the new tenant directory
                        String newUserPath = HadoopUtils.getHdfsUserDir(newTenant.getTenantCode(),user.getId());
                        HadoopUtils.getInstance().mkdir(newUserPath);
                    }else {
                        // if new tenant dir not exists , create
                        createTenantDirIfNotExists(newTenant.getTenantCode());
journey2018's avatar
journey2018 已提交
375
                    }
L
ligang 已提交
376 377 378 379 380 381 382

                }
            }
            user.setTenantId(tenantId);
        }

        // updateProcessInstance user
B
bao liang 已提交
383
        userMapper.updateById(user);
L
ligang 已提交
384 385 386 387 388 389 390
        putMsg(result, Status.SUCCESS);
        return result;
    }

    /**
     * delete user
     *
B
bao liang 已提交
391 392 393 394
     * @param loginUser login user
     * @param id user id
     * @return delete result code
     * @throws Exception exception when operate hdfs
L
ligang 已提交
395 396
     */
    public Map<String, Object> deleteUserById(User loginUser, int id) throws Exception {
_和's avatar
_和 已提交
397
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
398 399
        //only admin can operate
        if (!isAdmin(loginUser)) {
S
samz406 已提交
400 401 402 403 404 405
            putMsg(result, Status.USER_NO_OPERATION_PERM, id);
            return result;
        }
        //check exist
        User tempUser = userMapper.selectById(id);
        if (tempUser == null) {
L
ligang 已提交
406 407 408 409 410 411
            putMsg(result, Status.USER_NOT_EXIST, id);
            return result;
        }
        // delete user
        User user = userMapper.queryTenantCodeByUserId(id);

412 413
        if (user != null) {
            if (PropertyUtils.getResUploadStartupState()) {
journey2018's avatar
journey2018 已提交
414
                String userPath = HadoopUtils.getHdfsUserDir(user.getTenantCode(),id);
415 416 417 418
                if (HadoopUtils.getInstance().exists(userPath)) {
                    HadoopUtils.getInstance().delete(userPath, true);
                }
            }
L
ligang 已提交
419 420
        }

B
bao liang 已提交
421
        userMapper.deleteById(id);
L
ligang 已提交
422 423 424 425 426 427 428 429
        putMsg(result, Status.SUCCESS);

        return result;
    }

    /**
     * grant project
     *
B
bao liang 已提交
430 431 432 433
     * @param loginUser login user
     * @param userId user id
     * @param projectIds project id array
     * @return grant result code
L
ligang 已提交
434
     */
435
    @Transactional(rollbackFor = RuntimeException.class)
L
ligang 已提交
436
    public Map<String, Object> grantProject(User loginUser, int userId, String projectIds) {
_和's avatar
_和 已提交
437
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
438 439 440
        result.put(Constants.STATUS, false);

        //only admin can operate
L
lgcareer 已提交
441
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
442 443 444
            return result;
        }

S
samz406 已提交
445 446 447 448 449 450
        //check exist
        User tempUser = userMapper.selectById(userId);
        if (tempUser == null) {
            putMsg(result, Status.USER_NOT_EXIST, userId);
            return result;
        }
L
ligang 已提交
451
        //if the selected projectIds are empty, delete all items associated with the user
B
bao liang 已提交
452
        projectUserMapper.deleteProjectRelation(0, userId);
L
ligang 已提交
453

L
lgcareer 已提交
454
        if (check(result, StringUtils.isEmpty(projectIds), Status.SUCCESS)) {
L
ligang 已提交
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
            return result;
        }

        String[] projectIdArr = projectIds.split(",");

        for (String projectId : projectIdArr) {
            Date now = new Date();
            ProjectUser projectUser = new ProjectUser();
            projectUser.setUserId(userId);
            projectUser.setProjectId(Integer.parseInt(projectId));
            projectUser.setPerm(7);
            projectUser.setCreateTime(now);
            projectUser.setUpdateTime(now);
            projectUserMapper.insert(projectUser);
        }

        putMsg(result, Status.SUCCESS);

        return result;
    }


    /**
     * grant resource
     *
B
bao liang 已提交
480 481 482 483
     * @param loginUser login user
     * @param userId user id
     * @param resourceIds resource id array
     * @return grant result code
L
ligang 已提交
484
     */
485
    @Transactional(rollbackFor = RuntimeException.class)
L
ligang 已提交
486
    public Map<String, Object> grantResources(User loginUser, int userId, String resourceIds) {
_和's avatar
_和 已提交
487
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
488
        //only admin can operate
L
lgcareer 已提交
489
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
490 491
            return result;
        }
B
bao liang 已提交
492 493 494 495 496
        User user = userMapper.selectById(userId);
        if(user == null){
            putMsg(result, Status.USER_NOT_EXIST, userId);
            return result;
        }
L
ligang 已提交
497

498
        Set<Integer> needAuthorizeResIds = new HashSet();
499 500 501 502 503 504 505 506 507
        if (StringUtils.isNotBlank(resourceIds)) {
            String[] resourceFullIdArr = resourceIds.split(",");
            // need authorize resource id set
            for (String resourceFullId : resourceFullIdArr) {
                String[] resourceIdArr = resourceFullId.split("-");
                for (int i=0;i<=resourceIdArr.length-1;i++) {
                    int resourceIdValue = Integer.parseInt(resourceIdArr[i]);
                    needAuthorizeResIds.add(resourceIdValue);
                }
508 509 510
            }
        }

511

512 513 514 515 516 517 518 519 520 521 522
        //get the authorized resource id list by user id
        List<Resource> oldAuthorizedRes = resourceMapper.queryAuthorizedResourceList(userId);
        //if resource type is UDF,need check whether it is bound by UDF functon
        Set<Integer> oldAuthorizedResIds = oldAuthorizedRes.stream().map(t -> t.getId()).collect(Collectors.toSet());

        //get the unauthorized resource id list
        oldAuthorizedResIds.removeAll(needAuthorizeResIds);

        if (CollectionUtils.isNotEmpty(oldAuthorizedResIds)) {

            // get all resource id of process definitions those is released
523
            List<Map<String, Object>> list = processDefinitionMapper.listResourcesByUser(userId);
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
            Map<Integer, Set<Integer>> resourceProcessMap = ResourceProcessDefinitionUtils.getResourceProcessDefinitionMap(list);
            Set<Integer> resourceIdSet = resourceProcessMap.keySet();

            resourceIdSet.retainAll(oldAuthorizedResIds);
            if (CollectionUtils.isNotEmpty(resourceIdSet)) {
                logger.error("can't be deleted,because it is used of process definition");
                for (Integer resId : resourceIdSet) {
                    logger.error("resource id:{} is used of process definition {}",resId,resourceProcessMap.get(resId));
                }
                putMsg(result, Status.RESOURCE_IS_USED);
                return result;
            }

        }

B
bao liang 已提交
539
        resourcesUserMapper.deleteResourceUser(userId, 0);
L
ligang 已提交
540

L
lgcareer 已提交
541
        if (check(result, StringUtils.isEmpty(resourceIds), Status.SUCCESS)) {
L
ligang 已提交
542 543 544
            return result;
        }

545 546 547 548 549 550
        for (int resourceIdValue : needAuthorizeResIds) {
            Resource resource = resourceMapper.selectById(resourceIdValue);
            if (resource == null) {
                putMsg(result, Status.RESOURCE_NOT_EXIST);
                return result;
            }
L
ligang 已提交
551 552 553 554

            Date now = new Date();
            ResourcesUser resourcesUser = new ResourcesUser();
            resourcesUser.setUserId(userId);
555 556 557 558 559 560 561
            resourcesUser.setResourcesId(resourceIdValue);
            if (resource.isDirectory()) {
                resourcesUser.setPerm(Constants.AUTHORIZE_READABLE_PERM);
            }else{
                resourcesUser.setPerm(Constants.AUTHORIZE_WRITABLE_PERM);
            }

L
ligang 已提交
562 563 564
            resourcesUser.setCreateTime(now);
            resourcesUser.setUpdateTime(now);
            resourcesUserMapper.insert(resourcesUser);
565

L
ligang 已提交
566 567 568 569 570 571 572 573 574 575 576
        }

        putMsg(result, Status.SUCCESS);

        return result;
    }


    /**
     * grant udf function
     *
B
bao liang 已提交
577 578 579 580
     * @param loginUser login user
     * @param userId user id
     * @param udfIds udf id array
     * @return grant result code
L
ligang 已提交
581
     */
582
    @Transactional(rollbackFor = RuntimeException.class)
L
ligang 已提交
583
    public Map<String, Object> grantUDFFunction(User loginUser, int userId, String udfIds) {
_和's avatar
_和 已提交
584
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
585 586

        //only admin can operate
L
lgcareer 已提交
587
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
588 589
            return result;
        }
S
samz406 已提交
590 591 592 593 594
        User user = userMapper.selectById(userId);
        if(user == null){
            putMsg(result, Status.USER_NOT_EXIST, userId);
            return result;
        }
L
ligang 已提交
595 596 597

        udfUserMapper.deleteByUserId(userId);

L
lgcareer 已提交
598
        if (check(result, StringUtils.isEmpty(udfIds), Status.SUCCESS)) {
L
ligang 已提交
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
            return result;
        }

        String[] resourcesIdArr = udfIds.split(",");

        for (String udfId : resourcesIdArr) {
            Date now = new Date();
            UDFUser udfUser = new UDFUser();
            udfUser.setUserId(userId);
            udfUser.setUdfId(Integer.parseInt(udfId));
            udfUser.setPerm(7);
            udfUser.setCreateTime(now);
            udfUser.setUpdateTime(now);
            udfUserMapper.insert(udfUser);
        }

        putMsg(result, Status.SUCCESS);

        return result;
    }


    /**
     * grant datasource
     *
B
bao liang 已提交
624 625 626 627
     * @param loginUser login user
     * @param userId user id
     * @param datasourceIds  data source id array
     * @return grant result code
L
ligang 已提交
628
     */
629
    @Transactional(rollbackFor = RuntimeException.class)
L
ligang 已提交
630
    public Map<String, Object> grantDataSource(User loginUser, int userId, String datasourceIds) {
_和's avatar
_和 已提交
631
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
632 633 634
        result.put(Constants.STATUS, false);

        //only admin can operate
L
lgcareer 已提交
635
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
636 637
            return result;
        }
S
samz406 已提交
638 639 640 641 642
        User user = userMapper.selectById(userId);
        if(user == null){
            putMsg(result, Status.USER_NOT_EXIST, userId);
            return result;
        }
L
ligang 已提交
643 644 645

        datasourceUserMapper.deleteByUserId(userId);

L
lgcareer 已提交
646
        if (check(result, StringUtils.isEmpty(datasourceIds), Status.SUCCESS)) {
L
ligang 已提交
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
            return result;
        }

        String[] datasourceIdArr = datasourceIds.split(",");

        for (String datasourceId : datasourceIdArr) {
            Date now = new Date();

            DatasourceUser datasourceUser = new DatasourceUser();
            datasourceUser.setUserId(userId);
            datasourceUser.setDatasourceId(Integer.parseInt(datasourceId));
            datasourceUser.setPerm(7);
            datasourceUser.setCreateTime(now);
            datasourceUser.setUpdateTime(now);
            datasourceUserMapper.insert(datasourceUser);
        }

        putMsg(result, Status.SUCCESS);

        return result;
    }

    /**
     * query user info
     *
B
bao liang 已提交
672 673
     * @param loginUser login user
     * @return user info
L
ligang 已提交
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
     */
    public Map<String, Object> getUserInfo(User loginUser) {

        Map<String, Object> result = new HashMap<>();

        User user = null;
        if (loginUser.getUserType() == UserType.ADMIN_USER) {
            user = loginUser;
        } else {
            user = userMapper.queryDetailsById(loginUser.getId());

            List<AlertGroup> alertGroups = alertGroupMapper.queryByUserId(loginUser.getId());

            StringBuilder sb = new StringBuilder();

            if (alertGroups != null && alertGroups.size() > 0) {
                for (int i = 0; i < alertGroups.size() - 1; i++) {
                    sb.append(alertGroups.get(i).getGroupName() + ",");
                }
                sb.append(alertGroups.get(alertGroups.size() - 1));
                user.setAlertGroup(sb.toString());
            }
        }

        result.put(Constants.DATA_LIST, user);

        putMsg(result, Status.SUCCESS);
        return result;
    }

Q
qiaozhanwei 已提交
704 705 706
    /**
     * query user list
     *
B
bao liang 已提交
707 708
     * @param loginUser login user
     * @return user list
Q
qiaozhanwei 已提交
709 710
     */
    public Map<String, Object> queryAllGeneralUsers(User loginUser) {
_和's avatar
_和 已提交
711
        Map<String, Object> result = new HashMap<>();
Q
qiaozhanwei 已提交
712
        //only admin can operate
L
lgcareer 已提交
713
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
Q
qiaozhanwei 已提交
714 715 716
            return result;
        }

B
bao liang 已提交
717
        List<User> userList = userMapper.queryAllGeneralUser();
Q
qiaozhanwei 已提交
718 719 720 721 722 723 724
        result.put(Constants.DATA_LIST, userList);
        putMsg(result, Status.SUCCESS);

        return result;
    }


L
ligang 已提交
725 726 727
    /**
     * query user list
     *
B
bao liang 已提交
728 729
     * @param loginUser login user
     * @return user list
L
ligang 已提交
730 731
     */
    public Map<String, Object> queryUserList(User loginUser) {
_和's avatar
_和 已提交
732
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
733
        //only admin can operate
L
lgcareer 已提交
734
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
735 736 737
            return result;
        }

B
bao liang 已提交
738
        List<User> userList = userMapper.selectList(null );
L
ligang 已提交
739 740 741 742 743 744 745 746 747
        result.put(Constants.DATA_LIST, userList);
        putMsg(result, Status.SUCCESS);

        return result;
    }

    /**
     * verify user name exists
     *
B
bao liang 已提交
748 749
     * @param userName user name
     * @return true if user name not exists, otherwise return false
L
ligang 已提交
750 751 752
     */
    public Result verifyUserName(String userName) {

Q
qiaozhanwei 已提交
753
        Result result = new Result();
B
bao liang 已提交
754
        User user = userMapper.queryByUserNameAccurately(userName);
L
ligang 已提交
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
        if (user != null) {
            logger.error("user {} has exist, can't create again.", userName);

            putMsg(result, Status.USER_NAME_EXIST);
        } else {
            putMsg(result, Status.SUCCESS);
        }

        return result;
    }


    /**
     * unauthorized user
     *
B
bao liang 已提交
770 771 772
     * @param loginUser login user
     * @param alertgroupId alert group id
     * @return unauthorize result code
L
ligang 已提交
773 774 775
     */
    public Map<String, Object> unauthorizedUser(User loginUser, Integer alertgroupId) {

_和's avatar
_和 已提交
776
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
777
        //only admin can operate
L
lgcareer 已提交
778
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
779 780 781
            return result;
        }

782
        List<User> userList = userMapper.selectList(null );
L
ligang 已提交
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
        List<User> resultUsers = new ArrayList<>();
        Set<User> userSet = null;
        if (userList != null && userList.size() > 0) {
            userSet = new HashSet<>(userList);

            List<User> authedUserList = userMapper.queryUserListByAlertGroupId(alertgroupId);

            Set<User> authedUserSet = null;
            if (authedUserList != null && authedUserList.size() > 0) {
                authedUserSet = new HashSet<>(authedUserList);
                userSet.removeAll(authedUserSet);
            }
            resultUsers = new ArrayList<>(userSet);
        }
        result.put(Constants.DATA_LIST, resultUsers);
        putMsg(result, Status.SUCCESS);

        return result;
    }


    /**
     * authorized user
     *
B
bao liang 已提交
807 808 809
     * @param loginUser login user
     * @param alertgroupId alert group id
     * @return authorized result code
L
ligang 已提交
810 811
     */
    public Map<String, Object> authorizedUser(User loginUser, Integer alertgroupId) {
_和's avatar
_和 已提交
812
        Map<String, Object> result = new HashMap<>();
L
ligang 已提交
813
        //only admin can operate
L
lgcareer 已提交
814
        if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
L
ligang 已提交
815 816 817 818 819 820 821 822 823 824 825 826
            return result;
        }
        List<User> userList = userMapper.queryUserListByAlertGroupId(alertgroupId);
        result.put(Constants.DATA_LIST, userList);
        putMsg(result, Status.SUCCESS);

        return result;
    }

    /**
     * check
     *
B
bao liang 已提交
827 828 829 830
     * @param result result
     * @param bool bool
     * @param userNoOperationPerm status
     * @return check result
L
ligang 已提交
831
     */
L
lgcareer 已提交
832
    private boolean check(Map<String, Object> result, boolean bool, Status userNoOperationPerm) {
L
ligang 已提交
833 834 835
        //only admin can operate
        if (bool) {
            result.put(Constants.STATUS, userNoOperationPerm);
L
lgcareer 已提交
836
            result.put(Constants.MSG, userNoOperationPerm.getMsg());
L
ligang 已提交
837 838 839 840 841 842
            return true;
        }
        return false;
    }

    /**
B
bao liang 已提交
843 844
     * @param tenantId tenant id
     * @return true if tenant exists, otherwise return false
L
ligang 已提交
845
     */
B
bao liang 已提交
846 847
    private boolean checkTenantExists(int tenantId) {
        return tenantMapper.queryById(tenantId) != null ? true : false;
L
ligang 已提交
848
    }
B
bao liang 已提交
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876

    /**
     *
     * @param userName
     * @param password
     * @param email
     * @param phone
     * @return if check failed return the field, otherwise return null
     */
    private String checkUserParams(String userName, String password, String email, String phone) {

        String msg = null;
        if (!CheckUtils.checkUserName(userName)) {

            msg = userName;
        } else if (!CheckUtils.checkPassword(password)) {

            msg = password;
        } else if (!CheckUtils.checkEmail(email)) {

            msg = email;
        } else if (!CheckUtils.checkPhone(phone)) {

            msg = phone;
        }

        return msg;
    }
877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912

    /**
     * copy resource files
     * @param resourceComponent resource component
     * @param srcBasePath       src base path
     * @param dstBasePath       dst base path
     * @throws IOException      io exception
     */
    private void copyResourceFiles(ResourceComponent resourceComponent, String srcBasePath, String dstBasePath) throws IOException {
        List<ResourceComponent> components = resourceComponent.getChildren();

        if (CollectionUtils.isNotEmpty(components)) {
            for (ResourceComponent component:components) {
                // verify whether exist
                if (!HadoopUtils.getInstance().exists(String.format("%s/%s",srcBasePath,component.getFullName()))){
                    logger.error("resource file: {} not exist,copy error",component.getFullName());
                    throw new ServiceException(Status.RESOURCE_NOT_EXIST);
                }

                if (!component.isDirctory()) {
                    // copy it to dst
                    HadoopUtils.getInstance().copy(String.format("%s/%s",srcBasePath,component.getFullName()),String.format("%s/%s",dstBasePath,component.getFullName()),false,true);
                    continue;
                }

                if(CollectionUtils.isEmpty(component.getChildren())) {
                    // if not exist,need create it
                    if (!HadoopUtils.getInstance().exists(String.format("%s/%s",dstBasePath,component.getFullName()))) {
                        HadoopUtils.getInstance().mkdir(String.format("%s/%s",dstBasePath,component.getFullName()));
                    }
                }else{
                    copyResourceFiles(component,srcBasePath,dstBasePath);
                }
            }
        }
    }
S
sky 已提交
913 914 915 916 917 918 919 920 921

    /**
     * register user, default state is 0, default tenant_id is 1, no phone, no queue
     *
     * @param userName       user name
     * @param userPassword   user password
     * @param repeatPassword repeat password
     * @param email          email
     * @return register result code
S
sky 已提交
922
     * @throws Exception exception
S
sky 已提交
923
     */
924 925
    @Transactional(rollbackFor = RuntimeException.class)
    public Map<String, Object> registerUser(String userName, String userPassword, String repeatPassword, String email) {
S
sky 已提交
926
        Map<String, Object> result = new HashMap<>();
S
sky 已提交
927 928 929 930 931 932 933 934 935 936 937 938 939

        //check user params
        String msg = this.checkUserParams(userName, userPassword, email, "");

        if (!StringUtils.isEmpty(msg)) {
            putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,msg);
            return result;
        }

        if (!userPassword.equals(repeatPassword)) {
            putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, "two passwords are not same");
            return result;
        }
S
sky 已提交
940
        User user = createUser(userName, userPassword, email, 1, "", "", Flag.NO.ordinal());
S
sky 已提交
941
        putMsg(result, Status.SUCCESS);
S
sky 已提交
942
        result.put(Constants.DATA_LIST, user);
S
sky 已提交
943 944 945
        return result;
    }

S
sky 已提交
946 947 948 949
    /**
     * activate user, only system admin have permission, change user state code 0 to 1
     *
     * @param loginUser login user
S
sky 已提交
950
     * @param userName  user name
S
sky 已提交
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
     * @return create result code
     */
    public Map<String, Object> activateUser(User loginUser, String userName) {
        Map<String, Object> result = new HashMap<>();
        result.put(Constants.STATUS, false);

        if (!isAdmin(loginUser)) {
            putMsg(result, Status.USER_NO_OPERATION_PERM);
            return result;
        }

        if (!CheckUtils.checkUserName(userName)){
            putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, userName);
            return result;
        }

        User user = userMapper.queryByUserNameAccurately(userName);

        if (user == null) {
            putMsg(result, Status.USER_NOT_EXIST, userName);
            return result;
        }

        if (user.getState() != Flag.NO.ordinal()) {
            putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, userName);
            return result;
        }

        user.setState(Flag.YES.ordinal());
        Date now = new Date();
        user.setUpdateTime(now);
        userMapper.updateById(user);
        User responseUser = userMapper.queryByUserNameAccurately(userName);
        putMsg(result, Status.SUCCESS);
        result.put(Constants.DATA_LIST, responseUser);
        return result;
    }
S
sky 已提交
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035

    /**
     * activate user, only system admin have permission, change users state code 0 to 1
     *
     * @param loginUser login user
     * @param userNames user name
     * @return create result code
     */
    public Map<String, Object> batchActivateUser(User loginUser, List<String> userNames) {
        Map<String, Object> result = new HashMap<>();

        if (!isAdmin(loginUser)) {
            putMsg(result, Status.USER_NO_OPERATION_PERM);
            return result;
        }

        int totalSuccess = 0;
        List<String> successUserNames = new ArrayList<>();
        Map<String, Object> successRes = new HashMap<>();
        int totalFailed = 0;
        List<Map<String, String>> failedInfo = new ArrayList<>();
        Map<String, Object> failedRes = new HashMap<>();
        for (String userName : userNames) {
            Map<String, Object> tmpResult = activateUser(loginUser, userName);
            if (tmpResult.get(Constants.STATUS) != Status.SUCCESS) {
                totalFailed++;
                Map<String, String> failedBody = new HashMap<>();
                failedBody.put("userName", userName);
                Status status = (Status) tmpResult.get(Constants.STATUS);
                String errorMessage = MessageFormat.format(status.getMsg(), userName);
                failedBody.put("msg", errorMessage);
                failedInfo.add(failedBody);
            } else {
                totalSuccess++;
                successUserNames.add(userName);
            }
        }
        successRes.put("sum", totalSuccess);
        successRes.put("userName", successUserNames);
        failedRes.put("sum", totalFailed);
        failedRes.put("info", failedInfo);
        Map<String, Object> res = new HashMap<>();
        res.put("success", successRes);
        res.put("failed", failedRes);
        putMsg(result, Status.SUCCESS);
        result.put(Constants.DATA_LIST, res);
        return result;
    }
L
ligang 已提交
1036
}