Skip to content

Commit 8ba2a28

Browse files
committed
feat: auth, create team logic
1 parent 43e51ea commit 8ba2a28

File tree

10 files changed

+111
-73
lines changed

10 files changed

+111
-73
lines changed

src/extension.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,12 @@ import toast from './utils/toast';
77
import { readConfig } from './services/dcloud';
88

99
async function activate(context: IContext) {
10-
// TODO: 认证,拿到用户信息
1110
const webviewProvider = new WebviewProvider(context);
12-
1311
const repoInfo = await CodingServer.getRepoParams();
14-
console.log('repoInfo ==> ', repoInfo);
12+
console.log('repoInfo: ', repoInfo);
1513
const token = await readConfig(`token`);
16-
if (!token) {
17-
toast.warn(`请先登录 CODING`);
18-
}
1914

20-
const codingServer = new CodingServer({
21-
accessToken: token,
22-
});
15+
const codingServer = new CodingServer(context);
2316

2417
dispatch(ACTIONS.SET_CTX, {
2518
context,

src/init/initCredentials.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,40 @@
11
import hx from 'hbuilderx';
22
import * as DCloudService from '../services/dcloud';
33
import toast from '../utils/toast';
4+
import { refreshTree } from './registerCommands';
45

56
const { executeCommand } = hx.commands;
67

78
export async function initCredentials(context: IContext) {
89
try {
910
let hbToken = await DCloudService.readConfig(`hbToken`);
10-
console.log('hbToken => ', hbToken);
11+
const token = await DCloudService.readConfig(`token`);
1112

1213
if (!hbToken) {
1314
const code = await DCloudService.grantForUserInfo();
14-
console.log('code => ', code);
1515
const tokenResult = await DCloudService.applyForToken(code);
16-
console.log('tokenResult => ', tokenResult);
1716
hbToken = tokenResult.data.access_token;
1817
}
1918

2019
const resp = await DCloudService.fetchUser(hbToken);
21-
console.log('resp => ', resp);
2220
toast.info(`logged in as DCloud user: ${resp.data.nickname} ${resp.data.email}`);
2321

24-
executeCommand('codingPlugin.password');
22+
if (!token) {
23+
await executeCommand('codingPlugin.createTeam');
24+
}
2525

26-
// const {
27-
// ctx: { codingServer, repoInfo, token },
28-
// } = context;
29-
// const userData = await codingServer.getUserInfo(token);
30-
// console.log('userData => ', userData);
31-
// toast.info(`logged in as coding user: ${userData.name} @ ${userData.team}`);
26+
const {
27+
ctx: { codingServer, token: accessToken },
28+
} = context;
29+
if (accessToken) {
30+
const userData = await codingServer.getUserInfo(accessToken);
31+
toast.info(`logged in as CODING user: ${userData.name} @ ${userData.team}`);
32+
}
3233
} catch (err) {
33-
console.error(err);
34+
if (err === 1) {
35+
toast.warn(`请先登录 DCloud`);
36+
}
37+
} finally {
38+
refreshTree();
3439
}
3540
}

src/init/registerCommands.ts

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import toast from '../utils/toast';
55
import ACTIONS, { dispatch } from '../utils/actions';
66
import { IDepot, IMRItem, IUserInfo } from '../typings/common';
77

8-
const { registerCommand } = hx.commands;
8+
const { registerCommand, executeCommand } = hx.commands;
99
const { showQuickPick, showInputBox } = hx.window;
1010

11+
export const refreshTree = () => executeCommand('codingPlugin.refreshTree');
12+
1113
export default function registerCommands(context: IContext) {
1214
const { codingServer, token } = context;
1315

@@ -29,6 +31,7 @@ export default function registerCommands(context: IContext) {
2931
context,
3032
value: result.depot,
3133
});
34+
refreshTree();
3235
}),
3336
);
3437

@@ -70,7 +73,7 @@ export default function registerCommands(context: IContext) {
7073

7174
context.subscriptions.push(
7275
registerCommand('codingPlugin.createDepot', async function (param: any) {
73-
const depot = await hx.window.showInputBox({
76+
const depot = await showInputBox({
7477
prompt: '请输入仓库名',
7578
});
7679

@@ -89,6 +92,7 @@ export default function registerCommands(context: IContext) {
8992
value: result,
9093
});
9194
}
95+
refreshTree();
9296
}
9397
}),
9498
);
@@ -99,37 +103,74 @@ export default function registerCommands(context: IContext) {
99103
}),
100104
);
101105

