Browse Source

[Improvement-13824][Resource Center] User can only visit resources under tenant defaultPath (#13848)

* [Improvement-13824][Resource Center] User can only visit resources under tenant defaultPath

* remove semicolon

* set null in some specific scenario

* remove useless console.log
3.2.0-release
Aaron Wang 2 years ago committed by GitHub
parent
commit
4bf097ee40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
  2. 9
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java
  3. 40
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java
  4. 18
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ResourcesServiceTest.java
  5. 3
      dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResourceType.java
  6. 1
      dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperate.java
  7. 2
      dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java
  8. 16
      dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/main/java/org/apache/dolphinscheduler/plugin/storage/hdfs/HdfsStorageOperator.java
  9. 2
      dolphinscheduler-storage-plugin/dolphinscheduler-storage-oss/src/main/java/org/apache/dolphinscheduler/plugin/storage/oss/OssStorageOperator.java
  10. 2
      dolphinscheduler-storage-plugin/dolphinscheduler-storage-s3/src/main/java/org/apache/dolphinscheduler/plugin/storage/s3/S3StorageOperator.java
  11. 2
      dolphinscheduler-ui/src/layouts/content/components/user/use-dropdown.ts
  12. 10
      dolphinscheduler-ui/src/service/modules/resources/index.ts
  13. 2
      dolphinscheduler-ui/src/service/service.ts
  14. 2
      dolphinscheduler-ui/src/store/user/types.ts
  15. 14
      dolphinscheduler-ui/src/store/user/user.ts
  16. 10
      dolphinscheduler-ui/src/views/login/use-login.ts
  17. 2
      dolphinscheduler-ui/src/views/password/use-update.ts
  18. 9
      dolphinscheduler-ui/src/views/resource/components/resource/index.tsx

13
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java

@ -772,4 +772,17 @@ public class ResourcesController extends BaseController {
return resourceService.queryResourceByFullName(loginUser, fullName, tenantCode, type); return resourceService.queryResourceByFullName(loginUser, fullName, tenantCode, type);
} }
@Operation(summary = "queryResourceBaseDir", description = "QUERY_RESOURCE_BASE_DIR")
@Parameters({
@Parameter(name = "type", description = "RESOURCE_TYPE", required = true, schema = @Schema(implementation = ResourceType.class))
})
@GetMapping(value = "/base-dir")
@ResponseStatus(HttpStatus.OK)
@ApiException(RESOURCE_NOT_EXIST)
@AccessLogAnnotation
public Result<Object> queryResourceBaseDir(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "type") ResourceType type) {
return resourceService.queryResourceBaseDir(loginUser, type);
}
} }

9
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ResourcesService.java

@ -271,4 +271,13 @@ public interface ResourcesService {
Result<Object> queryResourceByFullName(User loginUser, String fullName, String tenantCode, Result<Object> queryResourceByFullName(User loginUser, String fullName, String tenantCode,
ResourceType type) throws IOException; ResourceType type) throws IOException;
/**
* get resource base dir
*
* @param loginUser login user
* @param type resource type
* @return
*/
Result<Object> queryResourceBaseDir(User loginUser, ResourceType type);
} }

40
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java

