limelm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/Gemfile +15 -0
  4. data/Gemfile.lock +75 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +75 -0
  7. data/Rakefile +50 -0
  8. data/TODO.md +10 -0
  9. data/VERSION +1 -0
  10. data/lib/lime_lm/connection.rb +23 -0
  11. data/lib/lime_lm/exceptions.rb +6 -0
  12. data/lib/lime_lm/feature.rb +62 -0
  13. data/lib/lime_lm/key.rb +83 -0
  14. data/lib/lime_lm/utils.rb +7 -0
  15. data/lib/limelm.rb +30 -0
  16. data/limelm.gemspec +89 -0
  17. data/spec/fixtures/dish_cassettes/all_features.yml +47 -0
  18. data/spec/fixtures/dish_cassettes/create_custom_feature.yml +46 -0
  19. data/spec/fixtures/dish_cassettes/create_detailed_key.yml +46 -0
  20. data/spec/fixtures/dish_cassettes/create_key_default_configuration.yml +46 -0
  21. data/spec/fixtures/dish_cassettes/create_key_new_version.yml +46 -0
  22. data/spec/fixtures/dish_cassettes/create_keys_with_email.yml +46 -0
  23. data/spec/fixtures/dish_cassettes/create_product_default_feature.yml +46 -0
  24. data/spec/fixtures/dish_cassettes/default_search.yml +46 -0
  25. data/spec/fixtures/dish_cassettes/default_search_pagination.yml +46 -0
  26. data/spec/fixtures/dish_cassettes/destroy_feature.yml +46 -0
  27. data/spec/fixtures/dish_cassettes/destroy_key.yml +46 -0
  28. data/spec/fixtures/dish_cassettes/destroy_random_key.yml +47 -0
  29. data/spec/fixtures/dish_cassettes/details_for_a_given_key.yml +46 -0
  30. data/spec/fixtures/dish_cassettes/details_for_a_given_key_with_tags.yml +46 -0
  31. data/spec/fixtures/dish_cassettes/find_keys_by_email.yml +46 -0
  32. data/spec/fixtures/dish_cassettes/id_for_a_given_key.yml +46 -0
  33. data/spec/fixtures/dish_cassettes/remove_tag_for_a_given_key.yml +46 -0
  34. data/spec/fixtures/dish_cassettes/revoke_key.yml +46 -0
  35. data/spec/fixtures/dish_cassettes/set_tags_for_a_given_key.yml +46 -0
  36. data/spec/fixtures/dish_cassettes/unrevoke_key.yml +46 -0
  37. data/spec/fixtures/dish_cassettes/update_custom_feature.yml +46 -0
  38. data/spec/lib/lime_lm/feature_spec.rb +86 -0
  39. data/spec/lib/lime_lm/key_spec.rb +212 -0
  40. data/spec/lib/limelm_spec.rb +37 -0
  41. data/spec/spec_helper.rb +70 -0
  42. metadata +142 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4f7bfe43b8147336288dec12ddb8cd5518ebaede
