Benoit Sida 4 år sedan
förälder
incheckning
3d1c1d6746
1 ändrade filer med 216 tillägg och 154 borttagningar
  1. 216
    154
      blih.js

+ 216
- 154
blih.js Visa fil

6
 const utf8 = require('utf8');
6
 const utf8 = require('utf8');
7
 const crypto = require('crypto');
7
 const crypto = require('crypto');
8
 const request = require('request');
8
 const request = require('request');
9
-const stringify = require('json-stable-stringify')
9
+const stringify = require('json-stable-stringify');
10
+const fs = require('fs');
10
 
11
 
11
 class Blih {
12
 class Blih {
12
-    constructor(options) {
13
-        this.options = options;
14
-        this._baseUrl = options.baseurl || 'https://blih.epitech.eu/';
15
-        this._user = options.user || this.get_user();
16
-        this._token = options.token || this.token_calc();
17
-        this._verbose = options.verbose || false;
18
-        this._userAgent = options.useragent || 'blih-' + program.version;
19
-    }
20
-
21
-    sign_data(data) {
22
-        const sign = crypto.createHmac('sha512', this._token);
23
-        return {
24
-            user: this._user,
25
-            signature: sign.update(this._user + stringify(data, {space: "    "})).digest('hex'),
26
-            data: data
27
-        };
28
-    }
29
-
30
-    request(options) {
31
-        const signed_data = this.sign_data(options.data);
32
-        request({
33
-            url: options.path,
34
-            baseUrl: this._baseUrl,
35
-            method: options.method || 'GET',
36
-            body: JSON.stringify(signed_data),
37
-            headers: {
38
-                'Content-Type': options.contentType || 'application/json',
39
-                'User-Agent': this._userAgent
40
-            }
41
-        }, function (err, res, body) {
42
-            if (err)
43
-              return console.error('request failed:', err);
44
-            return console.log(body);
45
-        });
46
-    }
47
-
48
-    get_user() {
49
-        return this.options.user || process.env.LOGNAME || process.env.USER ||
50
-            process.env.LNAME || process.env.USERNAME;
51
-    }
52
-
53
-    token_calc() {
54
-        return crypto.createHash('sha512').update(prompt('Password: ', {echo: '*'})).digest('hex');
55
-    }
56
-
57
-    repo_create(name, type, description) {
58
-        var data = { name, type: type || 'git' };
59
-        if (description)
60
-            data['description'] = description;
61
-        return this.request({ path: '/repositories', method:'POST', data: data });
62
-    }
13
+	constructor(options) {
14
+		this.options = options;
15
+		this._baseUrl = options.baseurl || 'https://blih.epitech.eu/';
16
+		this._user = options.user || this.get_user();
17
+		this._token = options.token || this.token_calc();
18
+		this._verbose = options.verbose || false;
19
+		this._userAgent = options.useragent || 'blih-' + program.version;
20
+	}
21
+
22
+	sign_data(data) {
23
+		const sign = crypto.createHmac('sha512', this._token);
24
+		sign.update(this._user);
25
+		if (data)
26
+			sign.update(stringify(data, {space: "    "}));
27
+		return {
28
+			user: this._user,
29
+			signature: sign.digest('hex'),
30
+			data: data
31
+		};
32
+	}
33
+
34
+	request(options, cb) {
35
+		cb = cb || ((res) => { console.log(res.message); });
36
+		const signed_data = this.sign_data(options.data);
37
+		request({
38
+			url: options.path,
39
+			baseUrl: this._baseUrl,
40
+			method: options.method || 'GET',
41
+			body: JSON.stringify(signed_data),
42
+			headers: {
43
+				'Content-Type': options.contentType || 'application/json',
44
+				'User-Agent': this._userAgent
45
+			}
46
+		}, function (err, res, body) {
47
+			body = JSON.parse(body);
48
+			if (body.error) {
49
+				console.error(`HTTP Error ${res.statusCode}\nError message: '${body.error}'`);
50
+				process.exit(0);
51
+			}
52
+			cb(body);
53
+		});
54
+	}
55
+
56
+	get_user() {
57
+		return this.options.user || process.env.LOGNAME || process.env.USER ||
58
+			process.env.LNAME || process.env.USERNAME;
59
+	}
60
+
61
+	token_calc() {
62
+		return crypto.createHash('sha512').update(prompt(`${this._user}'s password: `, {echo: '*'}) || process.exit(1)).digest('hex');
63
+	}
63
 }
64
 }
64
 
65
 