@ -574,8 +574,10 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe
} }
String tenantCode = getTenantCode(user); String tenantCode = getTenantCode(user);
String baseDir = isAdmin(loginUser) ? storageOperate.getDir(ResourceType.ALL, tenantCode)
if (!isUserTenantValid(isAdmin(loginUser), tenantCode, resTenantCode)) { : storageOperate.getDir(type, tenantCode);
if (!isUserTenantValid(isAdmin(loginUser), tenantCode, resTenantCode)
|| (StringUtils.isNotBlank(fullName) && !StringUtils.startsWith(fullName, baseDir))) {
log.error("current user does not have permission"); log.error("current user does not have permission");
putMsg(result, Status.NO_CURRENT_OPERATING_PERMISSION); putMsg(result, Status.NO_CURRENT_OPERATING_PERMISSION);
return result; return result;
@ -1679,6 +1681,40 @@ public class ResourcesServiceImpl extends BaseServiceImpl implements ResourcesSe
return result; return result;
} }
/**
* get resource base dir
*
* @param loginUser login user
* @param type resource type
* @return
*/
@Override
public Result<Object> queryResourceBaseDir(User loginUser, ResourceType type) {
Result<Object> result = new Result<>();
User user = userMapper.selectById(loginUser.getId());
if (user == null) {
log.error("user {} not exists", loginUser.getId());
putMsg(result, Status.USER_NOT_EXIST, loginUser.getId());
return result;
}
String tenantCode = getTenantCode(user);
if (!isUserTenantValid(isAdmin(loginUser), tenantCode, "")) {
log.error("current user does not have permission");
putMsg(result, Status.NO_CURRENT_OPERATING_PERMISSION);
return result;
}
String baseDir = isAdmin(loginUser) ? storageOperate.getDir(ResourceType.ALL, tenantCode)
: storageOperate.getDir(type, tenantCode);
putMsg(result, Status.SUCCESS);
result.setData(baseDir);
return result;
}
/** /**
* get authorized resource list * get authorized resource list
* *

18
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ResourcesServiceTest.java

@ -892,6 +892,24 @@ public class ResourcesServiceTest {
logger.error("hadoop error", e); logger.error("hadoop error", e);
} }
} }
@Test
void testQueryBaseDir() {
User user = getUser();
Mockito.when(userMapper.selectById(user.getId())).thenReturn(getUser());
Mockito.when(tenantMapper.queryById(user.getTenantId())).thenReturn(getTenant());
Mockito.when(storageOperate.getDir(ResourceType.FILE, "123")).thenReturn("/dolphinscheduler/123/resources/");
try {
Mockito.when(storageOperate.getFileStatus(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(),
Mockito.any())).thenReturn(getStorageEntityResource());
} catch (Exception e) {
logger.error(e.getMessage() + " Resource path: {}", "/dolphinscheduler/123/resources/ResourcesServiceTest",
e);
}
Result<Object> result = resourcesService.queryResourceBaseDir(user, ResourceType.FILE);
Assertions.assertEquals(Status.SUCCESS.getMsg(), result.getMsg());
}
private List<Resource> getResourceList() { private List<Resource> getResourceList() {
List<Resource> resources = new ArrayList<>(); List<Resource> resources = new ArrayList<>();

3
dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResourceType.java

@ -28,7 +28,8 @@ public enum ResourceType {
* 0 file, 1 udf * 0 file, 1 udf
*/ */
FILE(0, "file"), FILE(0, "file"),
UDF(1, "udf"); UDF(1, "udf"),
ALL(2, "all");
ResourceType(int code, String descp) { ResourceType(int code, String descp) {
this.code = code; this.code = code;

1
dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/StorageOperate.java

@ -48,7 +48,6 @@ public interface StorageOperate {
* @param tenantCode * @param tenantCode
* @return * @return
*/ */
String getUdfDir(String tenantCode); String getUdfDir(String tenantCode);
/** /**

2
dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java

@ -252,6 +252,8 @@ public class GcsStorageOperator implements Closeable, StorageOperate {
return getUdfDir(tenantCode); return getUdfDir(tenantCode);
case FILE: case FILE:
return getResDir(tenantCode); return getResDir(tenantCode);
case ALL:
return getGcsDataBasePath();
default: default:
return EMPTY_STRING; return EMPTY_STRING;
} }

16
dolphinscheduler-storage-plugin/dolphinscheduler-storage-hdfs/src/main/java/org/apache/dolphinscheduler/plugin/storage/hdfs/HdfsStorageOperator.java

@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.plugin.storage.hdfs; package org.apache.dolphinscheduler.plugin.storage.hdfs;
import static org.apache.dolphinscheduler.common.constants.Constants.EMPTY_STRING;
import static org.apache.dolphinscheduler.common.constants.Constants.FOLDER_SEPARATOR; import static org.apache.dolphinscheduler.common.constants.Constants.FOLDER_SEPARATOR;
import static org.apache.dolphinscheduler.common.constants.Constants.FORMAT_S_S; import static org.apache.dolphinscheduler.common.constants.Constants.FORMAT_S_S;
import static org.apache.dolphinscheduler.common.constants.Constants.RESOURCE_TYPE_FILE; import static org.apache.dolphinscheduler.common.constants.Constants.RESOURCE_TYPE_FILE;
@ -615,13 +616,16 @@ public class HdfsStorageOperator implements Closeable, StorageOperate {
* @return hdfs resource dir * @return hdfs resource dir
*/ */
public static String getHdfsDir(ResourceType resourceType, String tenantCode) { public static String getHdfsDir(ResourceType resourceType, String tenantCode) {
String hdfsDir = ""; switch (resourceType) {
if (resourceType.equals(ResourceType.FILE)) { case UDF:
hdfsDir = getHdfsResDir(tenantCode); return getHdfsUdfDir(tenantCode);
} else if (resourceType.equals(ResourceType.UDF)) { case FILE:
hdfsDir = getHdfsUdfDir(tenantCode); return getHdfsResDir(tenantCode);
case ALL:
return getHdfsDataBasePath();
default:
return EMPTY_STRING;
} }
return hdfsDir;
} }
@Override @Override

2
dolphinscheduler-storage-plugin/dolphinscheduler-storage-oss/src/main/java/org/apache/dolphinscheduler/plugin/storage/oss/OssStorageOperator.java

@ -268,6 +268,8 @@ public class OssStorageOperator implements Closeable, StorageOperate {
return getUdfDir(tenantCode); return getUdfDir(tenantCode);
case FILE: case FILE:
return getResDir(tenantCode); return getResDir(tenantCode);
case ALL:
return getOssDataBasePath();
default: default:
return ""; return "";
} }

2
dolphinscheduler-storage-plugin/dolphinscheduler-storage-s3/src/main/java/org/apache/dolphinscheduler/plugin/storage/s3/S3StorageOperator.java

@ -290,6 +290,8 @@ public class S3StorageOperator implements Closeable, StorageOperate {
return getUdfDir(tenantCode); return getUdfDir(tenantCode);
case FILE: case FILE:
return getResDir(tenantCode); return getResDir(tenantCode);
case ALL:
return getS3DataBasePath();
default: default:
return ""; return "";
} }

2
dolphinscheduler-ui/src/layouts/content/components/user/use-dropdown.ts

@ -41,6 +41,8 @@ export function useDropDown() {
userStore.setSessionId('') userStore.setSessionId('')
userStore.setSecurityConfigType('') userStore.setSecurityConfigType('')
userStore.setUserInfo({}) userStore.setUserInfo({})
userStore.setBaseResDir('')
userStore.setBaseUdfDir('')
cookies.remove('sessionId') cookies.remove('sessionId')
router.push({ path: '/login' }) router.push({ path: '/login' })

10
dolphinscheduler-ui/src/service/modules/resources/index.ts

@ -45,6 +45,16 @@ export function queryResourceListPaging(
}) })
} }
export function queryBaseDir(
params: ResourceTypeReq
): any {
return axios({
url: '/resources/base-dir',
method: 'get',
params
})
}
export function queryCurrentResourceByFileName( export function queryCurrentResourceByFileName(
params: ResourceTypeReq & FileNameReq & TenantCodeReq, params: ResourceTypeReq & FileNameReq & TenantCodeReq,
): any { ): any {

2
dolphinscheduler-ui/src/service/service.ts

@ -65,6 +65,8 @@ const err = (err: AxiosError): Promise<AxiosError> => {
userStore.setSessionId('') userStore.setSessionId('')
userStore.setSecurityConfigType('') userStore.setSecurityConfigType('')
userStore.setUserInfo({}) userStore.setUserInfo({})
userStore.setBaseResDir('')
userStore.setBaseUdfDir('')
router.push({ path: '/login' }) router.push({ path: '/login' })
} }

2
dolphinscheduler-ui/src/store/user/types.ts

@ -20,6 +20,8 @@ import type { UserInfoRes } from '@/service/modules/users/types'
interface UserState { interface UserState {
sessionId: string sessionId: string
securityConfigType: string securityConfigType: string
baseResDir: string
baseUdfDir: string
userInfo: UserInfoRes | {} userInfo: UserInfoRes | {}
} }

14
dolphinscheduler-ui/src/store/user/user.ts

@ -24,6 +24,8 @@ export const useUserStore = defineStore({
state: (): UserState => ({ state: (): UserState => ({
sessionId: '', sessionId: '',
securityConfigType: '', securityConfigType: '',
baseResDir: '',
baseUdfDir: '',
userInfo: {} userInfo: {}
}), }),
persist: true, persist: true,
@ -36,6 +38,12 @@ export const useUserStore = defineStore({
}, },
getUserInfo(): UserInfoRes | {} { getUserInfo(): UserInfoRes | {} {
return this.userInfo return this.userInfo
},
getBaseResDir(): string {
return this.baseResDir
},
getBaseUdfDir(): string {
return this.baseUdfDir
} }
}, },
actions: { actions: {
@ -47,6 +55,12 @@ export const useUserStore = defineStore({
}, },
setUserInfo(userInfo: UserInfoRes | {}): void { setUserInfo(userInfo: UserInfoRes | {}): void {
this.userInfo = userInfo this.userInfo = userInfo
},
setBaseResDir(baseResDir: string): void {
this.baseResDir = baseResDir
},
setBaseUdfDir(baseUdfDir: string): void {
this.baseUdfDir = baseUdfDir
} }
} }
}) })

