1 
2 module mars.protoauth;
3 
4 import std.algorithm;
5 import std.ascii;
6 import std.random;
7 import std.range;
8 import std.digest.sha;
9 import std.string;
10 import std.experimental.logger;
11 import vibe.core.log;
12 
13 import mars.msg;
14 import mars.client;
15 import mars.server;
16 
17 void protoAuth(S)(MarsClient* client, S socket)
18 {
19     import msgpack : unpack, pack;
20 
21     auto authenticationRequest = socket.binaryAs!AuthenticationRequest;
22     string username = authenticationRequest.username;
23 
24     // empty username, not allowed ...
25     if( username == "" ){
26         socket.sendReply(authenticationRequest, AuthenticationReply(AuthenticationReply.invalidUsername));
27         return;
28     }
29 
30     auto seed = letters.length
31         .iota
32         .randomSample(10)
33         .map!( i => letters[i] )
34         .array;
35     socket.sendReply(authenticationRequest, AuthenticationReply(AuthenticationReply.seedProvided, seed));
36     auto authenticateRequest = socket.receiveMsg!AuthenticateRequest;
37     logInfo("S <-- C | authenticate request, hash:%s", authenticateRequest.hash);
38 
39     // ... right now, we can't pass the hash to postgres, so ...
40     string hash256, password = "password";
41     if     ( username == "dev"    ){ password = "password"; }
42     else if( username == "pinver" ){ password = "arathorn"; }
43     else if( username == "elisa"  ){ password = "seta"; }
44     else if( username == "chiara" ){ password = "velluto"; }
45 
46     bool authorised = authenticateRequest.hash.toUpper() == sha256Of(seed ~ sha256Of(password).toHexString()).toHexString();
47 
48     AuthoriseError dbAuthorised = client.authoriseUser(username, password);
49 
50     auto reply = AuthenticateReply(cast(int)dbAuthorised, "", []);
51 
52     if( dbAuthorised == AuthoriseError.authorised ){
53         reply.sqlCreateDatabase = marsServer.configuration.alasqlCreateDatabase;
54         reply.sqlStatements = marsServer.configuration.alasqlStatements;
55 
56         // ... now that the client is authorised, expose the data to it
57         marsServer.createClientSideTablesFor(client);
58     }
59 
60     logInfo("S --> C | authenticate reply, authorised:%s", dbAuthorised);
61     socket.sendReply(authenticateRequest, reply);
62 
63     // ... try the push from the server, a new client has connected ...
64     //if(dbAuthorised == AuthoriseError.authorised) marsServer.broadcast(WelcomeBroadcast(username));
65 }
66 
67 void protoDeauth(S)(MarsClient* client, S socket)
68 {
69     auto request = socket.binaryAs!DiscardAuthenticationRequest;
70     client.discardAuthorisation();
71     auto reply = DiscardAuthenticationReply();
72     socket.sendReply(request, reply);
73 
74     //marsServer.broadcast(GoodbyBroadcast("theusename"));
75 }
76 
77 struct WelcomeBroadcast { static immutable type = MsgType.welcomeBroadcast; string username; }
78 struct GoodbyBroadcast { static immutable type = MsgType.goodbyBroadcast; string username; }