106+
context.subscriptions.push(
107+
registerCommand('codingPlugin.login', async function () {
108+
const newToken = await showInputBox({
109+
prompt: '请输入 CODING 个人令牌',
110+
});
111+
112+
if (!newToken) {
113+
toast.error(`个人令牌不能为空`);
114+
return;
115+
}
116+
117+
try {
118+
const userInfo = await codingServer.getUserInfo(newToken);
119+
if (userInfo) {
120+
dispatch(ACTIONS.SET_TOKEN, {
121+
context,
122+
value: newToken,
123+
});
124+
refreshTree();
125+
}
126+
} catch {
127+
toast.error(`个人令牌无效`);
128+
}
129+
}),
130+
);
131+
102132
context.subscriptions.push(
103133
registerCommand('codingPlugin.refreshTree', async function () {
104134
console.log('refresh');
105135
}),
106136
);
107137

108138
context.subscriptions.push(
109-
registerCommand('codingPlugin.password', async function () {
110-
const password1 = await showInputBox({
139+
registerCommand('codingPlugin.createTeam', async function () {
140+
const password = await showInputBox({
111141
prompt: '配置 CODING 服务密码',
112142
password: true,
113143
});
114144

115-
if (!password1) {
145+
if (!password) {
116146
toast.error('服务密码不能为空');
117147
return;
118148
}
119149

120-
const password2 = await showInputBox({
150+
const repeatPassword = await showInputBox({
121151
prompt: '再次确认密码',
122152
password: true,
123153
});
124154

125-
if (password1 !== password2) {
155+
if (password !== repeatPassword) {
126156
toast.error('两次输入的密码不一致');
127157
return;
128158
}
129159

130-
// 创建团队
131-
const result = await codingServer.createTeam(password1);
132-
console.log('create result => ', result);
160+
try {
161+
const result = await codingServer.createTeam(password);
162+
if (result) {
163+
toast.info('团队创建成功');
164+
dispatch(ACTIONS.SET_TOKEN, {
165+
context,
166+
value: result.Token,
167+
});
168+
refreshTree();
169+
}
170+
} catch (err) {
171+
toast.error(`创建团队失败`);
172+
console.error(err);
173+
}
133174
}),
134175
);
135176
}

src/initialize.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export function clear(context: IContext) {
88
}
99

1010
export default function initialize(context: IContext) {
11+
initCredentials(context);
1112
registerCommands(context);
1213
createTreeViews(context);
1314
initWorkspace(context);
14-
initCredentials(context);
1515
}

src/services/codingServer.ts

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
import hx from 'hbuilderx';
22
import fs from 'fs';
33
import qs from 'querystring';
4-
import axios from '../utils/axios';
4+
import axios, { getApiPrefix } from '../utils/axios';
55
import git from 'isomorphic-git';
6-
import { IDepot, IRepoInfo, ISessionData } from '../typings/common';
6+
import { IDepot, IRepoInfo } from '../typings/common';
77
import { parseCloneUrl } from '../utils/repo';
88
import { getIp } from '../utils/ip';
99
import { encryptPassword } from '../utils/password';
1010
import { getEmailPrefix } from '../utils/email';
1111
import { readConfig } from './dcloud';
1212

1313
export default class CodingServer {
14-
_session: ISessionData;
14+
context: IContext;
1515

16-
constructor(session: ISessionData) {
17-
this._session = session;
18-
}
19-
20-
get session() {
21-
return this._session;
16+
constructor(context: IContext) {
17+
this.context = context;
2218
}
2319

2420
getHeaders = (token?: string) => ({
25-
Authorization: `token ${token || this._session.accessToken}`,
21+
Authorization: `token ${token || this.context.token}`,
2622
});
2723

2824
static async getRepoParams() {
@@ -44,7 +40,7 @@ export default class CodingServer {
4440
try {
4541
const result = await axios({
4642
method: 'get',
47-
url: `https://e.coding.net/api/current_user`,
43+
url: `${getApiPrefix()}/api/current_user`,
4844
headers: this.getHeaders(token),
4945
});
5046

@@ -60,7 +56,7 @@ export default class CodingServer {
6056

6157
async getMrList({ team, project, repo }: IRepoInfo) {
6258
try {
63-
const url = `https://${team}.coding.net/api/user/${team}/project/${project}/depot/${repo}/git/merges/query`;
59+
const url = `${getApiPrefix(team)}/api/user/${team}/project/${project}/depot/${repo}/git/merges/query`;
6460
const result = await axios({
6561
method: 'get',
6662
url,
@@ -88,7 +84,9 @@ export default class CodingServer {
8884
try {
8985
const result = await axios({
9086
method: 'get',
91-
url: `https://${team}.coding.net/api/user/${team}/project/${project}/depot/${repo}/git/merge/${mergeRequestIId}/detail`,
87+
url: `${getApiPrefix(
88+
team,
89+
)}/api/user/${team}/project/${project}/depot/${repo}/git/merge/${mergeRequestIId}/detail`,
9290
headers: this.getHeaders(),
9391
});
9492

@@ -106,7 +104,7 @@ export default class CodingServer {
106104
try {
107105
const result = await axios({
108106
method: 'get',
109-
url: `https://${team}.coding.net/api/user/${team}/depots`,
107+
url: `${getApiPrefix(team)}/api/user/${team}/depots`,
110108
headers: this.getHeaders(),
111109
});
112110

@@ -125,7 +123,7 @@ export default class CodingServer {
125123
try {
126124
const result = await axios({
127125
method: 'post',
128-
url: `https://${team}.coding.net/api/team/${team}/template-project`,
126+
url: `${getApiPrefix(team)}/api/team/${team}/template-project`,
129127
headers: this.getHeaders(),
130128
data: {
131129
name: project,
@@ -153,7 +151,7 @@ export default class CodingServer {
153151

154152
const result = await axios({
155153
method: 'post',
156-
url: `https://${team}.coding.net/api/user/${team}/project/${project}/depot`,
154+
url: `${getApiPrefix(team)}/api/user/${team}/project/${project}/depot`,
157155
headers: {
158156
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
159157
...this.getHeaders(),
@@ -181,23 +179,14 @@ export default class CodingServer {
181179
const email = await readConfig(`email`);
182180
const ip = getIp();
183181
const pwd = encryptPassword(password);
184-
console.log('ip => ', ip);
185-
console.log('pwd => ', pwd);
186182
const emailPrefix = getEmailPrefix(email);
187-
const teamName = `dcloud-${emailPrefix}-${Date.now()}`;
188-
189-
console.log('data ===> ', {
190-
Action: 'CreateTeam',
191-
Domain: teamName,
192-
TeamName: teamName,
193-
Ip: ip,
194-
Password: pwd,
195-
Email: email,
196-
});
183+
const randomNum = Math.random().toString().slice(-5);
184+
const teamName = `dcloud-${emailPrefix}-${randomNum}`;
185+
console.log('teamName ==> ', teamName);
197186

198187
const result = await axios({
199188
method: 'post',
200-
url: `https://e.coding.net/open-api`,
189+
url: `${getApiPrefix()}/open-api`,
201190
data: {
202191
Action: 'CreateTeam',
203192
Domain: teamName,
@@ -207,7 +196,12 @@ export default class CodingServer {
207196
Email: email,
208197
},
209198
});
210-
console.log('result => ', result);
199+
200+
if (result.Response.Error) {
201+
return Promise.reject(result);
202+
}
203+
204+
return result.Response.PersonalToken;
211205
} catch (err) {
212206
console.error(err);
213207
}

src/services/dcloud.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import hx from 'hbuilderx';
22

33
import axios from '../utils/axios';
4-
import { ITokenResponse, IDCloudUser, ITokenType, IOAuthResponse } from '../typings/common';
4+
import { ITokenResponse, IDCloudUser, IOAuthResponse } from '../typings/common';
55

66
const appSecret = `dnGxdvWuEwOO3VimZwo1IsqfESam7k`;
77
export const appId = `crvUAM0Snz`;
@@ -89,7 +89,6 @@ export const grantForUserInfo = (): Promise<string | null> =>
8989
appId: appId,
9090
})
9191
.then((param: IOAuthResponse) => {
92-
console.log('param => ', param);
9392
const { code, error } = param;
9493
if (error || !code) {
9594
console.error(`授权出错码 ${error}${GRANT_ERROR[error]}`);

src/typings/common.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@ export interface IUserInfo {
1818
team: string;
1919
}
2020

21-
export interface ISessionData {
22-
id?: string;
23-
user?: IUserInfo | null;
24-
accessToken: string;
25-
refreshToken?: string;
26-
}
27-
2821
export interface IReviewer {
2922
reviewer: IUserInfo;
3023
value: number;

src/utils/actions.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { setConfig } from '../services/dcloud';
2+
13
const enum ACTIONS {
24
SET_DEPOTS = 'SET_DEPOTS',
35
SET_SELECTED_DEPOT = 'SET_SELECTED_DEPOT',
@@ -6,6 +8,7 @@ const enum ACTIONS {
68
SET_REPO_INFO = 'SET_REPO_INFO',
79
SET_CTX = 'SET_CTX',
810
SET_MR_CUSTOM_EDITOR = 'SET_MR_CUSTOM_EDITOR',
11+
SET_TOKEN = 'SET_TOKEN',
912
}
1013

1114
interface IPayload {
@@ -36,6 +39,10 @@ export const dispatch = (type: ACTIONS, { context, value }: IPayload) => {
3639
case ACTIONS.SET_MR_CUSTOM_EDITOR:
3740
context.mrCustomEditor = value;
3841
break;
42+
case ACTIONS.SET_TOKEN:
43+
context.token = value;
44+
setConfig(`token`, value);
45+
break;
3946
default:
4047
return;
4148
}

0 commit comments

Comments
 (0)