ProjectServiceImpl.java 16.2 KB
Newer Older
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.
 */
17

18 19 20 21 22 23 24
package org.apache.dolphinscheduler.api.service.impl;

import static org.apache.dolphinscheduler.api.utils.CheckUtils.checkDesc;

import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.service.ProjectService;
import org.apache.dolphinscheduler.api.utils.PageInfo;
25
import org.apache.dolphinscheduler.api.utils.Result;
26 27
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.UserType;
28 29
import org.apache.dolphinscheduler.common.utils.SnowFlakeUtils;
import org.apache.dolphinscheduler.common.utils.SnowFlakeUtils.SnowFlakeException;
30 31 32 33 34 35 36
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.ProjectUser;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper;
37
import org.apache.dolphinscheduler.dao.mapper.UserMapper;
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

/**
54
 * project service impl
55 56
 **/
@Service
57
public class ProjectServiceImpl extends BaseServiceImpl implements ProjectService {
58 59 60 61 62 63 64 65 66 67

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private ProjectUserMapper projectUserMapper;

    @Autowired
    private ProcessDefinitionMapper processDefinitionMapper;

68 69 70
    @Autowired
    private UserMapper userMapper;

71 72 73 74 75 76 77 78
    /**
     * create project
     *
     * @param loginUser login user
     * @param name project name
     * @param desc description
     * @return returns an error if it exists
     */
79
    @Override
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
    public Map<String, Object> createProject(User loginUser, String name, String desc) {

        Map<String, Object> result = new HashMap<>();
        Map<String, Object> descCheck = checkDesc(desc);
        if (descCheck.get(Constants.STATUS) != Status.SUCCESS) {
            return descCheck;
        }

        Project project = projectMapper.queryByName(name);
        if (project != null) {
            putMsg(result, Status.PROJECT_ALREADY_EXISTS, name);
            return result;
        }

        Date now = new Date();

96
        try {
97 98 99 100 101 102 103 104 105 106
            project = Project
                    .newBuilder()
                    .name(name)
                    .code(SnowFlakeUtils.getInstance().nextId())
                    .description(desc)
                    .userId(loginUser.getId())
                    .userName(loginUser.getUserName())
                    .createTime(now)
                    .updateTime(now)
                    .build();
107
        } catch (SnowFlakeException e) {
108
            putMsg(result, Status.CREATE_PROJECT_ERROR);
109 110
            return result;
        }
111 112

        if (projectMapper.insert(project) > 0) {
113
            result.put(Constants.DATA_LIST, project.getId());
114 115 116 117 118 119 120 121
            putMsg(result, Status.SUCCESS);
        } else {
            putMsg(result, Status.CREATE_PROJECT_ERROR);
        }
        return result;
    }

    /**
122
     * query project details by code
123
     *
124
     * @param projectCode project code
125 126
     * @return project detail information
     */
127
    @Override
128
    public Map<String, Object> queryByCode(User loginUser, long projectCode) {
129
        Map<String, Object> result = new HashMap<>();
130 131 132 133 134
        Project project = projectMapper.queryByCode(projectCode);
        boolean hasProjectAndPerm = hasProjectAndPerm(loginUser, project, result);
        if (!hasProjectAndPerm) {
            return result;
        }
135 136 137 138 139 140 141 142 143 144 145 146
        if (project != null) {
            result.put(Constants.DATA_LIST, project);
            putMsg(result, Status.SUCCESS);
        }
        return result;
    }

    /**
     * check project and authorization
     *
     * @param loginUser login user
     * @param project project
147
     * @param projectCode project code
148 149
     * @return true if the login user have permission to see the project
     */
150
    @Override
151
    public Map<String, Object> checkProjectAndAuth(User loginUser, Project project, long projectCode) {
152 153
        Map<String, Object> result = new HashMap<>();
        if (project == null) {
154
            putMsg(result, Status.PROJECT_NOT_FOUNT, projectCode);
155 156
        } else if (!checkReadPermission(loginUser, project)) {
            // check read permission
157
            putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), projectCode);
158 159 160 161 162 163
        } else {
            putMsg(result, Status.SUCCESS);
        }
        return result;
    }

164
    @Override
165 166 167 168 169
    public boolean hasProjectAndPerm(User loginUser, Project project, Map<String, Object> result) {
        boolean checkResult = false;
        if (project == null) {
            putMsg(result, Status.PROJECT_NOT_FOUNT, "");
        } else if (!checkReadPermission(loginUser, project)) {
170
            putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), project.getCode());
171 172 173 174 175 176
        } else {
            checkResult = true;
        }
        return checkResult;
    }

177 178 179 180 181 182 183 184 185 186 187 188 189
    @Override
    public boolean hasProjectAndPerm(User loginUser, Project project, Result result) {
        boolean checkResult = false;
        if (project == null) {
            putMsg(result, Status.PROJECT_NOT_FOUNT, "");
        } else if (!checkReadPermission(loginUser, project)) {
            putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), project.getName());
        } else {
            checkResult = true;
        }
        return checkResult;
    }

