Skip to content

Commit 949e031

Browse files
committed
Implement access marker for API
Contract definition: https://github.com/metarhia/Contracts/blob/master/doc/API.md Closes: #99 PR-URL: #103
1 parent ccb58b1 commit 949e031

File tree

4 files changed

+36
-29
lines changed

4 files changed

+36
-29
lines changed

api/about.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(async () => [
1+
async () => [
22
'Metarhia is a Community and Technology Stack',
33
'for Distributed Highload Applications and Data Storage',
44
'',
@@ -25,4 +25,4 @@
2525
'Objective-C, Kotlin, C#, Delphi, Assembler, Python, Haskell, etc.',
2626
'We provide solutions for Unix/Linux, Windows, OSX, Android, Internet',
2727
'solutions and Embedded systems.'
28-
]);
28+
];

api/signIn.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
async ({ login, password }) => {
2-
const user = await application.auth.getUser(login);
3-
const hash = user ? user.password : undefined;
4-
const verified = await application.security.validatePassword(password, hash);
5-
if (!user || !verified) throw new Error('Incorrect login or password');
6-
console.log(`Logged user: ${login}`);
7-
return { result: 'success', userId: user.id };
8-
};
1+
({
2+
access: 'public',
3+
method: async ({ login, password }) => {
4+
const user = await application.auth.getUser(login);
5+
const hash = user ? user.password : undefined;
6+
const valid = await application.security.validatePassword(password, hash);
7+
if (!user || !valid) throw new Error('Incorrect login or password');
8+
console.log(`Logged user: ${login}`);
9+
return { result: 'success', userId: user.id };
10+
}
11+
});

lib/application.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ class Application extends events.EventEmitter {
4848
}
4949

5050
async createScript(fileName) {
51-
const code = await fsp.readFile(fileName, 'utf8');
51+
const data = await fsp.readFile(fileName, 'utf8');
52+
const code = data.startsWith('({') ? data :
53+
`({ access: 'logged', method: ${data.trim().slice(0, -1)} });`;
5254
const src = `'use strict';\ncontext => ${code}`;
5355
const options = { filename: fileName, lineOffset: -1 };
5456
try {

lib/server.js

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,26 @@ class Client {
8080
const { req, res } = this;
8181
const { url } = req;
8282
const ip = req.connection.remoteAddress;
83-
const method = url.substring(METHOD_OFFSET);
83+
const name = url.substring(METHOD_OFFSET);
8484
const session = await this.application.auth.restore(req);
85-
if (!session && method !== 'signIn') {
86-
this.application.logger.error(`Forbidden ${url}`);
87-
this.error(403);
88-
semaphore.leave();
89-
return;
90-
}
9185
const args = await receiveArgs(req);
9286
const sandbox = session ? session.sandbox : undefined;
9387
const context = session ? session.context : {};
9488
try {
95-
const proc = this.application.runScript(method, sandbox);
96-
const result = await proc(context)(args);
89+
const exp = this.application.runScript(name, sandbox);
90+
const { method, access } = exp(context);
91+
if (!session && access !== 'public') {
92+
this.application.logger.error(`Forbidden ${url}`);
93+
this.error(403);
94+
semaphore.leave();
95+
return;
96+
}
97+
const result = await method(args);
9798
if (res.finished) {
9899
semaphore.leave();
99100
return;
100101
}
101-
if (method === 'signIn') {
102+
if (!session && access === 'public') {
102103
const session = this.application.auth.start(req, ip, result.userId);
103104
res.setHeader('Set-Cookie', session.cookie);
104105
}
@@ -151,19 +152,20 @@ const apiws = (application, connection, req) => async message => {
151152
}
152153
try {
153154
const ip = req.connection.remoteAddress;
154-
const { method, args } = JSON.parse(message);
155+
const { method: name, args } = JSON.parse(message);
155156
const session = await application.auth.restore(req);
156-
if (!session && method !== 'signIn') {
157-
application.logger.error(`Forbidden: ${method}`);
157+
const sandbox = session ? session.sandbox : undefined;
158+
const context = session ? session.context : {};
159+
const exp = application.runScript(name, sandbox);
160+
const { method, access } = exp(context);
161+
if (!session && access !== 'public') {
162+
application.logger.error(`Forbidden: ${name}`);
158163
send({ result: 'error', reason: 'forbidden' });
159164
semaphore.leave();
160165
return;
161166
}
162-
const sandbox = session ? session.sandbox : undefined;
163-
const context = session ? session.context : {};
164-
const proc = application.runScript(method, sandbox);
165-
const result = await proc(context)(args);
166-
if (method === 'signIn') {
167+
const result = await method(args);
168+
if (!session && access === 'public') {
167169
const session = application.auth.start(req, ip, result.userId);
168170
result.token = session.cookie;
169171
}

0 commit comments

Comments
 (0)