From 810d1e6bfcef701b70c2ee4a56a5476483b79470 Mon Sep 17 00:00:00 2001 From: Philippe PITTOLI Date: Wed, 18 Dec 2019 11:47:24 +0100 Subject: [PATCH] First messages exchanged, tokens are cleartext for now. --- src/client.cr | 35 +++++++++++++++++ src/colors.cr | 5 +++ src/common.cr | 34 +++++++++++++++++ src/json_tests.cr | 14 +++++++ src/main.cr | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 185 insertions(+) create mode 100644 src/client.cr create mode 100644 src/colors.cr create mode 100644 src/common.cr create mode 100644 src/json_tests.cr create mode 100644 src/main.cr diff --git a/src/client.cr b/src/client.cr new file mode 100644 index 0000000..631a8f1 --- /dev/null +++ b/src/client.cr @@ -0,0 +1,35 @@ +require "ipc" +require "json" + +require "./common.cr" + +client = IPC::Client.new("pong") + +token = Token.new 1002, "karchnu" +authentication_message = AuthenticationMessage.new token + +client.send(1.to_u8, authentication_message.to_json) + +m = client.read +# puts "message received: #{m.to_s}" +# puts "message received payload: #{String.new m.payload}" + +response = Response.from_json(String.new m.payload) + +if response.mid == authentication_message.mid + puts "This is a response for the authentication message" +else + puts "Message IDs from authentication message and its response differ" +end + +client.close + +#client.loop do |event| +# case event +# when IPC::Event::Message +# puts "\033[32mthere is a message\033[00m" +# puts event.message.to_s +# client.close +# exit +# end +#end diff --git a/src/colors.cr b/src/colors.cr new file mode 100644 index 0000000..4c4d49c --- /dev/null +++ b/src/colors.cr @@ -0,0 +1,5 @@ +CRED = "\033[31m" +CBLUE = "\033[36m" +CGREEN = "\033[32m" +CRESET = "\033[00m" +CORANGE = "\033[33m" diff --git a/src/common.cr b/src/common.cr new file mode 100644 index 0000000..71f0ebb --- /dev/null +++ b/src/common.cr @@ -0,0 +1,34 @@ + +require "uuid" + +class Token + JSON.mapping({ + uid: Int32, + login: String + }) + + def initialize(@uid, @login) + end +end + +class AuthenticationMessage + JSON.mapping({ + mid: String, + token: Token + }) + + def initialize(@token) + @mid = UUID.random.to_s + end +end + +class Response + JSON.mapping({ + mid: String, + response: String, + reason: String? + }) + + def initialize(@mid, @response, @reason = nil) + end +end diff --git a/src/json_tests.cr b/src/json_tests.cr new file mode 100644 index 0000000..0056f15 --- /dev/null +++ b/src/json_tests.cr @@ -0,0 +1,14 @@ +require "json" + +require "./common.cr" + + +token = Token.new 1002, "karchnu" +authentication_message = AuthenticationMessage.new token + +# TODO, TEST, DEBUG, XXX, FIXME +pp! authentication_message.to_json + +am_from_json = AuthenticationMessage.from_json authentication_message.to_json + +pp! am_from_json diff --git a/src/main.cr b/src/main.cr new file mode 100644 index 0000000..9d10362 --- /dev/null +++ b/src/main.cr @@ -0,0 +1,97 @@ +require "option_parser" +require "ipc" +require "json" + +require "./colors" + +require "./common.cr" + +storage_directory = "./storage" +service_name = "filestorage" + + +OptionParser.parse do |parser| + parser.on "-d storage-directory", + "--storage-directory storage-directory", + "The directory where to put uploaded files." do |opt| + storage_directory = opt + end + + parser.on "-s service-name", "--service-name service-name", "Service name." do |name| + service_name = name + end + + parser.on "-h", "--help", "Show this help" do + puts parser + exit 0 + end +end + + +# keep track of connected users +class User + property token : Token + def initialize(@token) + end +end + +# list of connected users +# fd => User +connected_users = Hash(Int32, User).new + +service = IPC::SwitchingService.new service_name + +service.loop do |event| + case event + when IPC::Event::Timer + puts "#{CORANGE}IPC::Event::Timer#{CRESET}" + + # puts "Disconnected client is: #{client_name}" + + when IPC::Event::Connection + puts "#{CBLUE}IPC::Event::Connection: #{event.connection.fd}#{CRESET}" + + when IPC::Event::Disconnection + puts "#{CBLUE}IPC::Event::Disconnection: #{event.connection.fd}#{CRESET}" + + connected_users.select! do |fd, user| + fd != event.connection.fd + end + + when IPC::Event::ExtraSocket + puts "#{CRED}IPC::Event::ExtraSocket: should not happen in this service#{CRESET}" + + when IPC::Event::Switch + puts "#{CRED}IPC::Event::Switch: should not happen in this service#{CRESET}" + + # IPC::Event::Message has to be the last entry + # because ExtraSocket and Switch inherit from Message class + when IPC::Event::Message + puts "#{CBLUE}IPC::Event::Message#{CRESET}: #{event.connection.fd}" + + # 1. test if the client is already authenticated + if user = connected_users[event.connection.fd]? + puts "User is connected: #{user.token.login}" + else + puts "User is not currently connected" + + authentication_message = AuthenticationMessage.from_json(String.new event.message.payload) + + new_user = User.new authentication_message.token + connected_users[event.connection.fd] = new_user + puts "New user is: #{new_user.token.login}" + + response = Response.new authentication_message.mid, "Ok" + event.connection.send 2.to_u8, response.to_json + end + + + # puts "New connected client is: #{client_name}" + + # The first message is the connection. + # Users sent their token (JWT) to authenticate. + # From the token, we get the user id, its login and a few other parameters (see the authd documentation). + else + raise "Event type not supported." + end +end