190 191 192 193 194 195 196 197 198
    /**
     * admin can view all projects
     *
     * @param loginUser login user
     * @param searchVal search value
     * @param pageSize page size
     * @param pageNo page number
     * @return project list which the login user have permission to see
     */
199
    @Override
200 201
    public Result queryProjectListPaging(User loginUser, Integer pageSize, Integer pageNo, String searchVal) {
        Result result = new Result();
202 203 204 205 206 207 208 209 210 211 212 213 214
        PageInfo<Project> pageInfo = new PageInfo<>(pageNo, pageSize);

        Page<Project> page = new Page<>(pageNo, pageSize);

        int userId = loginUser.getUserType() == UserType.ADMIN_USER ? 0 : loginUser.getId();
        IPage<Project> projectIPage = projectMapper.queryProjectListPaging(page, userId, searchVal);

        List<Project> projectList = projectIPage.getRecords();
        if (userId != 0) {
            for (Project project : projectList) {
                project.setPerm(Constants.DEFAULT_ADMIN_PERMISSION);
            }
        }
215 216 217
        pageInfo.setTotal((int) projectIPage.getTotal());
        pageInfo.setTotalList(projectList);
        result.setData(pageInfo);
218 219 220 221 222
        putMsg(result, Status.SUCCESS);
        return result;
    }

    /**
223
     * delete project by code
224 225
     *
     * @param loginUser login user
226
     * @param projectCode project code
227 228
     * @return delete result code
     */
229
    @Override
230
    public Map<String, Object> deleteProject(User loginUser, Long projectCode) {
231
        Map<String, Object> result = new HashMap<>();
232
        Project project = projectMapper.queryByCode(projectCode);
233 234 235 236 237 238 239 240 241 242
        Map<String, Object> checkResult = getCheckResult(loginUser, project);
        if (checkResult != null) {
            return checkResult;
        }

        if (!hasPerm(loginUser, project.getUserId())) {
            putMsg(result, Status.USER_NO_OPERATION_PERM);
            return result;
        }

243
        List<ProcessDefinition> processDefinitionList = processDefinitionMapper.queryAllDefinitionList(project.getCode());
244 245 246 247 248

        if (!processDefinitionList.isEmpty()) {
            putMsg(result, Status.DELETE_PROJECT_ERROR_DEFINES_NOT_NULL);
            return result;
        }
249
        int delete = projectMapper.deleteById(project.getId());
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
        if (delete > 0) {
            putMsg(result, Status.SUCCESS);
        } else {
            putMsg(result, Status.DELETE_PROJECT_ERROR);
        }
        return result;
    }

    /**
     * get check result
     *
     * @param loginUser login user
     * @param project project
     * @return check result
     */
    private Map<String, Object> getCheckResult(User loginUser, Project project) {
266
        Map<String, Object> checkResult = checkProjectAndAuth(loginUser, project, project == null ? 0L : project.getCode());
267 268 269 270 271 272 273 274 275 276 277
        Status status = (Status) checkResult.get(Constants.STATUS);
        if (status != Status.SUCCESS) {
            return checkResult;
        }
        return null;
    }

    /**
     * updateProcessInstance project
     *
     * @param loginUser login user
278
     * @param projectCode project code
279 280
     * @param projectName project name
     * @param desc description
281
     * @param userName project owner
282 283
     * @return update result code
     */
284
    @Override
285
    public Map<String, Object> update(User loginUser, Long projectCode, String projectName, String desc, String userName) {
286 287 288 289 290 291 292
        Map<String, Object> result = new HashMap<>();

        Map<String, Object> descCheck = checkDesc(desc);
        if (descCheck.get(Constants.STATUS) != Status.SUCCESS) {
            return descCheck;
        }

293
        Project project = projectMapper.queryByCode(projectCode);
294 295 296 297 298
        boolean hasProjectAndPerm = hasProjectAndPerm(loginUser, project, result);
        if (!hasProjectAndPerm) {
            return result;
        }
        Project tempProject = projectMapper.queryByName(projectName);
299
        if (tempProject != null && tempProject.getCode() != project.getCode()) {
300 301 302
            putMsg(result, Status.PROJECT_ALREADY_EXISTS, projectName);
            return result;
        }
303 304 305 306 307
        User user = userMapper.queryByUserNameAccurately(userName);
        if (user == null) {
            putMsg(result, Status.USER_NOT_EXIST, userName);
            return result;
        }
308 309 310
        project.setName(projectName);
        project.setDescription(desc);
        project.setUpdateTime(new Date());
311
        project.setUserId(user.getId());
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
        int update = projectMapper.updateById(project);
        if (update > 0) {
            putMsg(result, Status.SUCCESS);
        } else {
            putMsg(result, Status.UPDATE_PROJECT_ERROR);
        }
        return result;
    }


    /**
     * query unauthorized project
     *
     * @param loginUser login user
     * @param userId user id
     * @return the projects which user have not permission to see
     */
