Class: Canvas::API

Inherits:
Object
  • Object
show all
Defined in:
lib/canvas-api.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ API

Returns a new instance of API.



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/canvas-api.rb', line 8

def initialize(args={}) 
  @host = args[:host] && args[:host].to_s
  @token = args[:token] && args[:token].to_s
  @client_id = args[:client_id] && args[:client_id].to_s
  @secret = args[:secret] && args[:secret].to_s
  raise "host required" unless @host
  raise "invalid host, protocol required" unless @host.match(/^http/)
  raise "invalid host" unless @host.match(/^https?:\/\/[^\/]+$/)
  raise "token or client_id required" if !@token && !@client_id
  raise "secret required for client_id configuration" if @client_id && !@secret
end

Instance Attribute Details

#client_idObject

Returns the value of attribute client_id.



22
23
24
# File 'lib/canvas-api.rb', line 22

def client_id
  @client_id
end

#hostObject

Returns the value of attribute host.



20
21
22
# File 'lib/canvas-api.rb', line 20

def host
  @host
end

#tokenObject

Returns the value of attribute token.



21
22
23
# File 'lib/canvas-api.rb', line 21

def token
  @token
end

Class Method Details

.encode_id(prefix, id) ⇒ Object



32
33
34
35
# File 'lib/canvas-api.rb', line 32

def self.encode_id(prefix, id)
  return nil unless prefix && id
  "hex:#{prefix}:" + id.to_s.unpack("H*")[0]
end

Instance Method Details

#delete(endpoint) ⇒ Object



130
131
132
133
134
# File 'lib/canvas-api.rb', line 130

def delete(endpoint)
  generate_uri(endpoint)
  request = Net::HTTP::Delete.new(@uri.request_uri)
  retrieve_response(request)
end

#encode_id(prefix, id) ⇒ Object



37
38
39
# File 'lib/canvas-api.rb', line 37

def encode_id(prefix, id)
  Canvas::API.encode_id(prefix, id)
end

#generate_uri(endpoint) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/canvas-api.rb', line 82

def generate_uri(endpoint)
  validate_call(endpoint)
  unless @token == "ignore"
    endpoint += (endpoint.match(/\?/) ? "&" : "?") + "access_token=" + @token
    endpoint += "&as_user_id=" + @as_user_id.to_s if @as_user_id
  end
  @uri = URI.parse(@host + endpoint)
  @http = Net::HTTP.new(@uri.host, @uri.port)
  @http.use_ssl = @uri.scheme == 'https'
  @uri
end

#get(endpoint) ⇒ Object



124
125
126
127
128
# File 'lib/canvas-api.rb', line 124

def get(endpoint)
  generate_uri(endpoint)
  request = get_request(endpoint)
  retrieve_response(request)
end

#get_request(endpoint) ⇒ Object

Semi-hack so I can write better specs



120
121
122
# File 'lib/canvas-api.rb', line 120

def get_request(endpoint)
  Net::HTTP::Get.new(@uri.request_uri)
end

#login_url(callback_url) ⇒ Object



51
52
53
# File 'lib/canvas-api.rb', line 51

def (callback_url)
  oauth_url(callback_url, "/auth/userinfo")
end

#logoutObject



69
70
71
# File 'lib/canvas-api.rb', line 69

def logout
  !!delete("/login/oauth2/token")['logged_out']
end

#masquerade_as(user_id) ⇒ Object



24
25
26
# File 'lib/canvas-api.rb', line 24

def masquerade_as(user_id)
  @as_user_id = user_id && user_id.to_s
end

#oauth_url(callback_url, scopes = "") ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/canvas-api.rb', line 41

def oauth_url(callback_url, scopes="")
  raise "client_id required for oauth flow" unless @client_id
  raise "secret required for oauth flow" unless @secret
  raise "callback_url required" unless callback_url
  raise "invalid callback_url" unless (URI.parse(callback_url) rescue nil)
  scopes ||= ""
  scopes = scopes.length > 0 ? "&scopes=#{CGI.escape(scopes)}" : ""
  "#{@host}/login/oauth2/auth?client_id=#{@client_id}&response_type=code&redirect_uri=#{CGI.escape(callback_url)}#{scopes}"
end

#post(endpoint, params = {}) ⇒ Object



143
144
145
146
147
148
# File 'lib/canvas-api.rb', line 143

def post(endpoint, params={})
  generate_uri(endpoint)
  request = Net::HTTP::Post.new(@uri.request_uri)
  request.set_form_data(params)
  retrieve_response(request)
end

#put(endpoint, params = {}) ⇒ Object



136
137
138
139
140
141
# File 'lib/canvas-api.rb', line 136

def put(endpoint, params={})
  generate_uri(endpoint)
  request = Net::HTTP::Put.new(@uri.request_uri)
  request.set_form_data(params)
  retrieve_response(request)
end

#retrieve_access_token(code, callback_url) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/canvas-api.rb', line 55

def retrieve_access_token(code, callback_url)
  raise "client_id required for oauth flow" unless @client_id
  raise "secret required for oauth flow" unless @secret
  raise "code required" unless code
  raise "callback_url required" unless callback_url
  raise "invalid callback_url" unless (URI.parse(callback_url) rescue nil)
  @token = "ignore"
  res = post("/login/oauth2/token", :client_id => @client_id, :redirect_uri => callback_url, :client_secret => @secret, :code => code)
  if res['access_token']
    @token = res['access_token']
  end
  res
end

#retrieve_response(request) ⇒ Object

Raises:



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/canvas-api.rb', line 94

def retrieve_response(request)
  request['User-Agent'] = "CanvasAPI Ruby"
  begin
    response = @http.request(request)
  rescue Timeout::Error => e
    raise ApiError.new("request timed out")
  end
  raise ApiError.new("unexpected redirect to #{response.location}") if response.code.to_s.match(/3\d\d/)
  json = JSON.parse(response.body) rescue {'error' => 'invalid JSON'}
  if !json.is_a?(Array)
    raise ApiError.new(json['error']) if json['error']
    if !response.code.to_s.match(/2\d\d/)
      json['message'] ||= "unexpected error"
      raise ApiError.new("#{json['status']} #{json['message']}") 
    end
  else
    json = ResultSet.new(self, json)
    if response['link']
      json.link = response['link']
      json.next_endpoint = response['link'].split(/,/).detect{|rel| rel.match(/rel="next"/) }.split(/;/).first.strip[1..-2].sub(/https?:\/\/[^\/]+/, '') rescue nil
    end
  end
  json
end

#stop_masqueradingObject



28
29
30
# File 'lib/canvas-api.rb', line 28

def stop_masquerading
  @as_user_id = nil
end

#upload_file_from_localObject



150
151
152
# File 'lib/canvas-api.rb', line 150

def upload_file_from_local
  # TODO
end

#upload_file_from_urlObject



154
155
156
# File 'lib/canvas-api.rb', line 154

def upload_file_from_url
  # TODO
end

#validate_call(endpoint) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/canvas-api.rb', line 73

def validate_call(endpoint)
  raise "token required for api calls" unless @token
  raise "missing host" unless @host
  raise "missing endpoint" unless endpoint
  raise "missing leading slash on endpoint" unless endpoint.match(/^\//)
  raise "invalid endpoint" unless endpoint.match(/^\/api\/v\d+\//) unless @token == 'ignore'
  raise "invalid endpoint" unless (URI.parse(endpoint) rescue nil)
end