65
-class subcommand {
66
-    constructor(options) {
67
-        this.options = options;
68
-    }
69
-}
66
+class Subcommand {
67
+	constructor(options) {
68
+		this.options = options;
69
+		this.usage_message = '';
70
+	}
70
 
71
 
71
-class Repository extends subcommand {
72
-    create(params) {
73
-        if (params.length < 1)
74
-            return this.usage()
75
-        const blih = new Blih(this.options)
76
-        blih.repo_create(params[0]);
77
-    }
78
-
79
-    list() {
80
-        console.log(process.argv);
81
-    }
82
-
83
-    info() {
84
-        console.log(process.argv);
85
-    }
86
-
87
-    delete() {
88
-        console.log(process.argv);
89
-    }
90
-
91
-    setacl() {
92
-        console.log(process.argv);
93
-    }
94
-
95
-    getacl() {
96
-        console.log(process.argv);
97
-    }
98
-
99
-    usage() {
100
-        console.log('Usage: ' + process.argv[1] + ' [options] repository command ...')
101
-        console.log()
102
-        console.log('Commands :')
103
-        console.log('\tcreate repo\t\t\t-- Create a repository named "repo"')
104
-        console.log('\tinfo repo\t\t\t-- Get the repository metadata')
105
-        console.log('\tgetacl repo\t\t\t-- Get the acls set for the repository')
106
-        console.log('\tlist\t\t\t\t-- List the repositories created')
107
-        console.log('\tsetacl repo user [acl]\t\t-- Set (or remove) an acl for "user" on "repo"')
108
-        console.log('\t\t\t\t\tACL format:')
109
-        console.log('\t\t\t\t\tr for read')
110
-        console.log('\t\t\t\t\tw for write')
111
-        console.log('\t\t\t\t\ta for admin')
112
-    }
72
+	usage() {
73
+		console.log(this.usage_message);
74
+	}
113
 }
75
 }
114
 
76
 
115
-class sshkey extends subcommand {
116
-    list() {
117
-
118
-    }
119
-
120
-    upload() {
121
-
122
-    }
123
-
124
-    delete() {
125
-
126
-    }
127
-
128
-    usage() {
129
-
130
-    }
77
+class Repository extends Subcommand {
78
+	constructor(options) {
79
+		super(options);
80
+		this.usage_message =`
81
+		Usage: ${process.argv[1]} [options] repository command ...
82
+		
83
+		Commands :
84
+		    create repo\t\t\t-- Create a repository named "repo"
85
+		    info repo\t\t\t-- Get the repository metadata
86
+		    getacl repo\t\t\t-- Get the acls set for the repository
87
+		    list\t\t\t-- List the repositories created
88
+		    setacl repo user [acl]\t-- Set (or remove) an acl for "user" on "repo"
89
+		    \t\t\t\tACL format:
90
+		    \t\t\t\t\tr for read
91
+		    \t\t\t\t\tw for write
92
+		    \t\t\t\t\ta for admin`;
93
+		this.usage_message = this.usage_message.substr(3).replace(/\n\t\t/g, '\n');
94
+	}
95
+
96
+	create(params) {
97
+		if (params.length < 1)
98
+			return this.usage();
99
+		const blih = new Blih(this.options);
100
+		blih.request({ path: '/repositories', method:'POST', data: {
101
+			name: params[0],
102
+			type: 'git',
103
+			description: ''
104
+		}});
105
+	}
106
+
107
+	list() {
108
+		const blih = new Blih(this.options);
109
+		blih.request({ path: '/repositories' }, (res) => {
110
+			if (res.hasOwnProperty("repositories"))
111
+				for (let repo in res.repositories)
112
+					console.log(repo);
113
+		});
114
+	}
115
+
116
+	info(params) {
117
+		if (params.length < 1)
118
+			return this.usage();
119
+		const blih = new Blih(this.options);
120
+		blih.request({ path: `/repository/${params[0]}` }, (res) => {
121
+			console.log('Repository info :');
122
+			console.log(`name : ${params[0]}`);
123
+			if (res.hasOwnProperty("message"))
124
+				for (let info in res.message)
125
+					console.log(`${info} : ${res.message[info]}`);
126
+		});
127
+	}
128
+
129
+	delete(params) {
130
+		if (params.length < 1)
131
+			return this.usage();
132
+		const blih = new Blih(this.options);
133
+		blih.request({ path: `/repository/${params[0]}`, method:'DELETE' });
134
+	}
135
+
136
+	setacl(params) {
137
+		if (params.length < 2)
138
+			return this.usage();
139
+		const blih = new Blih(this.options);
140
+		blih.request({ path: `/repository/${params[0]}/acls`, method:'POST', data: {
141
+			user: params[1],
142
+			acl: params[2] || ''
143
+		}});
144
+	}
145
+
146
+	getacl(params) {
147
+		if (params.length < 1)
148
+			return this.usage();
149
+		const blih = new Blih(this.options);
150
+		blih.request({ path: `/repository/${params[0]}/acls` }, (res) => {
151
+			for (let info in res)
152
+				console.log(`${info}:${res[info]}`);
153
+		});
154
+	}
131
 }
155
 }