329
    @Override
330 331
    public Map<String, Object> queryUnauthorizedProject(User loginUser, Integer userId) {
        Map<String, Object> result = new HashMap<>();
332
        if (loginUser.getId() != userId && isNotAdmin(loginUser, result)) {
333 334
            return result;
        }
335
        // query all project list except specified userId
336 337
        List<Project> projectList = projectMapper.queryProjectExceptUserId(userId);
        List<Project> resultList = new ArrayList<>();
338
        Set<Project> projectSet;
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
        if (projectList != null && !projectList.isEmpty()) {
            projectSet = new HashSet<>(projectList);

            List<Project> authedProjectList = projectMapper.queryAuthedProjectListByUserId(userId);

            resultList = getUnauthorizedProjects(projectSet, authedProjectList);
        }
        result.put(Constants.DATA_LIST, resultList);
        putMsg(result, Status.SUCCESS);
        return result;
    }

    /**
     * get unauthorized project
     *
     * @param projectSet project set
     * @param authedProjectList authed project list
     * @return project list that authorization
     */
    private List<Project> getUnauthorizedProjects(Set<Project> projectSet, List<Project> authedProjectList) {
        List<Project> resultList;
360
        Set<Project> authedProjectSet;
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
        if (authedProjectList != null && !authedProjectList.isEmpty()) {
            authedProjectSet = new HashSet<>(authedProjectList);
            projectSet.removeAll(authedProjectSet);

        }
        resultList = new ArrayList<>(projectSet);
        return resultList;
    }

    /**
     * query authorized project
     *
     * @param loginUser login user
     * @param userId user id
     * @return projects which the user have permission to see, Except for items created by this user
     */
377
    @Override
378 379 380
    public Map<String, Object> queryAuthorizedProject(User loginUser, Integer userId) {
        Map<String, Object> result = new HashMap<>();

381
        if (loginUser.getId() != userId && isNotAdmin(loginUser, result)) {
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
            return result;
        }

        List<Project> projects = projectMapper.queryAuthedProjectListByUserId(userId);
        result.put(Constants.DATA_LIST, projects);
        putMsg(result, Status.SUCCESS);

        return result;
    }

    /**
     * query authorized project
     *
     * @param loginUser login user
     * @return projects which the user have permission to see, Except for items created by this user
     */
398
    @Override
399 400 401 402 403 404 405 406 407 408
    public Map<String, Object> queryProjectCreatedByUser(User loginUser) {
        Map<String, Object> result = new HashMap<>();

        List<Project> projects = projectMapper.queryProjectCreatedByUser(loginUser.getId());
        result.put(Constants.DATA_LIST, projects);
        putMsg(result, Status.SUCCESS);

        return result;
    }

409 410 411 412
    /**
     * query authorized and user create project list by user
     *
     * @param loginUser login user
413
     * @return project list
414
     */
415
    @Override
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
    public Map<String, Object> queryProjectCreatedAndAuthorizedByUser(User loginUser) {
        Map<String, Object> result = new HashMap<>();

        List<Project> projects = null;
        if (loginUser.getUserType() == UserType.ADMIN_USER) {
            projects = projectMapper.selectList(null);
        } else {
            projects = projectMapper.queryProjectCreatedAndAuthorizedByUserId(loginUser.getId());
        }

        result.put(Constants.DATA_LIST, projects);
        putMsg(result, Status.SUCCESS);

        return result;
    }

432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
    /**
     * check whether have read permission
     *
     * @param user user
     * @param project project
     * @return true if the user have permission to see the project, otherwise return false
     */
    private boolean checkReadPermission(User user, Project project) {
        int permissionId = queryPermission(user, project);
        return (permissionId & Constants.READ_PERMISSION) != 0;
    }

    /**
     * query permission id
     *
     * @param user user
     * @param project project
     * @return permission
     */
    private int queryPermission(User user, Project project) {
        if (user.getUserType() == UserType.ADMIN_USER) {
            return Constants.READ_PERMISSION;
        }

        if (project.getUserId() == user.getId()) {
            return Constants.ALL_PERMISSIONS;
        }

460
        ProjectUser projectUser = projectUserMapper.queryProjectRelation(project.getId(), user.getId());
461 462 463 464 465 466 467 468 469 470

        if (projectUser == null) {
            return 0;
        }

        return projectUser.getPerm();

    }

    /**
471
     * query all project list
472 473 474
     *
     * @return project list
     */
475
    @Override
476 477
    public Map<String, Object> queryAllProjectList() {
        Map<String, Object> result = new HashMap<>();
478
        List<Project> projects = projectMapper.queryAllProject();
479

480 481 482 483 484 485
        result.put(Constants.DATA_LIST, projects);
        putMsg(result, Status.SUCCESS);
        return result;
    }

}