class ApceraAuth

Attributes

api_host[R]
auth_host[R]
base_api_url[R]
base_auth_url[R]
bearer[R]
cache_file_path[R]

This is situational

domain[R]
scheme[R]
target[R]

Want to update this to check for HTTP_URI. If that is set, don't do ANY auth.

These are the bare minimum

token[R]

These are calculated from the above

token_prefix[R]

Public Class Methods

new(target = "", bearer = "") click to toggle source
# File lib/apcera_api_helper.rb, line 47
def initialize(target = "", bearer = "")
        # If a target or bearer is passed in, use that, otherwise, try to figure it out
        #
        cache_credentials = false
        
        if (target.nonblank? || bearer.nonblank?)
                @target = target
                @bearer = bearer
        else
                cache_credentials = true
                
                @cache_file_path = File.expand_path("~/.apcera_api")

                if !File.writable?(File.expand_path("~/"))
                        puts "Cache File #{@cache_file_path} not writable, falling back to tmp"
                        @cache_file_path = "/tmp/.apcera_api"
                end
                
                cached_fields = {}
                if (File.exists?(@cache_file_path))
                        cached_fields = JSON.parse(File.read(@cache_file_path))
                end
        
                # First, get the target.  If it isn't in the cache or env, prompt for it
                #
                if (!cached_fields.has_key?("target") || cached_fields["target"] == "")
                
                        default = "http://demo.proveapcera.io"
                
                        value = prompt_for_value("Enter the domain name for the cluster [#{default}] : ").delete!("\n")

                        if value == ""
                                value = default
                        end
                        cached_fields["target"] = value
                end
                
                # Just need to make sure that these are set when done
                #
                @target = cached_fields["target"]
        end

        # Build the paths
        #
        parts = @target.split(/[:\/]/)

        @scheme = parts.first
        @domain = parts.last

        @api_host = "api.#{@domain}"
        
        # Have to be running against a 2.x cluster or later for this to work.  Older
        # Clusters want the auth host to be "auth.xxx" not or "gauth.xxx"
        #
        @auth_host = "gauth.#{@domain}"
        @base_api_url = "#{scheme}://#{@api_host}"
        
        @base_auth_url = "#{scheme}://#{@auth_host}"
        
        # if the $HTTP_URI is set then we are in app_token mode, and auth is done.
        #
        if (ENV.key?("HTTP_URI"))
                puts "HTTP_URI is set [#{ENV.key("HTTP_URI")}], app_token mode"
                return
        end
        
        if (target.nonblank? || bearer.nonblank?)
                @bearer = bearer
        else
                # We need to find it.
                #
                if (ENV.key?("APC_REFRESH_TOKEN"))
                        puts "WARNING: Using refresh token from environment"
                        cached_fields["refresh_token"] = ENV["APC_REFRESH_TOKEN"]
                end

                if (!cached_fields.has_key?("refresh_token") || cached_fields["refresh_token"] == "")
                        response = RestClient.get("#{@base_auth_url}/v1/oauth2/device/google/getcode")
                        code = JSON.parse(response)

                        ApceraApiHelper.notice "go to \n\n#{code['verification_url']}\n\n and enter code #{code['user_code']}\n\n"
        
                        # This stuff only works on the mac
                        #
                        system("echo #{code['user_code']} | pbcopy")
                        system("open #{code['verification_url']}")

                        value = prompt_for_value "Press Y when completed: "

                        if value.delete!("\n").casecmp("Y") != 0
                                ApceraApiHelper.notice "Error, giving up."
                                exit
                        end

                        device_code = code['device_code']

                        redeemed_url = "#{@base_auth_url}/v1/oauth2/device/google/redeemed"

                        obj = {:device_code => device_code}

                        refresh_token_wrapper = JSON.parse(RestClient.post(redeemed_url, obj.to_json, {:content_type => :json}))
                        cached_fields["refresh_token"] = refresh_token_wrapper["refresh_token"]
                end  
                
                # If the token isn't there, or is expired, refresh it
                #
                if !cached_fields.has_key?("token") || cached_fields["token"] == "" || Time.parse(cached_fields["expires"]) < Time.now
                        refresh_url = "#{@base_auth_url}/v1/oauth2/device/google/refresh"

                        refresh_token_wrapper = {:refresh_token => cached_fields["refresh_token"], :token_type => "GOOGLE_REFRESH" }
                        begin
                                refresh_resp = RestClient.post(refresh_url, refresh_token_wrapper.to_json, {:content_type => :json})
                        rescue Exception => e
                                refresh_resp = RestClient.post(refresh_url, refresh_token_wrapper.to_json, {:content_type => 'application/json'})
                        end
                        
                        refreshed_token = JSON.parse(refresh_resp)
                        
                        cached_fields["token"] = "Bearer #{refreshed_token['access_token']}"
                        cached_fields["expires"] = Time.now + refreshed_token["expires_in"].to_i                    
                end
                @bearer = cached_fields["token"]                     
        end
        
        @token_prefix = @bearer.split.first
        @token = @bearer.split.last

        if (cache_credentials)        
                File.write(cache_file_path, JSON.pretty_generate(cached_fields))
        end

end

Public Instance Methods

prompt_for_value(*args) click to toggle source
# File lib/apcera_api_helper.rb, line 180
def prompt_for_value(*args)
    print(*args)
    gets
end
to_s() click to toggle source
# File lib/apcera_api_helper.rb, line 185
def to_s
        body  = "target            [#{@target}]\n"
        body += "bearer            [#{@bearer}]\n"
        body += "token             [#{@token}]\n"
        body += "token_prefix      [#{@token_prefix}]\n"
        body += "domain            [#{@domain}]\n"
        body += "scheme            [#{@scheme}]\n"
        body += "api_host          [#{@api_host}]\n"
        body += "auth_host         [#{@auth_host}]\n"
        body += "base_api_url      [#{@base_api_url}]\n"
        body += "base_auth_url     [#{@base_auth_url}]\n"
        body += "cache_file_path   [#{@cache_file_path}]\n"
end