10
dolphinscheduler-ui/src/views/login/use-login.ts

@ -25,6 +25,7 @@ import type { UserInfoRes } from '@/service/modules/users/types'
import { useRouteStore } from '@/store/route/route' import { useRouteStore } from '@/store/route/route'
import { useTimezoneStore } from '@/store/timezone/timezone' import { useTimezoneStore } from '@/store/timezone/timezone'
import cookies from 'js-cookie' import cookies from 'js-cookie'
import {queryBaseDir} from "@/service/modules/resources";
export function useLogin(state: any) { export function useLogin(state: any) {
const router: Router = useRouter() const router: Router = useRouter()
@ -43,6 +44,15 @@ export function useLogin(state: any) {
const userInfoRes: UserInfoRes = await getUserInfo() const userInfoRes: UserInfoRes = await getUserInfo()
await userStore.setUserInfo(userInfoRes) await userStore.setUserInfo(userInfoRes)
const baseResDir = await queryBaseDir({
type: 'FILE'
})
const baseUdfDir = await queryBaseDir({
type: 'UDF'
})
await userStore.setBaseResDir(baseResDir)
await userStore.setBaseUdfDir(baseUdfDir)
const timezone = userInfoRes.timeZone ? userInfoRes.timeZone : 'UTC' const timezone = userInfoRes.timeZone ? userInfoRes.timeZone : 'UTC'
await timezoneStore.setTimezone(timezone) await timezoneStore.setTimezone(timezone)

2
dolphinscheduler-ui/src/views/password/use-update.ts

@ -42,6 +42,8 @@ export function useUpdate(state: any) {
await userStore.setSessionId('') await userStore.setSessionId('')
await userStore.setSecurityConfigType('') await userStore.setSecurityConfigType('')
await userStore.setUserInfo({}) await userStore.setUserInfo({})
await userStore.setBaseResDir('')
await userStore.setBaseUdfDir('')
await router.push({ path: 'login' }) await router.push({ path: 'login' })
} }
}) })

