masheri 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +5 -0
- data/Gemfile.lock +18 -0
- data/LICENSE.txt +21 -0
- data/README.md +3 -0
- data/README.textile +56 -0
- data/Rakefile +16 -0
- data/VERSION +1 -0
- data/lib/masheri.rb +22 -0
- data/lib/masheri/api_object_base.rb +26 -0
- data/lib/masheri/client.rb +40 -0
- data/lib/masheri/exceptions.rb +27 -0
- data/lib/masheri/key.rb +22 -0
- data/lib/masheri/member.rb +24 -0
- data/lib/masheri/query.rb +63 -0
- data/lib/masheri/role.rb +20 -0
- data/lib/masheri/version.rb +9 -0
- data/masheri.gemspec +66 -0
- data/tasks/mashery.thor +200 -0
- metadata +131 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Farley Knight
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
data/README.textile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
A Ruby library for the "Mashery API":http://support.mashery.com/docs/mashery_api.
|
2
|
+
|
3
|
+
h2. Prerequisites
|
4
|
+
|
5
|
+
Install the gem dependencies (see "gembundler.com":http://gembundler.com/ if you aren't familiar with Bundler):
|
6
|
+
|
7
|
+
@$ bundle install@
|
8
|
+
|
9
|
+
h2. Calling methods from the command line
|
10
|
+
|
11
|
+
A set of Thor tasks are provided so that you can call API methods from the command line (read more about Thor at
|
12
|
+
"http://github.com/wycats/thor":http://github.com/wycats/thor).
|
13
|
+
|
14
|
+
The following examples assume you have Thor installed system-wide. If it's local to your bundle, then replace
|
15
|
+
@thor@ with @bundle exec thor@.
|
16
|
+
|
17
|
+
You can see all available Mashery tasks with this command:
|
18
|
+
|
19
|
+
@$ thor list mashery@
|
20
|
+
|
21
|
+
h3. Environment
|
22
|
+
|
23
|
+
Before you can successfully call an API method, you must set these environment variables:
|
24
|
+
|
25
|
+
bc. $ export MASHERY_SITE_ID=666
|
26
|
+
$ export MASHERY_API_KEY=cafebebedeadbeefcafebebedeadbeef
|
27
|
+
$ export MASHERY_SHARED_SECRET=blahblahblah
|
28
|
+
|
29
|
+
By default, the thor tasks call methods in the Mashery sandbox. If you want them to access the production environment
|
30
|
+
instead, set the {{MASHERY_PRODUCTION_MODE}} environment variable to any value:
|
31
|
+
|
32
|
+
bc. $ export MASHERY_PRODUCTION_MODE=hi
|
33
|
+
|
34
|
+
h3. Querying objects
|
35
|
+
|
36
|
+
The Mashery API supports querying the following types of objects: "members":http://support.mashery.com/docs/mashery_api/member/, "applications":http://support.mashery.com/docs/mashery_api/application/, "keys":http://support.mashery.com/docs/mashery_api/key/, "services":http://support.mashery.com/docs/mashery_api/service/, and "roles":http://support.mashery.com/docs/mashery_api/role/.
|
37
|
+
|
38
|
+
To perform a query, construct a Query object for the type of object you want to query:
|
39
|
+
|
40
|
+
bc. query = Mashery::Query.new('members')
|
41
|
+
members = query.fetch_all
|
42
|
+
|
43
|
+
The @fetch_all@ method will automatically paginate through the results for you. You can also control this yourself with the @page@ parameter and @execute@:
|
44
|
+
|
45
|
+
bc. query = Mashery::Query.new('members', :page => 2)
|
46
|
+
result = query.execute
|
47
|
+
items = result['items']
|
48
|
+
|
49
|
+
(Or, use the @items@ method, which combines @execute@ and @result['items']@ -- however, this does not return result set metadata, like current page and total pages.)
|
50
|
+
|
51
|
+
The default will return all fields (e.g., @SELECT * FROM members@). To control this, specify the @:fields@ parameter.
|
52
|
+
|
53
|
+
To control which records are returned, specify the @:where@ parameter.
|
54
|
+
|
55
|
+
bc. query = Mashery::Query.new('members', :where => 'username = "Jeff"'
|
56
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
require './lib/masheri/version.rb'
|
4
|
+
Jeweler::Tasks.new do |gemspec|
|
5
|
+
gemspec.name = "masheri"
|
6
|
+
gemspec.summary = "A gem for Ruby on Rails to use the Mashery API, with a clean configuration file."
|
7
|
+
gemspec.email = "farleyknight@gmail.com"
|
8
|
+
gemspec.homepage = "http://github.com/farleyknight/masheri"
|
9
|
+
gemspec.authors = ["Farley Knight"]
|
10
|
+
gemspec.version = Masheri::Version::STRING
|
11
|
+
gemspec.license = "MIT"
|
12
|
+
end
|
13
|
+
Jeweler::RubygemsDotOrgTasks.new
|
14
|
+
rescue LoadError => error
|
15
|
+
puts error
|
16
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.2
|
data/lib/masheri.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
require 'masheri/exceptions'
|
5
|
+
require 'masheri/client'
|
6
|
+
require 'masheri/api_object_base'
|
7
|
+
require 'masheri/member'
|
8
|
+
require 'masheri/key'
|
9
|
+
require 'masheri/role'
|
10
|
+
require 'masheri/query'
|
11
|
+
|
12
|
+
module Masheri
|
13
|
+
mattr_accessor :client
|
14
|
+
@@client = nil
|
15
|
+
|
16
|
+
mattr_accessor :logger, :instance_writer => false
|
17
|
+
@@logger = Logger.new(STDOUT)
|
18
|
+
@@logger.level = Logger::WARN
|
19
|
+
|
20
|
+
mattr_accessor :test_mode, :instance_writer => false
|
21
|
+
@@test_mode = true
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Masheri
|
2
|
+
class ApiObjectBase
|
3
|
+
def self.create(fields = {})
|
4
|
+
# XXX: only send fields that aren't read-only
|
5
|
+
new(Masheri.client.call_remote(method('create'), fields))
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.fetch(id)
|
9
|
+
data = Masheri.client.call_remote(method('fetch'), id)
|
10
|
+
data.nil?? nil : new(data)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.delete(id)
|
14
|
+
Masheri.client.call_remote(method('delete'), id)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.method(basename)
|
18
|
+
"#{name.split(/\:\:/).last.downcase}.#{basename}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(data)
|
22
|
+
# XXX: use setter methods
|
23
|
+
data.each_pair {|k, v| instance_variable_set("@#{k}".to_sym, v)}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'json'
|
3
|
+
require 'httparty'
|
4
|
+
require 'md5'
|
5
|
+
|
6
|
+
module Masheri
|
7
|
+
class Client
|
8
|
+
TEST_HOST = 'api.sandbox.mashery.com'
|
9
|
+
PRODUCTION_HOST = 'api.mashery.com'
|
10
|
+
|
11
|
+
def initialize(site_id, key, secret)
|
12
|
+
host = Masheri.test_mode ? TEST_HOST : PRODUCTION_HOST
|
13
|
+
@uri = "http://#{host}/v2/json-rpc/#{site_id}"
|
14
|
+
@key = key
|
15
|
+
@secret = secret
|
16
|
+
end
|
17
|
+
|
18
|
+
def echo(value)
|
19
|
+
call_remote('test.echo', value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def call_remote(method, *params)
|
23
|
+
# all calls are synchronous, so id in request and response will always be 1
|
24
|
+
if Masheri.logger
|
25
|
+
Masheri.logger.debug("Calling method #{method} with params #{params.inspect} on URI #{signed_uri}")
|
26
|
+
end
|
27
|
+
req = ::JSON[{:version => '1.1', :method => method, :params => params, :id => 1}]
|
28
|
+
response = HTTParty.post(signed_uri, :body => req)
|
29
|
+
raise HttpException.new(response.headers['x-mashery-error-code']) unless response.code < 300
|
30
|
+
res = ::JSON[response.body]
|
31
|
+
raise Exception.create(res['error']) if res.include?('error')
|
32
|
+
res['result']
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
def signed_uri
|
37
|
+
"#{@uri}?apikey=#{@key}&sig=#{MD5.new(@key + @secret + Time.now.to_i.to_s).hexdigest}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Masheri
|
2
|
+
class Exception < ::Exception
|
3
|
+
def self.create(options = {})
|
4
|
+
case options['code']
|
5
|
+
when 1000 then ValidationException.new(options['data'])
|
6
|
+
when 1001 then DuplicateObjectException.new("#{options['message']} (JSON-RPC error #{options['code']})")
|
7
|
+
else JsonRpcException.new("#{options['message']} (JSON-RPC error #{options['code']})")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class HttpException < Exception
|
13
|
+
end
|
14
|
+
|
15
|
+
class JsonRpcException < Exception
|
16
|
+
end
|
17
|
+
|
18
|
+
class DuplicateObjectException < Exception
|
19
|
+
end
|
20
|
+
|
21
|
+
class ValidationException < Exception
|
22
|
+
attr_reader :errors
|
23
|
+
def initialize(errs= {})
|
24
|
+
@errors = errs
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/masheri/key.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Masheri
|
2
|
+
class Key < ApiObjectBase
|
3
|
+
attr_reader :id, :created, :updated, :service_key, :username, :limits
|
4
|
+
attr_accessor(:apikey, :status, :rate_limit_ceiling, :qps_limit_ceiling, :rate_limit_exempt, :qps_limit_exempt,
|
5
|
+
:required_referer, :secret)
|
6
|
+
|
7
|
+
def self.create(service_key, username, fields = {})
|
8
|
+
fields ||= {}
|
9
|
+
our_fields = fields.merge('service' => {'service_key' => service_key}, 'member' => {'username' => username})
|
10
|
+
super(our_fields)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(data)
|
14
|
+
limits = data.delete('limits')
|
15
|
+
@limits = limits.map {|l| Limit.new(l['period'], l['source'], l['ceiling'])} if limits
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Limit < Struct.new(:period, :source, :ceiling)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Masheri
|
2
|
+
class Member < ApiObjectBase
|
3
|
+
attr_reader :created, :updated
|
4
|
+
attr_accessor(:username, :email, :display_name, :uri, :blog, :im, :imsvc, :phone,
|
5
|
+
:company, :address1, :address2, :locality, :region, :postal_code, :country_code, :first_name, :last_name,
|
6
|
+
:registration_ipaddr, :area_status, :external_id, :passwd_new)
|
7
|
+
|
8
|
+
def self.create(username, display_name, email, fields = {})
|
9
|
+
fields ||= {}
|
10
|
+
our_fields = fields.merge('username' => username, 'display_name' => display_name, 'email' => email)
|
11
|
+
super(our_fields)
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_role(role_or_id)
|
15
|
+
role_id = role_or_id.is_a?(Role) ? role_or_id.id : role_or_id
|
16
|
+
Masheri.client.call_remote('member.addRole', {'username' => username}, {'id' => role_id})
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove_role(role_or_id)
|
20
|
+
role_id = role_or_id.is_a?(Role) ? role_or_id.id : role_or_id
|
21
|
+
Masheri.client.call_remote('member.removeRole', {'username' => username}, {'id' => role_id})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Masheri
|
2
|
+
class Query
|
3
|
+
OBJECT_TYPES = ['members', 'keys', 'services', 'roles', 'applications']
|
4
|
+
DEFAULT_QUERIES_PER_SECOND = 2
|
5
|
+
|
6
|
+
attr_reader :object_type, :fields
|
7
|
+
attr_accessor :page
|
8
|
+
|
9
|
+
def initialize(object_type, options={})
|
10
|
+
if !OBJECT_TYPES.include?(object_type)
|
11
|
+
raise "Invalid object type. '#{object_type}' must be in #{OBJECT_TYPES.inspect}"
|
12
|
+
end
|
13
|
+
|
14
|
+
@object_type = object_type
|
15
|
+
|
16
|
+
if options[:fields]
|
17
|
+
@fields = options[:fields]
|
18
|
+
else
|
19
|
+
@fields = "*"
|
20
|
+
end
|
21
|
+
|
22
|
+
@where = options[:where]
|
23
|
+
@page = options[:page]
|
24
|
+
end
|
25
|
+
|
26
|
+
def page_clause
|
27
|
+
"PAGE #{@page}" if @page
|
28
|
+
end
|
29
|
+
|
30
|
+
def where_clause
|
31
|
+
"WHERE #{@where}" if @where
|
32
|
+
end
|
33
|
+
|
34
|
+
def query_string
|
35
|
+
"SELECT #{fields} FROM #{object_type} #{where_clause} #{page_clause}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute
|
39
|
+
Masheri.client.call_remote('object.query', query_string)
|
40
|
+
end
|
41
|
+
|
42
|
+
def items
|
43
|
+
execute['items']
|
44
|
+
end
|
45
|
+
|
46
|
+
# Page through the results. Due heavy use of the API, this method
|
47
|
+
# takes a qps parameter to control how often the API is called.
|
48
|
+
def fetch_all(qps=DEFAULT_QUERIES_PER_SECOND)
|
49
|
+
response = execute
|
50
|
+
items = response['items']
|
51
|
+
|
52
|
+
while response['current_page'] < response['total_pages']
|
53
|
+
self.page = response['current_page'] + 1
|
54
|
+
response = execute
|
55
|
+
items = items + response['items']
|
56
|
+
|
57
|
+
sleep(1.0/DEFAULT_QUERIES_PER_SECOND)
|
58
|
+
end
|
59
|
+
|
60
|
+
return items
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/masheri/role.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Masheri
|
2
|
+
class Role < ApiObjectBase
|
3
|
+
attr_reader :id, :created, :updated, :is_assignable, :is_predefined
|
4
|
+
attr_accessor :name, :description
|
5
|
+
|
6
|
+
def assignable?
|
7
|
+
is_assignable == true
|
8
|
+
end
|
9
|
+
|
10
|
+
def predefined?
|
11
|
+
is_predefined == true
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.create(name, fields = {})
|
15
|
+
fields ||= {}
|
16
|
+
our_fields = fields.merge('name' => name)
|
17
|
+
super(our_fields)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/masheri.gemspec
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "masheri"
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Farley Knight"]
|
12
|
+
s.date = "2013-09-04"
|
13
|
+
s.email = "farleyknight@gmail.com"
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"LICENSE.txt",
|
16
|
+
"README.md",
|
17
|
+
"README.textile"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"LICENSE.txt",
|
23
|
+
"README.md",
|
24
|
+
"README.textile",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/masheri.rb",
|
28
|
+
"lib/masheri/api_object_base.rb",
|
29
|
+
"lib/masheri/client.rb",
|
30
|
+
"lib/masheri/exceptions.rb",
|
31
|
+
"lib/masheri/key.rb",
|
32
|
+
"lib/masheri/member.rb",
|
33
|
+
"lib/masheri/query.rb",
|
34
|
+
"lib/masheri/role.rb",
|
35
|
+
"lib/masheri/version.rb",
|
36
|
+
"masheri.gemspec",
|
37
|
+
"tasks/mashery.thor"
|
38
|
+
]
|
39
|
+
s.homepage = "http://github.com/farleyknight/masheri"
|
40
|
+
s.licenses = ["MIT"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.rubygems_version = "1.8.25"
|
43
|
+
s.summary = "A gem for Ruby on Rails to use the Mashery API, with a clean configuration file."
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<thor>, [">= 0"])
|
50
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0"])
|
51
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
52
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<thor>, [">= 0"])
|
55
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
56
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
57
|
+
s.add_dependency(%q<json>, [">= 0"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<thor>, [">= 0"])
|
61
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
62
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
63
|
+
s.add_dependency(%q<json>, [">= 0"])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
data/tasks/mashery.thor
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup
|
4
|
+
|
5
|
+
# XXX: only do this when the task has not been installed
|
6
|
+
$: << 'lib'
|
7
|
+
|
8
|
+
require 'mashery'
|
9
|
+
|
10
|
+
module Mashery
|
11
|
+
class CLI < Thor
|
12
|
+
namespace :mashery
|
13
|
+
|
14
|
+
desc "echo VALUE", "Echo the provided value (tests connectivity and authentication)"
|
15
|
+
def echo(value)
|
16
|
+
run { ok(::Mashery.client.echo(value)) }
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
def run(&block)
|
21
|
+
site_id = ENV['MASHERY_SITE_ID'] or
|
22
|
+
raise Exception, "Please set the MASHERY_SITE_ID environment variable."
|
23
|
+
key = ENV['MASHERY_API_KEY'] or
|
24
|
+
raise Exception, "Please set the MASHERY_API_KEY environment variable."
|
25
|
+
secret = ENV['MASHERY_SHARED_SECRET'] or
|
26
|
+
raise Exception, "Please set the MASHERY_SHARED_SECRET environment variable."
|
27
|
+
::Mashery.test_mode = ENV['MASHERY_PRODUCTION_MODE'].blank?
|
28
|
+
::Mashery.logger.level = Logger::DEBUG
|
29
|
+
::Mashery.client = ::Mashery::Client.new(site_id, key, secret)
|
30
|
+
begin
|
31
|
+
yield
|
32
|
+
rescue ::Mashery::HttpException => e
|
33
|
+
error("HTTP error: #{e.message}")
|
34
|
+
rescue ::Mashery::JsonRpcException => e
|
35
|
+
error(e.message)
|
36
|
+
rescue ::Mashery::ValidationException => e
|
37
|
+
e.errors.each {|err| warn("#{err['field']}: #{err['message']}")}
|
38
|
+
error("Unable to execute method due to validation errors")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def warn(msg)
|
43
|
+
say_status :WARN, msg, :yellow
|
44
|
+
end
|
45
|
+
|
46
|
+
def ok(msg)
|
47
|
+
say_status :OK, msg
|
48
|
+
end
|
49
|
+
|
50
|
+
def error(msg)
|
51
|
+
say_status :ERROR, msg, :red
|
52
|
+
end
|
53
|
+
|
54
|
+
def debug(msg)
|
55
|
+
say_status :DEBUG, msg, :cyan
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class MemberCLI < CLI
|
60
|
+
namespace 'mashery:member'
|
61
|
+
|
62
|
+
desc "create USERNAME DISPLAY_NAME EMAIL [--fields ...]", "Create a member"
|
63
|
+
method_option :fields, :type => :hash
|
64
|
+
def create(username, display_name, email)
|
65
|
+
run do
|
66
|
+
begin
|
67
|
+
member = ::Mashery::Member.create(username, display_name, email, options[:fields])
|
68
|
+
ok("Member #{member.username} created")
|
69
|
+
rescue ::Mashery::DuplicateObjectException
|
70
|
+
error("The username #{username} has already been claimed")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "fetch USERNAME", "Fetch a member"
|
76
|
+
def fetch(username)
|
77
|
+
run do
|
78
|
+
member = ::Mashery::Member.fetch(username)
|
79
|
+
if member
|
80
|
+
ok("Member #{username} found")
|
81
|
+
say(member.to_yaml)
|
82
|
+
else
|
83
|
+
warn("Member #{username} not found")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "addrole USERNAME ROLE_ID", "Assign a role to a member"
|
89
|
+
def addrole(username, role_id)
|
90
|
+
run do
|
91
|
+
member = ::Mashery::Member.fetch(username)
|
92
|
+
if member
|
93
|
+
role = ::Mashery::Role.fetch(role_id.to_i)
|
94
|
+
if role
|
95
|
+
member.add_role(role)
|
96
|
+
ok("Role #{role.name} assigned to member #{username}")
|
97
|
+
else
|
98
|
+
warn("Role #{role_id} not found")
|
99
|
+
end
|
100
|
+
else
|
101
|
+
warn("Member #{username} not found")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
desc "rmrole USERNAME ROLE_ID", "Revoke a role from a member"
|
107
|
+
def rmrole(username, role_id)
|
108
|
+
run do
|
109
|
+
member = ::Mashery::Member.fetch(username)
|
110
|
+
if member
|
111
|
+
role = ::Mashery::Role.fetch(role_id.to_i)
|
112
|
+
if role
|
113
|
+
member.remove_role(role)
|
114
|
+
ok("Role #{role.name} revoked from member #{username}")
|
115
|
+
else
|
116
|
+
warn("Role #{role_id} not found")
|
117
|
+
end
|
118
|
+
else
|
119
|
+
warn("Member #{username} not found")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
desc "delete USERNAME", "Delete a member"
|
125
|
+
def delete(username)
|
126
|
+
run do
|
127
|
+
::Mashery::Member.delete(username)
|
128
|
+
ok("Member #{username} deleted")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class KeyCLI < CLI
|
134
|
+
namespace 'mashery:key'
|
135
|
+
|
136
|
+
desc "create SERVICE_KEY USERNAME [--fields ...]", "Create a key"
|
137
|
+
method_option :fields, :type => :hash
|
138
|
+
def create(service_key, username)
|
139
|
+
run do
|
140
|
+
key = ::Mashery::Key.create(service_key, username, options[:fields])
|
141
|
+
ok("Key #{key.id} created for member #{username} and service #{service_key}")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
desc "fetch ID", "Fetch a key"
|
146
|
+
def fetch(id)
|
147
|
+
run do
|
148
|
+
key = ::Mashery::Key.fetch(id.to_i)
|
149
|
+
if key
|
150
|
+
ok("Key #{id} found")
|
151
|
+
say(key.to_yaml)
|
152
|
+
else
|
153
|
+
warn("Key #{id} not found")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
desc "delete ID", "Delete a key"
|
159
|
+
def delete(id)
|
160
|
+
run do
|
161
|
+
::Mashery::Key.delete(id.to_i)
|
162
|
+
ok("Key #{id} deleted")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class RoleCLI < CLI
|
168
|
+
namespace 'mashery:role'
|
169
|
+
|
170
|
+
desc "create NAME [--fields ...]", "Create a role"
|
171
|
+
method_option :fields, :type => :hash
|
172
|
+
def create(name)
|
173
|
+
run do
|
174
|
+
role = ::Mashery::Role.create(name, options[:fields])
|
175
|
+
ok("Role #{role.id} created with name #{name}")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
desc "fetch ID", "Fetch a role"
|
180
|
+
def fetch(id)
|
181
|
+
run do
|
182
|
+
role = ::Mashery::Role.fetch(id.to_i)
|
183
|
+
if role
|
184
|
+
ok("Role #{id} found")
|
185
|
+
say(role.to_yaml)
|
186
|
+
else
|
187
|
+
warn("Role #{id} not found")
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
desc "delete ID", "Delete a role"
|
193
|
+
def delete(id)
|
194
|
+
run do
|
195
|
+
::Mashery::Role.delete(id.to_i)
|
196
|
+
ok("Role #{id} deleted")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: masheri
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Farley Knight
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: httparty
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: activesupport
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: json
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description:
|
79
|
+
email: farleyknight@gmail.com
|
80
|
+
executables: []
|
81
|
+
extensions: []
|
82
|
+
extra_rdoc_files:
|
83
|
+
- LICENSE.txt
|
84
|
+
- README.md
|
85
|
+
- README.textile
|
86
|
+
files:
|
87
|
+
- Gemfile
|
88
|
+
- Gemfile.lock
|
89
|
+
- LICENSE.txt
|
90
|
+
- README.md
|
91
|
+
- README.textile
|
92
|
+
- Rakefile
|
93
|
+
- VERSION
|
94
|
+
- lib/masheri.rb
|
95
|
+
- lib/masheri/api_object_base.rb
|
96
|
+
- lib/masheri/client.rb
|
97
|
+
- lib/masheri/exceptions.rb
|
98
|
+
- lib/masheri/key.rb
|
99
|
+
- lib/masheri/member.rb
|
100
|
+
- lib/masheri/query.rb
|
101
|
+
- lib/masheri/role.rb
|
102
|
+
- lib/masheri/version.rb
|
103
|
+
- masheri.gemspec
|
104
|
+
- tasks/mashery.thor
|
105
|
+
homepage: http://github.com/farleyknight/masheri
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ! '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 1.8.25
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: A gem for Ruby on Rails to use the Mashery API, with a clean configuration
|
130
|
+
file.
|
131
|
+
test_files: []
|