4
+ data.tar.gz: ef7e67debc9162ee42338bd63979ae74fd736b6e
5
+ SHA512:
6
+ metadata.gz: 2abe2f632746d8153cc5f8a26bb60204335f564bba62d77287e1aa55e63331c193f53b6dea5dd63929e3a6f8b8cfb209dab3a8d7d3181a8ace16b67a9f2f0f8a
7
+ data.tar.gz: f49186894b96e139e7145231c0ed29903cca69cff37996fc1d8276306df809e1f3d454d571158f26192774f6d4d024826d21599c82b48aa00278b06411d9816c
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'httparty'
4
+
5
+ group :development do
6
+ gem 'rdoc'
7
+ gem 'bundler', '~> 1.0'
8
+ gem 'jeweler', '~> 2.0.1'
9
+ end
10
+
11
+ group :test do
12
+ gem 'webmock'
13
+ gem 'vcr'
14
+ gem 'simplecov', require: false
15
+ end
@@ -0,0 +1,75 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.7)
5
+ builder (3.2.2)
6
+ crack (0.4.2)
7
+ safe_yaml (~> 1.0.0)
8
+ descendants_tracker (0.0.4)
9
+ thread_safe (~> 0.3, >= 0.3.1)
10
+ docile (1.1.5)
11
+ faraday (0.9.1)
12
+ multipart-post (>= 1.2, < 3)
13
+ git (1.2.9.1)
14
+ github_api (0.12.3)
15
+ addressable (~> 2.3)
16
+ descendants_tracker (~> 0.0.4)
17
+ faraday (~> 0.8, < 0.10)
18
+ hashie (>= 3.3)
19
+ multi_json (>= 1.7.5, < 2.0)
20
+ nokogiri (~> 1.6.3)
21
+ oauth2
22
+ hashie (3.4.0)
23
+ highline (1.7.1)
24
+ httparty (0.13.3)
25
+ json (~> 1.8)
26
+ multi_xml (>= 0.5.2)
27
+ jeweler (2.0.1)
28
+ builder
29
+ bundler (>= 1.0)
30
+ git (>= 1.2.5)
31
+ github_api
32
+ highline (>= 1.6.15)
33
+ nokogiri (>= 1.5.10)
34
+ rake
35
+ rdoc
36
+ json (1.8.2)
37
+ jwt (1.3.0)
38
+ mini_portile (0.6.2)
39
+ multi_json (1.10.1)
40
+ multi_xml (0.5.5)
41
+ multipart-post (2.0.0)
42
+ nokogiri (1.6.6.2)
43
+ mini_portile (~> 0.6.0)
44
+ oauth2 (1.0.0)
45
+ faraday (>= 0.8, < 0.10)
46
+ jwt (~> 1.0)
47
+ multi_json (~> 1.3)
48
+ multi_xml (~> 0.5)
49
+ rack (~> 1.2)
50
+ rack (1.6.0)
51
+ rake (10.4.2)
52
+ rdoc (4.1.0)
53
+ safe_yaml (1.0.4)
54
+ simplecov (0.9.2)
55
+ docile (~> 1.1.0)
56
+ multi_json (~> 1.0)
57
+ simplecov-html (~> 0.9.0)
58
+ simplecov-html (0.9.0)
59
+ thread_safe (0.3.4)
60
+ vcr (2.9.3)
61
+ webmock (1.20.4)
62
+ addressable (>= 2.3.6)
63
+ crack (>= 0.3.2)
64
+
65
+ PLATFORMS
66
+ ruby
67
+
68
+ DEPENDENCIES
69
+ bundler (~> 1.0)
70
+ httparty
71
+ jeweler (~> 2.0.1)
72
+ rdoc
73
+ simplecov
74
+ vcr
75
+ webmock
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015 Damien Imberdis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,75 @@
1
+ # limelm
2
+
3
+ A Ruby API wrapper for the LimeLM API. LimeLM is a powerfull Licence and Online Activation Manager. For more information, see: http://wyday.com/limelm/
4
+
5
+ Documentation for the LimeLM API can be found here: https://wyday.com/limelm/help/api/
6
+
7
+ ## Setup
8
+
9
+ gem install limelm
10
+
11
+ Or with bundler,
12
+
13
+ ```ruby
14
+ gem "limelm"
15
+ ```
16
+
17
+ Before using the library, you must initialize it with your LimeLM API key. If you're using Rails, put this code in an initializer:
18
+
19
+ ```ruby
20
+ LimeLm.configure(api_key: 'YOUR_API_KEY')
21
+ ```
22
+
23
+ If you are working with an unique version of a Product, you can set it during the configuration:
24
+
25
+ ```ruby
26
+ LimeLm.configure(api_key: 'YOUR_API_KEY', version_id: 'YOUR_PRODUCT_VERSION_ID')
27
+ ```
28
+
29
+ ## Usage example
30
+
31
+ Find all the keys that matching a specific product version (cf. version_id parameter) and a specific user via its registered email:
32
+
33
+ ```ruby
34
+ LimeLm::Key.find('imberdis.damien@gmail.com', version_id: '1')
35
+ ```
36
+
37
+ ## API endpoints not developed yet
38
+ * [deactivate a specific activation](https://wyday.com/limelm/help/api/limelm.pkey.deactivate/)
39
+ * [manual offline activation of a key](https://wyday.com/limelm/help/api/limelm.pkey.manualActivation/)
40
+ * [manual offline deactivation of a key](https://wyday.com/limelm/help/api/limelm.pkey.manualDeactivation/)
41
+ * [trial extension CRUD operation](https://wyday.com/limelm/help/api/)
42
+ * [Gets the activity of a product version between a date range](https://wyday.com/limelm/help/api/limelm.pkey.activity/)
43
+ * [Remove a tag from all product keys](https://wyday.com/limelm/help/api/limelm.tag.delete/)
44
+
45
+ ## Contribute to limelm
46
+
47
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
48
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
49
+ * Fork the project.
50
+ * Start a feature/bugfix branch.
51
+ * Commit and push until you are happy with your contribution.
52
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
53
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
54
+
55
+ ### Testing
56
+
57
+ All tests can be run by the command `rake spec`. By default, all the API requests are mocked by web fixtures.
58
+
59
+ As LimeLM not providing yet a demo environment, you will need to use your own product version to implement new functionalities:
60
+
61
+ * create a conf.yml file under the project root directory that will containes your personal `api_ key` and `version_id`.
62
+ * nether share that file via your source control tool.
63
+ * write new test (cf. other tests as examples on how to use VCR for mocking the HTTP requests), launch them with the command `rake spec MODE=live`.
64
+ * Once VCR generated the fixtures, anonymize them (replace every api_key, version_id, key ids and values by fake data).
65
+
66
+
67
+ ## Disclaimer
68
+
69
+ This project and the code therein was not created by and is not supported by WyDay, Inc or any of its affiliates.
70
+
71
+ ## Copyright
72
+
73
+ Copyright (c) 2015 Damien Imberdis. See LICENSE.txt for
74
+ further details.
75
+
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
+ gem.name = "limelm"
18
+ gem.homepage = "http://github.com/dam/limelm"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{limelm is a Ruby wrapper for the LimeLM JSON API}
21
+ gem.description = %Q{limelm is a Ruby wrapper for the LimeLM JSON API. LimeLM is a powerfull Licence and Online Activation Manager}
22
+ gem.email = "imberdis.damien@gmail.com"
23
+ gem.authors = ["Damien Imberdis"]
24
+ end
25
+ Jeweler::RubygemsDotOrgTasks.new
26
+
27
+ require 'rake/testtask'
28
+ Rake::TestTask.new(:spec) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.verbose = true
32
+ end
33
+
34
+ desc "Code coverage detail"
35
+ task :simplecov do
36
+ ENV['COVERAGE'] = "true"
37
+ Rake::Task['spec'].execute
38
+ end
39
+
40
+ task :default => :spec
41
+
42
+ require 'rdoc/task'
43
+ Rake::RDocTask.new do |rdoc|
44
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
45
+
46
+ rdoc.rdoc_dir = 'rdoc'
47
+ rdoc.title = "limelm #{version}"
48
+ rdoc.rdoc_files.include('README*')
49
+ rdoc.rdoc_files.include('lib/**/*.rb')
50
+ end
data/TODO.md ADDED
@@ -0,0 +1,10 @@
1
+ # API endpoints not yet implemented
2
+ * [deactivate a specific activation](https://wyday.com/limelm/help/api/limelm.pkey.deactivate/)
3
+ * [manual offline activation of a key](https://wyday.com/limelm/help/api/limelm.pkey.manualActivation/)
4
+ * [manual offline deactivation of a key](https://wyday.com/limelm/help/api/limelm.pkey.manualDeactivation/)
5
+ * [trial extension CRUD operation](https://wyday.com/limelm/help/api/)
6
+ * [Gets the activity of a product version between a date range](https://wyday.com/limelm/help/api/limelm.pkey.activity/)
7
+ * [Remove a tag from all product keys](https://wyday.com/limelm/help/api/limelm.tag.delete/)
8
+
9
+ # Tests
10
+ * LimeLm::Key.search: add more tests to cover some optional parameters
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,23 @@
1
+ module LimeLm
2
+ class Connection
3
+ include HTTParty
4
+ base_uri 'https://wyday.com/limelm/api/rest/'
5
+
6
+ class << self
7
+ def post_json(params)
8
+ raise LimeLm::InvalidParams, 'LimeLM api expecting a method parameter' unless params[:method]
9
+
10
+ params[:api_key] = LimeLm.config[:api_key]
11
+ params[:format] = :json
12
+
13
+ response = post('', query: params)
14
+
15
+ parsed_response = JSON.parse($1) if response.body =~ /jsonLimeLMApi\((.*)\)/
16
+ raise LimeLm::ParseResponse, "Unable to parse API response: #{response.body }" unless parsed_response
17
+
18
+ raise LimeLm::ApiError, "#{parsed_response['code']}: #{parsed_response['message']}" unless parsed_response['stat'] == 'ok'
19
+ parsed_response
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ module LimeLm
2
+ class InvalidParams < StandardError; end
3
+ class ParseResponse < StandardError; end
4
+ class ApiError < StandardError; end
5
+ class InvalidObject < StandardError; end
6
+ end
@@ -0,0 +1,62 @@
1
+ module LimeLm
2
+ class Feature
3
+ attr_reader :id
4
+ attr_reader :name
5
+ attr_reader :type
6
+ attr_reader :ta_readable
7
+ attr_reader :required
8
+ attr_reader :description
9
+
10
+ def initialize(hash)
11
+ self.send(:assign_properties, hash)
12
+ end
13
+
14
+ class << self
15
+ def create(params={})
16
+ version_id = params.delete(:version_id) { LimeLm.config[:version_id] }
17
+
18
+ response = LimeLm::Connection.post_json({ method: 'limelm.feature.add', version_id: version_id }.merge!(params))
19
+ additional_info = LimeLm::Utils.stringify_keys(params)
20
+ additional_info['type'] = 'string' unless additional_info['type']
21
+ additional_info['required'] = 'true' unless additional_info['required']
22
+ additional_info['ta_readable'] = 'true' unless additional_info['ta_readable']
23
+
24
+ new(response['feature'].merge!(additional_info))
25
+ end
26
+
27
+ def all(params={})
28
+ version_id = params.delete(:version_id) { LimeLm.config[:version_id] }
29
+
30
+ response = LimeLm::Connection.post_json({ method: 'limelm.feature.getAll', version_id: version_id })
31
+ response['fields']['field'].map { |f| new(f) }
32
+ end
33
+ end
34
+
35
+ def update!(params={})
36
+ response = LimeLm::Connection.post_json({ method: 'limelm.feature.edit', feature_id: @id }.merge!(params))
37
+ new_info = LimeLm::Utils.stringify_keys(params)
38
+ @name = new_info['name'] if new_info['name']
39
+ @ta_readable = (new_info['ta_readable'] == 'true') if new_info['ta_readable']
40
+ @required = (new_info['required'] == 'true') if new_info['required']
41
+ @description = new_info['description'] if new_info['description']
42
+ true
43
+ end
44
+
45
+ def destroy!
46
+ LimeLm::Connection.post_json({ method: 'limelm.feature.delete', feature_id: @id })
47
+ true
48
+ end
49
+
50
+ private
51
+
52
+ def assign_properties(hash)
53
+ hash = LimeLm::Utils.stringify_keys(hash)
54
+ @id = hash['id']
55
+ @name = hash['name']
56
+ @type = hash['type']
57
+ @ta_readable = hash['ta_readable'] == 'true'
58
+ @required = hash['required'] == 'true'
59
+ @description = hash['description']
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,83 @@
1
+ module LimeLm
2
+ class Key
3
+ attr_reader :id
4
+ attr_reader :key
5
+ attr_reader :version_id
6
+ attr_reader :email
7
+ attr_reader :revoked
8
+ attr_reader :properties
9
+
10
+ def initialize(hash)
11
+ self.send(:assign_properties, hash)
12
+ raise LimeLm::InvalidObject, 'You need to provide at least an id or a key for the LimeLm::Key object' unless @id || @key
13
+ end
14
+
15
+ class << self
16
+ def create(params={})
17
+ version_id = params.delete(:version_id) { LimeLm.config[:version_id] }
18
+
19
+ response = LimeLm::Connection.post_json({ method: 'limelm.pkey.generate', version_id: version_id }.merge!(params))
20
+ additional_info = LimeLm::Utils.stringify_keys(params.merge!({ version_id: version_id }))
21
+ response['pkeys']['pkey'].map { |k| new(k.merge!(additional_info)) }
22
+ end
23
+
24
+ def find(email, params={})
25
+ version_id = params.delete(:version_id) { LimeLm.config[:version_id] }
26
+
27
+ response = LimeLm::Connection.post_json({ method: 'limelm.pkey.find', version_id: version_id, email: email })
28
+ response['pkeys']['pkey'].map { |k| new(k.merge!({ 'version_id' => version_id, 'email' => email })) }
29
+ end
30
+
31
+ def search(params={})
32
+ response = LimeLm::Connection.post_json({ method: 'limelm.pkey.advancedSearch'}.merge!(params))
33
+ response['pkeys']['pkey'].map { |k| new(k) }
34
+ end
35
+ end
36
+
37
+ def id(params={})
38
+ return @id if @id
39
+
40
+ version_id = params.delete(:version_id) { LimeLm.config[:version_id] }
41
+ response = LimeLm::Connection.post_json({ method: 'limelm.pkey.getID', version_id: version_id, pkey: @key })
42
+ @id = response['pkey']['id']
43
+ end
44
+
45
+ def tag(tags=[])
46
+ LimeLm::Connection.post_json({ method: 'limelm.pkey.setTags', pkey_id: @id, tag: tags })
47
+ true
48
+ end
49
+
50
+ def remove_tag(tag)
51
+ LimeLm::Connection.post_json({ method: 'limelm.pkey.removeTag', pkey_id: @id, tag: tag })
52
+ true
53
+ end
54
+
55
+ def details
56
+ response = LimeLm::Connection.post_json({ method: 'limelm.pkey.getDetails', pkey_id: @id })
57
+ self.send(:assign_properties, response['pkey'])
58
+ end
59
+
60
+ def destroy!
61
+ LimeLm::Connection.post_json({ method: 'limelm.pkey.delete', pkey_id: @id })
62
+ true
63
+ end
64
+
65
+ def toggle_revoke!
66
+ revoke = @revoked ? 'false' : 'true'
67
+ LimeLm::Connection.post_json({ method: 'limelm.pkey.revoke', pkey_id: @id, revoke: revoke })
68
+ @revoked = !@revoked
69
+ end
70
+
71
+ private
72
+
73
+ def assign_properties(hash)
74
+ hash = LimeLm::Utils.stringify_keys(hash)
75
+ @id = hash['id']
76
+ @key = hash['key']
77
+ @version_id = hash['version_id']
78
+ @email = hash['email']
79
+ @revoked = hash['revoked'] || false
80
+ @properties = hash
81
+ end
82
+ end
83
+ end