Class: RBus::Auth::StateMachine
- Inherits:
-
Object
- Object
- RBus::Auth::StateMachine
- Defined in:
- lib/rbus/auth/state_machine.rb
Overview
Implements a statemachine for Authorization like the one described in the D-Bus specification.
Instance Method Summary collapse
-
#authorize ⇒ Object
Main entry point, returns guid if succesful, or raises otherwise.
-
#hex_encode(plain) ⇒ Object
Server expects all data to be encoded in hex.
-
#initialize(transport) ⇒ StateMachine
constructor
A new instance of StateMachine.
-
#method_missing(symbol, *args) ⇒ Object
send_begin => BEGIN, etc.
-
#next_mechanism(data) ⇒ Object
Move to next mechanism.
-
#populate_mechanisms(data) ⇒ Object
Build initial mechanism list.
-
#send_auth(command, data) ⇒ Object
Send AUTH …
Constructor Details
#initialize(transport) ⇒ StateMachine
Returns a new instance of StateMachine.
30 31 32 33 |
# File 'lib/rbus/auth/state_machine.rb', line 30 def initialize(transport) @transport = transport @mechanism = FIRST_MECHANISM.new end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args) ⇒ Object
send_begin => BEGIN, etc
139 140 141 142 143 144 145 |
# File 'lib/rbus/auth/state_machine.rb', line 139 def method_missing(symbol, *args) command = symbol.to_s if command.sub!('send_', '') line = [command.upcase, hex_encode(args[0])].compact.join(' ') @transport.sendline(line) end end |
Instance Method Details
#authorize ⇒ Object
Main entry point, returns guid if succesful, or raises otherwise.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/rbus/auth/state_machine.rb', line 36 def state = :AUTH loop do case state when :AUTH command, data, state = @mechanism.auth send_auth(command, data) when :REJECTED response = Command.new(@transport.readline) case response.command when 'REJECTED' next_mechanism(response.data) state = :AUTH else raise AuthException end when :OK response = Command.new(@transport.readline) case response.command when 'OK' send_begin return response.data when 'REJECTED' next_mechanism(response.data) state = :AUTH when 'DATA' send_cancel state = :REJECTED when 'ERROR' send_cancel state = :REJECTED else send_error state = :OK end when :DATA response = Command.new(@transport.readline) case response.command when 'DATA' begin , state = @mechanism.data(response.data) rescue AuthException => e send_cancel state = :REJECTED else send_data() end when 'REJECTED' next_mechanism(response.data) state = :AUTH when 'ERROR' send_cancel state = :REJECTED when 'OK' send_begin return response.data else send_error state = :DATA end else raise end end end |
#hex_encode(plain) ⇒ Object
Server expects all data to be encoded in hex
148 149 150 151 |
# File 'lib/rbus/auth/state_machine.rb', line 148 def hex_encode(plain) return nil if plain.nil? plain.to_s.unpack('H*')[0] end |
#next_mechanism(data) ⇒ Object
Move to next mechanism
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/rbus/auth/state_machine.rb', line 107 def next_mechanism(data) if @mechanisms.nil? populate_mechanisms(data) end if @mechanisms.empty? raise AuthException else @mechanism = @mechanisms.shift.new end end |
#populate_mechanisms(data) ⇒ Object
Build initial mechanism list
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/rbus/auth/state_machine.rb', line 119 def populate_mechanisms(data) server_mechanisms = data.split(' ') # Find common mechanisms, or try them all if server didn't tell us if server_mechanisms.empty? mechanisms = MECHANISMS.keys else mechanisms = (server_mechanisms & MECHANISMS.keys) end @mechanisms = mechanisms.map{|name| MECHANISMS[name]} end |
#send_auth(command, data) ⇒ Object
Send AUTH …
133 134 135 136 |
# File 'lib/rbus/auth/state_machine.rb', line 133 def send_auth(command, data) line = ['AUTH', command, hex_encode(data)].compact.join(' ') @transport.sendline(line) end |