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 22 auto authenticationRequest = socket.binaryAs!AuthenticationRequest; 23 string username = authenticationRequest.username; 24 25 // reject multiple authentication request ... 26 if( client.authorised ){ 27 socket.sendReply(authenticationRequest, AuthenticationReply(AuthenticationReply.alreadyAuthorised)); 28 return; 29 } 30 31 // empty username, not allowed ... 32 if( username == "" ){ 33 socket.sendReply(authenticationRequest, AuthenticationReply(AuthenticationReply.invalidUsername)); 34 return; 35 } 36 37 38 auto seed = letters.length 39 .iota 40 .randomSample(10) 41 .map!( i => letters[i] ) 42 .array; 43 socket.sendReply(authenticationRequest, AuthenticationReply(AuthenticationReply.seedProvided, seed)); 44 auto authenticateRequest = socket.receiveMsg!AuthenticateRequest; 45 logInfo("S <-- %s | authenticate request, hash:%s", client.id, authenticateRequest.hash); 46 47 // ... right now, we can't pass the hash to postgres, so ... 48 string hash256, password = "password"; 49 if ( username == "dev" ){ password = "password"; } 50 else if( username == "pinver" ){ password = "arathorn"; } 51 else if( username == "elisa" ){ password = "seta"; } 52 else if( username == "chiara" ){ password = "velluto"; } 53 else if( username == "a.liu" ){ password = "2tuxeSeseswa"; } 54 55 bool authorised = authenticateRequest.hash.toUpper() == sha256Of(seed ~ sha256Of(password).toHexString()).toHexString(); 56 if(authorised){ 57 AuthoriseError dbAuthorised = client.authoriseUser(username, password) ; 58 59 auto reply = AuthenticateReply(cast(int)dbAuthorised, "", []); 60 61 if( dbAuthorised == AuthoriseError.authorised ){ 62 reply.sqlCreateDatabase = marsServer.configuration.alasqlCreateDatabase; 63 reply.sqlStatements = marsServer.configuration.alasqlStatements; 64 reply.jsStatements = marsServer.configuration.jsStatements; 65 66 // ... now that the client is authorised, expose the data to it 67 marsServer.createClientSideTablesFor(client); 68 } 69 70 logInfo("S --> %s | authenticate reply, authorised:%s", client.id, dbAuthorised); 71 socket.sendReply(authenticateRequest, reply); 72 } 73 else { 74 logInfo("S --> %s | authenticate reply, authorised:%s (web password hash failed)", client.id, false); 75 auto reply = AuthenticateReply(cast(int)AuthoriseError.wrongUsernameOrPassword, "", []); 76 socket.sendReply(authenticateRequest, reply); 77 } 78 79 // ... try the push from the server, a new client has connected ... 80 //if(dbAuthorised == AuthoriseError.authorised) marsServer.broadcast(WelcomeBroadcast(username)); 81 } 82 83 void protoDeauth(S)(MarsClient* client, S socket) 84 { 85 marsServer.wipeClientSideTablesFor(client); 86 auto request = socket.binaryAs!DiscardAuthenticationRequest; 87 client.discardAuthorisation(); 88 auto reply = DiscardAuthenticationReply(); 89 socket.sendReply(request, reply); 90 91 //marsServer.broadcast(GoodbyBroadcast("theusename")); 92 } 93 94 struct WelcomeBroadcast { static immutable type = MsgType.welcomeBroadcast; string username; } 95 struct GoodbyBroadcast { static immutable type = MsgType.goodbyBroadcast; string username; }