const http = require('http');
const isAdmin = require('cnpmjs.org/lib/common').isAdmin;
const config = require('cnpmjs.org/config');
// User: https://github.com/cnpm/cnpmjs.org/wiki/Use-Your-Own-User-Authorization#user-data-structure
// {
// "login": "fengmk2",
// "email": "fengmk2@gmail.com",
// "name": "Yuan Feng",
// "html_url": "http://fengmk2.github.com",
// "avatar_url": "https://avatars3.githubusercontent.com/u/156269?s=460",
// "im_url": "",
// "site_admin": false,
// "scopes": ["@org1", "@org2"]
// }
const emailDomain = '@xxxx.com';
const defaultToken = 'xxxxxxxxxxxxxxxxxxxx';
function convertToUser(gitUser) {
let user = {
login: gitUser.username,
email: gitUser.email || `${gitUser.username}${emailDomain}`,
name: gitUser.name,
html_url: gitUser.web_url,
avatar_url: gitUser.avatar_url,
im_url: '',
site_admin: isAdmin(gitUser.username),
scopes: config.scopes,
};
return user;
}
function gitHttp(api, token) {
return new Promise((resolve, reject) => {
let options = {
method: 'GET',
port: 80,
hostname: 'git.xxxxxx.work',
path: `/api/v4${api}`,
headers: {
'PRIVATE-TOKEN': token
}
};
let req = http.request(options, (res) => {
if (res.statusCode === 200) {
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => {
rawData += chunk;
});
res.on('end', () => {
try {
let parsedData = JSON.parse(rawData);
console.log(`[CustomUserService] [${api}] [${token}] JSON.parse: success`, parsedData);
resolve(parsedData);
} catch (e) {
reject(`[CustomUserService] [${api}] [${token}] JSON.parse: ${e.message}`, e);
}
});
}
else {
reject(`[CustomUserService] [${api}] [${token}] statusCode: ${res.statusCode}`);
}
});
req.on('error', (e) => {
reject(`[CustomUserService] [${api}] [${token}] error: ${e.message}`, e);
});
req.end();
});
}
function* gitAuth(username, token) {
let data = yield gitHttp('/user', token);
let gitUser = null;
if (data && data.username === username) {
gitUser = data;
}
return gitUser;
}
function* gitGet(username) {
let data = yield gitHttp(`/users?username=${encodeURIComponent(username)}`, defaultToken);
let gitUser = null;
if (data && data.length > 0 && data[0].username === username) {
gitUser = data[0];
}
return gitUser;
}
function* gitList(usernames) {
let gitUsers = [];
if (usernames && usernames.length > 0) {
for (let i = 0; i < usernames.length; i++) {
let username = usernames[i];
let gitUser = yield gitGet(username);
if (gitUser) {
gitUsers.push(gitUser);
}
}
}
return gitUsers;
}
function* gitSearch(query, limit) {
let data = yield gitHttp(`/users?search=${encodeURIComponent(query)}&per_page=${limit}`, defaultToken);
let gitUsers = [];
if (data && data.length > 0) {
gitUsers = data;
}
return gitUsers;
}
function CustomUserService() { }
const proto = CustomUserService.prototype;
/**
* Auth user with login name and password
* @param {String} login login name
* @param {String} password login password
* @return {User}
*/
proto.auth = function* (login, password) {
console.log(`[CustomUserService] [auth]`, login, password);
let user = null;
try {
let gitUser = yield gitAuth(login, password);
if (gitUser) {
user = convertToUser(gitUser);
}
}
catch (e) {
console.log(`[CustomUserService] [auth]`, e);
}
return user;
};
/**
* Get user by login name
* @param {String} login login name
* @return {User}
*/
proto.get = function* (login) {
console.log(`[CustomUserService] [get]`, login);
let user = null;
try {
let gitUser = yield gitGet(login);
if (gitUser) {
user = convertToUser(gitUser);
}
}
catch (e) {
console.log(`[CustomUserService] [get]`, e);
}
return user;
};
/**
* List users
* @param {Array<String>} logins login names
* @return {Array<User>}
*/
proto.list = function* (logins) {
console.log(`[CustomUserService] [list]`, logins);
let users = [];
try {
let gitUsers = yield gitList(logins);
gitUsers.forEach((gitUser) => {
users.push(convertToUser(gitUser));
});
}
catch (e) {
console.log(`[CustomUserService] [list]`, e);
}
return users;
};
/**
* Search users
* @param {String} query query keyword
* @param {Object} [options] optional query params
* - {Number} limit match users count, default is `20`
* @return {Array<User>}
*/
proto.search = function* (query, options) {
console.log(`[CustomUserService] [search]`, query, options);
let users = [];
try {
options = options || {};
options.limit = parseInt(options.limit);
if (!options.limit || options.limit < 0) {
options.limit = 20;
}
let gitUsers = yield gitSearch(query, options.limit);
gitUsers.forEach((gitUser) => {
users.push(convertToUser(gitUser));
});
}
catch (e) {
console.log(`[CustomUserService] [search]`, e);
}
return users;
};
module.exports = CustomUserService;