module SimpleTelnetServer::HasLogin
Adds functionality for simple authentication and authorization.
By default, login credentials are defined right in the class definition using {ClassMethods::has_login}. If something more dynamic is needed, just override {#authenticate}.
After authentication, {#entered_username}, {#entered_password}, and {#authorized_role} are set.
Attributes
@return [String] the password username
@return [String] the entered username @note This doesn’t necessarily mean the user is logged in. Use
{#authorized?} to check for that.
Public Class Methods
Extends klass with {ClassMethods}.
# File lib/em-simple_telnet_server/has_login.rb, line 11 def self.included(klass) klass.extend ClassMethods end
Public Instance Methods
Checks user and pass against all known login credentials.
@param user [String] entered username @param pass [String] entered password @return [Symbol] associated role, if credentials are known @return [nil] if credentials are not known
# File lib/em-simple_telnet_server/has_login.rb, line 134 def authenticate(user, pass) self.class.login_credentials.each do |role, credentials| return role if credentials == [ user, pass ] end return nil end
Initiates authentication. This means setting the connection state to waiting_for_username
and sending the login prompt.
# File lib/em-simple_telnet_server/has_login.rb, line 50 def initiate_authentication @connection_state = :waiting_for_username send_login_prompt end
@return [true] true, as this module is about authentication
# File lib/em-simple_telnet_server/has_login.rb, line 44 def needs_authentication? true end
If the user was requested to enter his username, the username is read. If the user was requested to enter his password, the password is read.
Otherwise, the normal (super
) behavior proceeds.
In all cases, it ensures that the buffer is cleared at the end.
# File lib/em-simple_telnet_server/has_login.rb, line 62 def process_buffer if waiting_for_username? read_username_from_buffer elsif waiting_for_password? read_password_from_buffer else super end ensure @buffer.clear end
Reads the password from buffer and authorizes the user if he can be authenticated. Otherwise the connection state is set back to :waiting_for_username
and the login prompt is sent.
# File lib/em-simple_telnet_server/has_login.rb, line 100 def read_password_from_buffer @entered_password = @buffer.chomp if role = authenticate(@entered_username, @entered_password) @authorized_role = role authorize else @connection_state = :waiting_for_username @entered_username = @entered_password = nil send_login_failed send_login_prompt end end
Reads the username from buffer. Sends the password prompt afterwards ({#send_password_prompt}) and sets the connection state to :waiting_for_password
.
# File lib/em-simple_telnet_server/has_login.rb, line 116 def read_username_from_buffer @entered_username = @buffer.strip send_password_prompt @connection_state = :waiting_for_password end
Sends the message “Sorry, please try again.” and the login prompt.
# File lib/em-simple_telnet_server/has_login.rb, line 123 def send_login_failed send_data "Sorry, please try again.\n" end
Sends the login prompt.
# File lib/em-simple_telnet_server/has_login.rb, line 77 def send_login_prompt send_data options[:login_prompt] end
Sends the password prompt.
# File lib/em-simple_telnet_server/has_login.rb, line 82 def send_password_prompt send_data options[:password_prompt] end
@return [Boolean] whether we are waiting for the user to enter the password
# File lib/em-simple_telnet_server/has_login.rb, line 92 def waiting_for_password? @connection_state == :waiting_for_password end
@return [Boolean] whether we are waiting for the user to enter the username
# File lib/em-simple_telnet_server/has_login.rb, line 87 def waiting_for_username? @connection_state == :waiting_for_username end