Skip to content

Commit 627c76b

Browse files
authored
[Improvement-16106] Add admin-user-filter in LDAP (#16826)
* improvement 16106 * fix ut * fix comment * fix spotless
1 parent b885970 commit 627c76b

File tree

23 files changed

+802
-255
lines changed

23 files changed

+802
-255
lines changed

.github/workflows/api-test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ jobs:
115115
class: org.apache.dolphinscheduler.api.test.cases.ExecutorAPITest
116116
- name: WorkflowInstanceAPITest
117117
class: org.apache.dolphinscheduler.api.test.cases.WorkflowInstanceAPITest
118+
- name: LdapLoginAPITest
119+
class: org.apache.dolphinscheduler.api.test.cases.LdapLoginAPITest
118120
env:
119121
RECORDING_PATH: /tmp/recording-${{ matrix.case.name }}
120122
steps:

docs/docs/en/guide/security/authentication-type.md

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,23 @@
1010
security:
1111
authentication:
1212
# Authentication types (supported types: PASSWORD,LDAP,CASDOOR_SSO)
13-
type: PASSWORD
13+
type: LDAP
1414
# IF you set type `LDAP`, below config will be effective
1515
ldap:
1616
# ldap server config
17-
urls: ldap://ldap.forumsys.com:389/
17+
url: ldap://ldap.forumsys.com:389/
1818
base-dn: dc=example,dc=com
19-
username: cn=read-only-admin,dc=example,dc=com
19+
username: cn=admin,dc=example,dc=com
2020
password: password
2121
user:
2222
# admin userId when you use LDAP login
23-
admin: read-only-admin
23+
admin: ldap-admin
24+
# user search filter to find admin user
25+
admin-user-filter: (&(cn={0}))
2426
identity-attribute: uid
2527
email-attribute: mail
2628
# action when ldap user is not exist (supported types: CREATE,DENY)
27-
not-exist-action: CREATE
29+
not-exist-action: DENY
2830
ssl:
2931
enable: false
3032
# jks file absolute path && password
@@ -71,31 +73,6 @@ casdoor:
7173
redirect-url: ""
7274
```
7375
74-
For detailed explanation of specific fields, please see: [Api-server related configuration](../../architecture/configuration.md)
75-
76-
## LDAP Test
77-
78-
We offer you a unit-test class while you can test the integration of DolphinScheduler with LDAP without running the service.
79-
80-
> dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java
81-
82-
You can follow guide below:
83-
- Change`TestPropertySource`configuration to your LDAP information.
84-
- Change userId && userPwd to your information in the `ldapLogin` method.
85-
- Change the expected email to the return value you expect in the `ldapLogin` method.
86-
- Run`ldapLogin`method and determine whether the LDAP login result is expected.
87-
88-
If you want to enable ssl, please change configuration in `TestPropertySource` like below:
89-
90-
```
91-
security.authentication.ldap.ssl.enable=false
92-
// absolute path
93-
security.authentication.ldap.ssl.trust-store=/ldapkeystore.jks
94-
security.authentication.ldap.ssl.trust-store-password=yourpassword
95-
```
96-
97-
Then run`ldapLoginSSL`method and determine whether the LDAP login result is expected.
98-
9976
## Casdoor SSO
10077
10178
[Casdoor](https://casdoor.org/) is a UI-first Identity Access Management (IAM) / Single-Sign-On (SSO) platform based on OAuth 2.0, OIDC, SAML and CAS. You can add SSO capability to Dolphinscheduler through Casdoor by following these steps:

docs/docs/zh/guide/security/authentication-type.md

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,23 @@ security:
1414
# IF you set type `LDAP`, below config will be effective
1515
ldap:
1616
# ldap server config
17-
urls: ldap://ldap.forumsys.com:389/
17+
url: ldap://ldap.forumsys.com:389/
1818
base-dn: dc=example,dc=com
19-
username: cn=read-only-admin,dc=example,dc=com
19+
username: cn=admin,dc=example,dc=com
2020
password: password
2121
user:
22-
# admin userId when you use LDAP login
23-
admin: read-only-admin
24-
identity-attribute: uid
25-
email-attribute: mail
26-
# action when ldap user is not exist (supported types: CREATE,DENY)
27-
not-exist-action: CREATE
22+
# admin userId when you use LDAP login
23+
admin: ldap-admin
24+
# user search filter to find admin user
25+
identity-attribute: uid
26+
email-attribute: mail
27+
# action when ldap user is not exist (supported types: CREATE,DENY)
28+
not-exist-action: DENY
2829
ssl:
29-
enable: false
30-
# jks file absolute path && password
31-
trust-store: "/ldapkeystore.jks"
32-
trust-store-password: "password"
30+
enable: false
31+
# jks file absolute path && password
32+
trust-store: "/ldapkeystore.jks"
33+
trust-store-password: "password"
3334
casdoor:
3435
user:
3536
admin: ""
@@ -71,31 +72,6 @@ casdoor:
7172
redirect-url: ""
7273
```
7374
74-
具体字段解释详见:[Api-server相关配置](../../architecture/configuration.md)
75-
76-
## 开发者LDAP测试
77-
78-
我们提供了一个单元测试类,可以在不启动项目的情况下测试DolphinScheduler与LDAP的集成。
79-
80-
> dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapServiceTest.java
81-
82-
使用步骤如下:
83-
- 修改`TestPropertySource`配置参数为你的LDAP信息;
84-
- 修改`ldapLogin`方法中的userId和userPwd为你的账号密码;
85-
- 修改`ldapLogin`方法中的expected email为正常登陆的返回值;
86-
- 执行`ldapLogin`方法,判断LDAP登陆结果是否为预期;
87-
88-
如果你要启用ssl,请修改`TestPropertySource`配置中ssl相关参数为:
89-
90-
```
91-
security.authentication.ldap.ssl.enable=false
92-
// absolute path
93-
security.authentication.ldap.ssl.trust-store=/ldapkeystore.jks
94-
security.authentication.ldap.ssl.trust-store-password=yourpassword
95-
```
96-
97-
运行`ldapLoginSSL`方法,判断email是否为预期的返回值。
98-
9975
## 通过 Casdoor 实现 SSO 登录
10076
10177
Casdoor 是基于 OAuth 2.0、OIDC、SAML 和 CAS 的面向 UI 的身份访问管理(IAM)/单点登录(SSO)平台。您可以通过以下步骤通过 Casdoor 为 Dolphinscheduler 添加 SSO 功能:

dolphinscheduler-api-test/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,29 @@ class TenantAPITest {
4343
}
4444
```
4545

46+
## Notes
47+
48+
## Local development
49+
50+
### Mac M1
51+
Add VM options to the test configuration in IntelliJ IDEA:
52+
```
53+
# In this mode you need to install docker desktop for mac and run it with locally
54+
-Dm1_chip=true
55+
```
56+
57+
### Running locally(without Docker)
58+
```
59+
# In this mode you need to start frontend and backend services locally
60+
-Dlocal=true
61+
```
62+
63+
### Running locally(with Docker)
64+
```
65+
# In this mode you only need to install docker locally
66+
```
67+
68+
- To run the tests locally, you need to have the DolphinScheduler running locally. You should add `dolphinscheduler-api-test/pom.xml` to the maven project
69+
Since it does not participate in project compilation, it is not in the main project.
70+
- Running run test class `org.apache.dolphinscheduler.api.test.cases.TenantAPITest` in the IDE.
71+

dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@
4747
import org.junit.jupiter.api.BeforeAll;
4848
import org.junit.jupiter.api.Order;
4949
import org.junit.jupiter.api.Test;
50+
import org.junitpioneer.jupiter.DisableIfTestFails;
5051

5152
//TODO: Some test cases rely on WorkflowInstance APIs. Should complete remaining cases after WorkflowInstance related API tests done.
5253
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
5354
@Slf4j
55+
@DisableIfTestFails
5456
public class ExecutorAPITest {
5557

5658
private static final String username = "admin";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.api.test.cases;
19+
20+
import org.apache.dolphinscheduler.api.test.core.DolphinScheduler;
21+
import org.apache.dolphinscheduler.api.test.entity.GetUserInfoResponseData;
22+
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
23+
import org.apache.dolphinscheduler.api.test.entity.LoginResponseData;
24+
import org.apache.dolphinscheduler.api.test.pages.LoginPage;
25+
import org.apache.dolphinscheduler.api.test.pages.security.UserPage;
26+
import org.apache.dolphinscheduler.api.test.utils.JSONUtils;
27+
import org.apache.dolphinscheduler.common.enums.UserType;
28+
29+
import lombok.extern.slf4j.Slf4j;
30+
31+
import org.junit.jupiter.api.Assertions;
32+
import org.junit.jupiter.api.Order;
33+
import org.junit.jupiter.api.Test;
34+
import org.junitpioneer.jupiter.DisableIfTestFails;
35+
36+
@DolphinScheduler(composeFiles = "docker/ldap-login/docker-compose.yaml")
37+
@Slf4j
38+
@DisableIfTestFails
39+
public class LdapLoginAPITest {
40+
41+
private static String sessionId;
42+
43+
@Test
44+
@Order(10)
45+
public void testAdminUserLoginSuccess() {
46+
final String username = "admin_user01";
47+
48+
final String password = "123";
49+
50+
LoginPage loginPage = new LoginPage();
51+
HttpResponse loginHttpResponse = loginPage.login(username, password);
52+
sessionId =
53+
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
54+
UserPage userPage = new UserPage();
55+
HttpResponse getUserInfoHttpResponse = userPage.getUserInfo(sessionId);
56+
GetUserInfoResponseData getUserInfoResponseData =
57+
JSONUtils.convertValue(getUserInfoHttpResponse.getBody().getData(), GetUserInfoResponseData.class);
58+
Assertions.assertEquals(username, getUserInfoResponseData.getUserName());
59+
Assertions.assertEquals(UserType.ADMIN_USER, getUserInfoResponseData.getUserType());
60+
}
61+
62+
@Test
63+
@Order(20)
64+
public void testAdminUserFilterLoginSuccess() {
65+
final String username = "admin_user03";
66+
67+
final String password = "123";
68+
69+
LoginPage loginPage = new LoginPage();
70+
HttpResponse loginHttpResponse = loginPage.login(username, password);
71+
sessionId =
72+
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
73+
UserPage userPage = new UserPage();
74+
HttpResponse getUserInfoHttpResponse = userPage.getUserInfo(sessionId);
75+
GetUserInfoResponseData getUserInfoResponseData =
76+
JSONUtils.convertValue(getUserInfoHttpResponse.getBody().getData(), GetUserInfoResponseData.class);
77+
Assertions.assertEquals(username, getUserInfoResponseData.getUserName());
78+
Assertions.assertEquals(UserType.ADMIN_USER, getUserInfoResponseData.getUserType());
79+
}
80+
81+
@Test
82+
@Order(30)
83+
public void testGeneralUserLoginSuccess() {
84+
final String username = "general_user02";
85+
86+
final String password = "123";
87+
88+
LoginPage loginPage = new LoginPage();
89+
HttpResponse loginHttpResponse = loginPage.login(username, password);
90+
sessionId =
91+
JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
92+
UserPage userPage = new UserPage();
93+
HttpResponse getUserInfoHttpResponse = userPage.getUserInfo(sessionId);
94+
GetUserInfoResponseData getUserInfoResponseData =
95+
JSONUtils.convertValue(getUserInfoHttpResponse.getBody().getData(), GetUserInfoResponseData.class);
96+
Assertions.assertEquals(username, getUserInfoResponseData.getUserName());
97+
Assertions.assertEquals(UserType.GENERAL_USER, getUserInfoResponseData.getUserType());
98+
}
99+
100+
@Test
101+
@Order(40)
102+
public void testGeneralUserLoginFailed() {
103+
final String username = "general_user02";
104+
105+
final String password = "1";
106+
107+
LoginPage loginPage = new LoginPage();
108+
HttpResponse loginHttpResponse = loginPage.login(username, password);
109+
Boolean loginResult = loginHttpResponse.getBody().getSuccess();
110+
Assertions.assertFalse(loginResult);
111+
}
112+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.api.test.entity;
19+
20+
import org.apache.dolphinscheduler.common.enums.UserType;
21+
22+
import java.util.Date;
23+
24+
import lombok.AllArgsConstructor;
25+
import lombok.Data;
26+
import lombok.NoArgsConstructor;
27+
28+
@Data
29+
@NoArgsConstructor
30+
@AllArgsConstructor
31+
public class GetUserInfoResponseData {
32+
33+
private Integer id;
34+
private String userName;
35+
private String userPassword;
36+
private String email;
37+
private Integer phone;
38+
private UserType userType;
39+
private Integer tenantId;
40+
private Integer state;
41+
private String tenantCode;
42+
private String queueName;
43+
private String alertGroup;
44+
private String queue;
45+
private String timeZone;
46+
private Date createTime;
47+
private Date updateTime;
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.api.test.pages.security;
19+
20+
import org.apache.dolphinscheduler.api.test.core.Constants;
21+
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
22+
import org.apache.dolphinscheduler.api.test.utils.RequestClient;
23+
24+
import java.util.HashMap;
25+
import java.util.Map;
26+
27+
public class UserPage {
28+
29+
public HttpResponse getUserInfo(String sessionId) {
30+
Map<String, String> headers = new HashMap<>();
31+
headers.put(Constants.SESSION_ID_KEY, sessionId);
32+
33+
RequestClient requestClient = new RequestClient();
34+
35+
return requestClient.get("/users/get-user-info", headers, new HashMap<>());
36+
}
37+
}

0 commit comments

Comments
 (0)