132
 
156
 
157
+class SSHKey extends Subcommand {
158
+	constructor(options) {
159
+		super(options);
160
+		this.usage_message = `
161
+		Usage: ${process.argv[1]} [options] sshkey command ...
162
+		
163
+		Commands :
164
+		    upload [file]\t\t\t-- Upload a new ssh-key
165
+		    list\t\t\t\t-- List the ssh-keys
166
+		    delete [sshkey]\t\t\t-- Delete the sshkey with comment [sshkey]`;
167
+		this.usage_message = this.usage_message.substr(3).replace(/\n\t\t/g, '\n');
168
+	}
169
+
170
+	list() {
171
+		const blih = new Blih(this.options);
172
+		blih.request({ path: '/sshkeys' }, (res) => {
173
+			console.log();
174
+			for (let info in res)
175
+				console.log(`${info}:\n${res[info]}\n`);
176
+		});
177
+	}
178
+
179
+	upload(params) {
180
+		if (params.length < 1)
181
+			return this.usage();
182
+		const file = params[0];
183
+		const blih = new Blih(this.options);
184
+		fs.readFile(file, 'utf8', (err, data) => {
185
+			if (err) {
186
+				console.error(`Can't open file : ${file}`);
187
+				process.exit(1);
188
+			}
189
+			blih.request({ path: '/sshkeys', method: 'POST', data: { sshkey: data.trim() } });
190
+		});
191
+	}
192
+
193
+	delete(params) {
194
+		if (params.length < 1)
195
+			return this.usage();
196
+		const blih = new Blih(this.options);
197
+		blih.request({ path: `/sshkey/${params[0]}`, method: 'DELETE' });
198
+	}
199
+}
133
 
200
 
134
-program
135
-.version('1.7')
136
-.option('-v, --verbose', 'Enable verbose mode')
137
-.option('-u, --user <user>', 'Set user')
138
-.option('-b, --baseurl <url>', 'Set baseurl')
139
-.option('-t, --token <token>', 'Set token')
140
-.option('-U, --useragent <agent>', 'Set useragent');
141
-
142
-program
143
-.command('repository [params...]')
144
-.description('Manages repositories')
145
-.action(function (params) {
146
-    const action = params.shift();
147
-    var repo = new Repository(program);
148
-    if (typeof repo[action] === 'function')
149
-        repo[action](params);
150
-    else
151
-        repo.usage();
152
-});
153
-
154
-program
155
-.command('sshkey')
156
-.description('Manages SSH keys')
157
-.action(function (params) {
158
-    const action = params.unshift();
159
-    var sshkeys= new sshkey(program);
160
-    if (typeof sshkeys[action] === 'function')
161
-        sshkeys[action]();
162
-    else
163
-        sshkeys.usage();
164
-});
165
-
166
-program
167
-.command('whoami')
168
-.description('Ask who you are')
169
-.action(function() {
170
-    console.log('whoami');
171
-});
201
+program.version('1.7')
202
+	   .option('-v, --verbose', 'Enable verbose mode [ actually no difference ]')
203
+	   .option('-u, --user <user>', 'Set user')
204
+	   .option('-b, --baseurl <url>', 'Set baseurl')
205
+	   .option('-t, --token <token>', 'Set token')
206
+	   .option('-U, --useragent <agent>', 'Set useragent');
207
+
208
+program.command('repository [params...]')
209
+	   .description('Manages repositories')
210
+	   .action(function (params) {
211
+		   var action = params.shift();
212
+		   const repo = new Repository(program);
213
+		   if (typeof repo[action] !== 'function')
214
+			   action = 'usage';
215
+		   repo[action](params);
216
+	   });
217
+
218
+program.command('sshkey [params...]')
219
+	   .description('Manages SSH keys')
220
+	   .action(function (params) {
221
+		   var action = params.shift();
222
+		   const sshkeys = new SSHKey(program);
223
+		   if (typeof sshkeys[action] !== 'function')
224
+			   action = 'usage';
225
+		   sshkeys[action](params);
226
+	   });
227
+
228
+program.command('whoami')
229
+	   .description('Ask who you are')
230
+	   .action(function() {
231
+		   const blih = new Blih(program);
232
+		   blih.request({ path: "/whoami" });
233
+	   });
172
 
234
 
173
 program.parse(process.argv);
235
 program.parse(process.argv);
174
 
236
 
175
 if (program.args.length === 0)
237
 if (program.args.length === 0)
176
-  program.help();
238
+	program.help();