Skip to content

Commit baa3ab8

Browse files
authored
Merge pull request #34 from hejieehe/feat_33
feat: Gitee支持OAuth授权 #33
2 parents c10905c + f7ef8cd commit baa3ab8

File tree

16 files changed

+367
-14
lines changed

16 files changed

+367
-14
lines changed

buildSrc/src/main/kotlin/Versions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object Release {
22
const val Group = "com.tencent.bk.devops.scm"
3-
const val Version = "1.1.1"
3+
const val Version = "1.1.2"
44
}
55

66
object Versions {

devops-scm-api/src/main/kotlin/com/tencent/devops/scm/api/pojo/webhook/git/GitPushHook.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ data class GitPushHook(
8383

8484
override fun repository() = repo
8585

86-
override val userName = sender.name
86+
override val userName = sender.username
8787

8888
override val eventDesc = ScmI18Variable(
8989
code = getI18Code(),
9090
params = listOf(
9191
GitUtils.trimRef(ref),
9292
link,
9393
commit?.sha?.let { GitUtils.getShortSha(it) } ?: "",
94-
sender.name
94+
userName
9595
)
9696
)
9797

@@ -100,13 +100,13 @@ data class GitPushHook(
100100
// 通用变量
101101

102102
outputParams[PIPELINE_REPO_NAME] = repo.fullName
103-
outputParams[PIPELINE_START_WEBHOOK_USER_ID] = sender.name
103+
outputParams[PIPELINE_START_WEBHOOK_USER_ID] = sender.username
104104
outputParams[PIPELINE_WEBHOOK_EVENT_TYPE] = eventType
105105

106106
outputParams[PIPELINE_WEBHOOK_BRANCH] = ref
107107

108108
// 传统变量
109-
outputParams[BK_REPO_GIT_WEBHOOK_PUSH_USERNAME] = sender.name
109+
outputParams[BK_REPO_GIT_WEBHOOK_PUSH_USERNAME] = sender.username
110110
outputParams[BK_REPO_GIT_WEBHOOK_PUSH_BEFORE_COMMIT] = before
111111
outputParams[BK_REPO_GIT_WEBHOOK_PUSH_AFTER_COMMIT] = after
112112
outputParams[BK_REPO_GIT_WEBHOOK_PUSH_TOTAL_COMMIT] = totalCommitsCount

devops-scm-api/src/main/kotlin/com/tencent/devops/scm/api/pojo/webhook/git/PullRequestHook.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,15 @@ data class PullRequestHook(
8787
override fun repository() = repo
8888

8989
override val userName: String
90-
get() = sender.name
90+
get() = sender.username
9191

9292
override val eventDesc: ScmI18Variable
9393
get() = ScmI18Variable(
9494
code = getI18Code(),
9595
params = listOf(
9696
pullRequest.link,
9797
pullRequest.number.toString(),
98-
sender.name
98+
userName
9999
)
100100
)
101101

devops-scm-provider/devops-scm-provider-git/devops-scm-provider-gitee/src/main/kotlin/com/tencent/devops/scm/provider/git/gitee/GiteeObjectConverter.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.tencent.devops.scm.sdk.gitee.pojo.GiteePullRequestDiff
2121
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeRepositoryDetail
2222
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeTag
2323
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeTagDetail
24+
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeUserInfo
2425
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeWebhookConfig
2526
import com.tencent.devops.scm.sdk.gitee.pojo.webhook.GiteeEventAuthor
2627
import com.tencent.devops.scm.sdk.gitee.pojo.webhook.GiteeEventCommit
@@ -214,7 +215,7 @@ object GiteeObjectConverter {
214215
id = id,
215216
name = name,
216217
email = email,
217-
username = ""
218+
username = user.name
218219
)
219220
}
220221

@@ -227,6 +228,15 @@ object GiteeObjectConverter {
227228
)
228229
}
229230

231+
fun convertUser(user: GiteeUserInfo) = with(user) {
232+
User(
233+
id = id,
234+
name = name,
235+
email = email,
236+
username = user.login
237+
)
238+
}
239+
230240
/*========================================compare====================================================*/
231241
fun convertCompare(commitCompare: GiteeCommitCompare) = with(commitCompare) {
232242
files.map {

devops-scm-provider/devops-scm-provider-git/devops-scm-provider-gitee/src/main/kotlin/com/tencent/devops/scm/provider/git/gitee/GiteeRepositoryService.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import com.tencent.devops.scm.api.pojo.auth.IScmAuth
1212
import com.tencent.devops.scm.api.pojo.repository.ScmProviderRepository
1313
import com.tencent.devops.scm.api.pojo.repository.ScmServerRepository
1414
import com.tencent.devops.scm.sdk.gitee.GiteeApiFactory
15+
import com.tencent.devops.scm.sdk.gitee.enums.ProjectAffiliation
16+
import com.tencent.devops.scm.sdk.gitee.enums.ProjectVisibility
1517
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeProjectHook
1618

1719
class GiteeRepositoryService(private val apiFactory: GiteeApiFactory) : RepositoryService {
@@ -29,7 +31,17 @@ class GiteeRepositoryService(private val apiFactory: GiteeApiFactory) : Reposito
2931
}
3032

3133
override fun list(auth: IScmAuth, opts: RepoListOptions): List<ScmServerRepository> {
32-
throw UnsupportedOperationException("gitee not support list repo")
34+
return GiteeApiTemplate.execute(auth, apiFactory) { giteeApi ->
35+
val projectApi = giteeApi.getProjectApi()
36+
val projectApiHooks = projectApi.getProjects(
37+
arrayOf(ProjectAffiliation.OWNER, ProjectAffiliation.COLLABORATOR),
38+
ProjectVisibility.ALL,
39+
opts.repoName,
40+
opts.page,
41+
opts.pageSize
42+
)
43+
projectApiHooks.map { GiteeObjectConverter.convertRepository(it) }
44+
}
3345
}
3446

3547
override fun listHooks(repository: ScmProviderRepository, opts: ListOptions): List<Hook> {

devops-scm-provider/devops-scm-provider-git/devops-scm-provider-gitee/src/main/kotlin/com/tencent/devops/scm/provider/git/gitee/GiteeScmProvider.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,21 @@ import com.tencent.devops.scm.provider.git.command.GitScmProvider
1313
import com.tencent.devops.scm.sdk.common.GitOauth2ClientProperties
1414
import com.tencent.devops.scm.sdk.common.connector.ScmConnector
1515
import com.tencent.devops.scm.sdk.gitee.GiteeApiFactory
16+
import com.tencent.devops.scm.sdk.gitee.GiteeOauth2Api
1617

1718
class GiteeScmProvider : GitScmProvider {
1819
private val apiFactory: GiteeApiFactory
20+
private var oauth2Api: GiteeOauth2Api? = null
1921

2022
constructor(apiUrl: String, connector: ScmConnector) : this(GiteeApiFactory(apiUrl, connector))
2123

2224
constructor(
2325
apiUrl: String,
2426
connector: ScmConnector,
2527
properties: GitOauth2ClientProperties
26-
) : this(apiUrl, connector)
28+
) : this(apiUrl, connector) {
29+
this.oauth2Api = GiteeOauth2Api(properties, connector)
30+
}
2731

2832
constructor(apiFactory: GiteeApiFactory) {
2933
this.apiFactory = apiFactory
@@ -42,7 +46,7 @@ class GiteeScmProvider : GitScmProvider {
4246
}
4347

4448
override fun users() : UserService {
45-
throw UnsupportedOperationException("gitee not support user service")
49+
return GiteeUserService(apiFactory)
4650
}
4751

4852
override fun files(): FileService {
@@ -62,6 +66,6 @@ class GiteeScmProvider : GitScmProvider {
6266
}
6367

6468
override fun token(): TokenService {
65-
throw UnsupportedOperationException("gitee not support token service")
69+
return oauth2Api?.let { GiteeTokenService(it) } ?: throw IllegalStateException("OAuth2 API not initialized")
6670
}
6771
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.tencent.devops.scm.provider.git.gitee
2+
3+
import com.tencent.devops.scm.api.TokenService
4+
import com.tencent.devops.scm.api.pojo.Oauth2AccessToken
5+
import com.tencent.devops.scm.sdk.gitee.GiteeOauth2Api
6+
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeOauth2AccessToken
7+
8+
/**
9+
* Gitee 令牌服务实现类
10+
* @property oauth2Api TGit OAuth2 API
11+
*/
12+
class GiteeTokenService(
13+
private val oauth2Api: GiteeOauth2Api
14+
) : TokenService {
15+
16+
/**
17+
* 获取授权URL
18+
* @param state 状态参数
19+
* @return 授权URL
20+
*/
21+
override fun authorizationUrl(state: String): String {
22+
return oauth2Api.authorizationUrl(state)
23+
}
24+
25+
/**
26+
* 回调处理
27+
* @param code 授权码
28+
* @return 访问令牌
29+
*/
30+
override fun callback(code: String): Oauth2AccessToken {
31+
val accessToken = oauth2Api.callback(code)
32+
return convertAccessToken(accessToken)
33+
}
34+
35+
/**
36+
* 刷新令牌
37+
* @param refreshToken 刷新令牌
38+
* @return 新的访问令牌
39+
*/
40+
override fun refresh(refreshToken: String): Oauth2AccessToken {
41+
val accessToken = oauth2Api.refresh(refreshToken)
42+
return convertAccessToken(accessToken)
43+
}
44+
45+
private fun convertAccessToken(src: GiteeOauth2AccessToken): Oauth2AccessToken {
46+
return with(src) {
47+
Oauth2AccessToken(
48+
accessToken = accessToken,
49+
tokenType = tokenType,
50+
expiresIn = expiresIn,
51+
refreshToken = refreshToken,
52+
scope = scope
53+
)
54+
}
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.tencent.devops.scm.provider.git.gitee
2+
3+
import com.tencent.devops.scm.api.UserService
4+
import com.tencent.devops.scm.api.pojo.User
5+
import com.tencent.devops.scm.api.pojo.auth.IScmAuth
6+
import com.tencent.devops.scm.sdk.gitee.GiteeApiFactory
7+
8+
/**
9+
* Gitee 用户服务实现类
10+
* @property apiFactory Gitee API工厂
11+
*/
12+
class GiteeUserService(
13+
private val apiFactory: GiteeApiFactory
14+
) : UserService {
15+
16+
/**
17+
* 查找当前用户
18+
* @param auth 认证信息
19+
* @return 用户信息
20+
*/
21+
override fun find(auth: IScmAuth): User {
22+
return GiteeApiTemplate.execute(auth, apiFactory) { tGitApi ->
23+
val tGitUser = tGitApi.userApi.currentUser
24+
GiteeObjectConverter.convertUser(tGitUser)
25+
}
26+
}
27+
}

devops-scm-sdk/devops-scm-sdk-gitee/src/main/java/com/tencent/devops/scm/sdk/gitee/GiteeApi.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class GiteeApi {
2222
private volatile GiteeProjectApi projectApi;
2323
private volatile GiteeCommitApi commitApi;
2424
private volatile GiteeTagApi tagApi;
25+
private volatile GiteeUserApi userApi;
2526

2627

2728
public GiteeApi(GiteeApiClient client) {
@@ -101,4 +102,15 @@ public GiteeTagApi getTagApi() {
101102
}
102103
return tagApi;
103104
}
105+
106+
public GiteeUserApi getUserApi() {
107+
if (userApi == null) {
108+
synchronized (this) {
109+
if (userApi == null) {
110+
userApi = new GiteeUserApi(this);
111+
}
112+
}
113+
}
114+
return userApi;
115+
}
104116
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.tencent.devops.scm.sdk.gitee;
2+
3+
import com.tencent.devops.scm.sdk.common.GitOauth2ClientProperties;
4+
import com.tencent.devops.scm.sdk.common.Requester;
5+
import com.tencent.devops.scm.sdk.common.ScmHttpMethod;
6+
import com.tencent.devops.scm.sdk.common.ScmRequest;
7+
import com.tencent.devops.scm.sdk.common.UriTemplate;
8+
import com.tencent.devops.scm.sdk.common.auth.HttpAuthProvider;
9+
import com.tencent.devops.scm.sdk.common.connector.ScmConnector;
10+
import com.tencent.devops.scm.sdk.common.util.MapBuilder;
11+
import com.tencent.devops.scm.sdk.common.util.UrlEncoder;
12+
import com.tencent.devops.scm.sdk.gitee.pojo.GiteeOauth2AccessToken;
13+
14+
public class GiteeOauth2Api {
15+
16+
private final GitOauth2ClientProperties properties;
17+
private final GiteeApiClient client;
18+
private static final String OAUTH2_URI_PATTERN = "oauth/authorize";
19+
private static final String OAUTH2_CALLBACK_URI_PATTERN =
20+
"oauth/token?client_id=:client_id&"
21+
+ "client_secret=:client_secret&"
22+
+ "code=:code&"
23+
+ "grant_type=authorization_code&"
24+
+ "redirect_uri=:redirect_uri";
25+
private static final String OAUTH2_REFRESH_TOKEN_URI_PATTERN =
26+
"oauth/token?client_id=:client_id&"
27+
+ "client_secret=:client_secret&"
28+
+ "refresh_token=:refresh_token&"
29+
+ "grant_type=refresh_token&"
30+
+ "redirect_uri=:redirect_uri";
31+
32+
public GiteeOauth2Api(GitOauth2ClientProperties properties, ScmConnector connector) {
33+
this.properties = properties;
34+
this.client = new GiteeApiClient(properties.getWebUrl(), connector, HttpAuthProvider.ANONYMOUS);
35+
}
36+
37+
// client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=YOUR_UNIQUE_STATE_HASH
38+
public String authorizationUrl(String state) {
39+
return ScmRequest.newBuilder()
40+
.withApiUrl(properties.getWebUrl())
41+
.withUrlPath(OAUTH2_URI_PATTERN)
42+
.with("client_id", properties.getClientId())
43+
.with("redirect_uri", properties.getRedirectUri())
44+
.with("response_type", "code")
45+
.with("state", state)
46+
.build()
47+
.url()
48+
.toString();
49+
}
50+
51+
public GiteeOauth2AccessToken callback(String code) {
52+
String urlPath = UriTemplate.from(OAUTH2_CALLBACK_URI_PATTERN)
53+
.with("client_id", properties.getClientId())
54+
.with("client_secret", properties.getClientSecret())
55+
.with("code", code)
56+
.with("redirect_uri", properties.getRedirectUri(), true)
57+
.expand();
58+
return new Requester(client)
59+
.method(ScmHttpMethod.POST)
60+
.withUrlPath(
61+
OAUTH2_CALLBACK_URI_PATTERN,
62+
MapBuilder.<String, String>newBuilder()
63+
.add("client_id", properties.getClientId())
64+
.add("client_secret", properties.getClientSecret())
65+
.add("code", code)
66+
.add("redirect_uri", UrlEncoder.urlEncode(properties.getRedirectUri()))
67+
.build()
68+
)
69+
.contentType("application/x-www-form-urlencoded")
70+
.with("")
71+
.fetch(GiteeOauth2AccessToken.class);
72+
}
73+
74+
public GiteeOauth2AccessToken refresh(String refreshToken) {
75+
return new Requester(client)
76+
.method(ScmHttpMethod.POST)
77+
.withUrlPath(
78+
OAUTH2_REFRESH_TOKEN_URI_PATTERN,
79+
MapBuilder.<String, String>newBuilder()
80+
.add("client_id", properties.getClientId())
81+
.add("client_secret", properties.getClientSecret())
82+
.add("refresh_token", refreshToken)
83+
.add("redirect_uri", UrlEncoder.urlEncode(properties.getRedirectUri()))
84+
.build()
85+
)
86+
.contentType("application/x-www-form-urlencoded")
87+
.with("")
88+
.fetch(GiteeOauth2AccessToken.class);
89+
}
90+
}

0 commit comments

Comments
 (0)