Class: ApceraAuth

Inherits:
Object
  • Object
show all
Defined in:
lib/apcera_api_gem.rb,
lib/apcera_api_helper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target = "", bearer = "") ⇒ ApceraAuth

Returns a new instance of ApceraAuth.



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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/apcera_api_gem.rb', line 46

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"
    
      # This can also be set in the environment
      #
      if ENV.key?("APC_TARGET")
        puts "WARNING: Using APC_TARGET from ENV"
        value = ENV["APC_TARGET"]
      else
        value = prompt_for_value("Enter the domain name for the cluster [#{default}] : ").delete!("\n")
      end

      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}"
  @auth_host = "auth.#{@domain}"
  @base_api_url = "#{scheme}://#{@api_host}"
  @base_auth_url = "#{scheme}://#{@auth_host}"
  
  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)

      ApceraApi.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
        ApceraApi.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" }
      refresh_resp = RestClient.post(refresh_url, refresh_token_wrapper.to_json, {:content_type => :json})
      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

Instance Attribute Details

#api_hostObject (readonly)

Returns the value of attribute api_host.



37
38
39
# File 'lib/apcera_api_gem.rb', line 37

def api_host
  @api_host
end

#auth_hostObject (readonly)

Returns the value of attribute auth_host.



38
39
40
# File 'lib/apcera_api_gem.rb', line 38

def auth_host
  @auth_host
end

#base_api_urlObject (readonly)

Returns the value of attribute base_api_url.



39
40
41
# File 'lib/apcera_api_gem.rb', line 39

def base_api_url
  @base_api_url
end

#base_auth_urlObject (readonly)

Returns the value of attribute base_auth_url.



40
41
42
# File 'lib/apcera_api_gem.rb', line 40

def base_auth_url
  @base_auth_url
end

#bearerObject (readonly)

Returns the value of attribute bearer.



29
30
31
# File 'lib/apcera_api_gem.rb', line 29

def bearer
  @bearer
end

#cache_file_pathObject (readonly)

This is situational



44
45
46
# File 'lib/apcera_api_gem.rb', line 44

def cache_file_path
  @cache_file_path
end

#domainObject (readonly)

Returns the value of attribute domain.



35
36
37
# File 'lib/apcera_api_gem.rb', line 35

def domain
  @domain
end

#schemeObject (readonly)

Returns the value of attribute scheme.



36
37
38
# File 'lib/apcera_api_gem.rb', line 36

def scheme
  @scheme
end

#targetObject (readonly)

These are the bare minimum



28
29
30
# File 'lib/apcera_api_gem.rb', line 28

def target
  @target
end

#tokenObject (readonly)

These are calculated from the above



33
34
35
# File 'lib/apcera_api_gem.rb', line 33

def token
  @token
end

#token_prefixObject (readonly)

Returns the value of attribute token_prefix.



34
35
36
# File 'lib/apcera_api_gem.rb', line 34

def token_prefix
  @token_prefix
end

Instance Method Details

#prompt_for_value(*args) ⇒ Object



169
170
171
172
# File 'lib/apcera_api_gem.rb', line 169

def prompt_for_value(*args)
    print(*args)
    gets
end

#to_sObject



174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/apcera_api_gem.rb', line 174

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