9
dolphinscheduler-ui/src/views/resource/components/resource/index.tsx

@ -45,8 +45,9 @@ import ResourceUploadModal from './upload'
import ResourceRenameModal from './rename' import ResourceRenameModal from './rename'
import styles from './index.module.scss' import styles from './index.module.scss'
import type { Router } from 'vue-router' import type { Router } from 'vue-router'
import Search from "@/components/input-search" import Search from '@/components/input-search'
import { ResourceType } from "@/views/resource/components/resource/types"; import { ResourceType } from '@/views/resource/components/resource/types'
import { useUserStore } from '@/store/user/user'
const props = { const props = {
@ -73,6 +74,7 @@ export default defineComponent({
handleCreateFile, handleCreateFile,
} = useTable() } = useTable()
const userStore = useUserStore()
variables.resourceType = props.resourceType variables.resourceType = props.resourceType
@ -121,7 +123,8 @@ export default defineComponent({
const goBread = (fullName: string) => { const goBread = (fullName: string) => {
const { resourceType, tenantCode } = variables const { resourceType, tenantCode } = variables
if (fullName === '') { const baseDir = resourceType === 'UDF' ? userStore.getBaseUdfDir : userStore.getBaseResDir
if (fullName === '' || !fullName.startsWith(baseDir)) {
router.push({ name: resourceType === 'UDF' ? 'resource-manage' : 'file-manage' }) router.push({ name: resourceType === 'UDF' ? 'resource-manage' : 'file-manage' })
} else { } else {
router.push({ router.push({

Loading…
Cancel
Save