lib/redfish_client/root.rb in redfish_client-0.4.1 vs lib/redfish_client/root.rb in redfish_client-0.5.0

- old
+ new

@@ -1,53 +1,16 @@ # frozen_string_literal: true -require "base64" -require "json" require "server_sent_events" require "redfish_client/event_listener" require "redfish_client/resource" module RedfishClient # Root resource represents toplevel entry point into Redfish service data. # Its main purpose is to provide authentication support for the API. class Root < Resource - # AuthError is raised if the user session cannot be created. - class AuthError < StandardError; end - - # Basic and token authentication headers. - BASIC_AUTH_HEADER = "Authorization" - TOKEN_AUTH_HEADER = "X-Auth-Token" - - # Authenticate against the service. - # - # Calling this method will try to create new session on the service using - # provided credentials. If the session creation fails, basic - # authentication will be attempted. If basic authentication fails, - # {AuthError} will be raised. - # - # @param username [String] username - # @param password [String] password - # @raise [AuthError] if user session could not be created - def login(username, password) - # Since session auth is more secure, we try it first and use basic auth - # only if session auth is not available. - if session_login_available? - session_login(username, password) - else - basic_login(username, password) - end - end - - # Sign out of the service. - # - # If the session could not be deleted, {AuthError} will be raised. - def logout - session_logout - basic_logout - end - # Find Redfish service object by OData ID field. # # @param oid [String] Odata id of the resource # @return [Resource, nil] new resource or nil if resource cannot be found def find(oid) @@ -75,49 +38,40 @@ return nil if address.nil? EventListener.new(ServerSentEvents.create_client(address)) end - private - - def session_login_available? - !@content.dig("Links", "Sessions").nil? - end - - def session_login(username, password) - r = @connector.post( - @content["Links"]["Sessions"]["@odata.id"], - "UserName" => username, "Password" => password + # Authenticate against the service. + # + # Calling this method will select the appropriate method of authentication + # and try to login using provided credentials. + # + # @param username [String] username + # @param password [String] password + # @raise [RedfishClient::AuthenticatedConnector::AuthError] if user + # session could not be authenticated + def login(username, password) + @connector.set_auth_info( + username, password, auth_test_path, session_path ) - raise AuthError, "Invalid credentials" unless r.status == 201 - - session_logout - - payload = r.data[:headers][TOKEN_AUTH_HEADER] - @connector.add_headers(TOKEN_AUTH_HEADER => payload) - @session = Resource.new(@connector, content: JSON.parse(r.data[:body])) + @connector.login end - def session_logout - return unless @session - r = @session.delete - raise AuthError unless r.status == 204 - @session = nil - @connector.remove_headers([TOKEN_AUTH_HEADER]) + # Sign out of the service. + def logout + @connector.logout end - def auth_test_path - @content.values.map { |v| v["@odata.id"] }.compact.first - end + private - def basic_login(username, password) - payload = Base64.encode64("#{username}:#{password}").strip - @connector.add_headers(BASIC_AUTH_HEADER => "Basic #{payload}") - r = @connector.get(auth_test_path) - raise AuthError, "Invalid credentials" unless r.status == 200 + def session_path + # We access raw values here on purpose, since calling dig on resource + # instance would try to download the sessions collection, which would + # fail since we are not yet logged in. + raw.dig("Links", "Sessions", "@odata.id") end - def basic_logout - @connector.remove_headers([BASIC_AUTH_HEADER]) + def auth_test_path + raw.values.find { |v| v["@odata.id"] }["@odata.id"] end end end