soteria 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +77 -0
  9. data/Rakefile +5 -0
  10. data/bin/bundler +17 -0
  11. data/bin/console +17 -0
  12. data/bin/htmldiff +17 -0
  13. data/bin/ldiff +17 -0
  14. data/bin/nokogiri +17 -0
  15. data/bin/rackup +17 -0
  16. data/bin/rake +17 -0
  17. data/bin/rspec +17 -0
  18. data/bin/setup +17 -0
  19. data/bin/socksify_ruby +17 -0
  20. data/lib/soteria.rb +10 -0
  21. data/lib/soteria/client.rb +326 -0
  22. data/lib/soteria/credential.rb +154 -0
  23. data/lib/soteria/credential_types.rb +13 -0
  24. data/lib/soteria/push.rb +141 -0
  25. data/lib/soteria/sms.rb +81 -0
  26. data/lib/soteria/user.rb +409 -0
  27. data/lib/soteria/utilities.rb +45 -0
  28. data/lib/soteria/version.rb +4 -0
  29. data/soteria.gemspec +26 -0
  30. data/spec/credential_spec.rb +121 -0
  31. data/spec/fixtures/credential/authenticate_credentials_response.xml +13 -0
  32. data/spec/fixtures/credential/credential_fail.xml +11 -0
  33. data/spec/fixtures/credential/credential_success.xml +12 -0
  34. data/spec/fixtures/credential/get_cred_info_response.xml +40 -0
  35. data/spec/fixtures/credential/get_server_time_response.xml +11 -0
  36. data/spec/fixtures/credential/register_sms_response.xml +12 -0
  37. data/spec/fixtures/push/authenticate_with_push_error.xml +9 -0
  38. data/spec/fixtures/push/authenticate_with_push_response.xml +14 -0
  39. data/spec/fixtures/sms/check_otp_success_response.xml +13 -0
  40. data/spec/fixtures/sms/send_sms_success_response.xml +10 -0
  41. data/spec/fixtures/user/add_credential_response.xml +9 -0
  42. data/spec/fixtures/user/clear_temp_password_response.xml +10 -0
  43. data/spec/fixtures/user/clear_user_pin_response.xml +10 -0
  44. data/spec/fixtures/user/create_user_response.xml +9 -0
  45. data/spec/fixtures/user/delete_user_response.xml +10 -0
  46. data/spec/fixtures/user/get_temp_pass_attr_response.xml +14 -0
  47. data/spec/fixtures/user/remove_credential_response.xml +10 -0
  48. data/spec/fixtures/user/set_temp_pass_attr_response.xml +10 -0
  49. data/spec/fixtures/user/set_temp_pass_response.xml +11 -0
  50. data/spec/fixtures/user/update_credential_response.xml +10 -0
  51. data/spec/fixtures/user/update_user_response.xml +10 -0
  52. data/spec/fixtures/wsdl/vipuserservices-1.7.xsd +1015 -0
  53. data/spec/fixtures/wsdl/vipuserservices-auth-1.7.wsdl +155 -0
  54. data/spec/fixtures/wsdl/vipuserservices-mgmt-1.7.wsdl +246 -0
  55. data/spec/fixtures/wsdl/vipuserservices-query-1.7.wsdl +114 -0
  56. data/spec/push_spec.rb +148 -0
  57. data/spec/sms_spec.rb +84 -0
  58. data/spec/soteria_spec.rb +8 -0
  59. data/spec/spec_helper.rb +2 -0
  60. data/spec/user_spec.rb +245 -0
  61. metadata +206 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4c0cfc2a664b2499ac66b28f0448574b4f051b3b
4
+ data.tar.gz: 868b423d6a0be0b622c983be79444f428dcbedff
5
+ SHA512:
6
+ metadata.gz: 6563f1bb0d6c1961dd7653e097e45fefed2d61e78b7bbabbb19ca1c66a78610479e9f5aa2163a2ff68d3dbed36c93b489d288319e723b85b6677d9ecf2e8df9e
7
+ data.tar.gz: 8e5ee6d25474c868fb929f6defcfa0e4194395b29b66d1b202e16e90d080752c1a40fcbc07ed00f1037cdcc6e51539fefc297f4efac82c13e63a848858a0272c
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.13.2
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at caslerry@msu.edu. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Ryan Casler
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
@@ -0,0 +1,77 @@
1
+ # Soteria
2
+
3
+ Soteria is a gem to integrate Symantec VIP two factor authentication into any application.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'soteria'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install soteria
20
+
21
+ ## Obtaining a certificate
22
+
23
+ To use Soteria in your project you first need a certificate from [Symantec VIP manager](https://manager.vip.symantec.com).
24
+ To obtain a certificate login and go to Account -> Manage VIP Certificates -> Request a Certificate. From there follow
25
+ the directions to create a new certificate. On the download screen select the PKCS#12 format and enter the password you
26
+ would like to use to secure the certificate.
27
+
28
+ After downloading the PKCS#12 certificate, you must split it into a public and private key. To do so run the following two
29
+ commands.
30
+
31
+ Extract the private key:
32
+
33
+ $ openssl pkcs12 -in yourP12File.pfx -nocerts -out privateKey.pem
34
+
35
+ Extract the public certificate:
36
+
37
+ $ openssl pkcs12 -in yourP12File.pfx -clcerts -nokeys -out publicCert.pem
38
+
39
+ ## Usage
40
+
41
+ Once the certificate is split, Soteria is easy to use.
42
+
43
+ ```ruby
44
+ # Start by createing a Soteria client
45
+ soteria = soteria = Soteria.new('/Users/user/soteria/lib/publicCert.pem', '/Users/user/soteria/lib/privateKey.pem', 'passwordForKey')
46
+
47
+ # Register a new user
48
+ soteria.create_user('userid', nil)
49
+
50
+ # Add a credential
51
+ soteria.add_credential('userid', 'VSMT123456', CredentialTypes::STANDARD, nil)
52
+
53
+ # Send a push to that user
54
+ soteria.send_push('userid', nil)
55
+ # => { success: true, id: 'send_push_request_20161025010101', transaction_id: '3239814823', message: 'Success' }
56
+
57
+ # Poll for the push response
58
+ soteria.poll_for_response('3239814823', 5, 30)
59
+ # => { success: true, message: '"Mobile push request approved by user', id: 'poll_push_status_20161025010101' }
60
+ ```
61
+
62
+
63
+ ## Development
64
+
65
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
66
+
67
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
68
+
69
+ ## Contributing
70
+
71
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ryanrampage1/soteria. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
72
+
73
+
74
+ ## License
75
+
76
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
77
+
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ Dir.glob('tasks/**/*.rake').each(&method(:import))
4
+
5
+ task default: :spec
data/bin/bundler ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'bundler' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("bundler", "bundler")
data/bin/console ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'console' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("soteria", "console")
data/bin/htmldiff ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'htmldiff' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("diff-lcs", "htmldiff")
data/bin/ldiff ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'ldiff' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("diff-lcs", "ldiff")
data/bin/nokogiri ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'nokogiri' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("nokogiri", "nokogiri")
data/bin/rackup ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rackup' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rack", "rackup")
data/bin/rake ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rake' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rake", "rake")
data/bin/rspec ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rspec' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rspec-core", "rspec")
data/bin/setup ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'setup' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("soteria", "setup")
data/bin/socksify_ruby ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'socksify_ruby' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("socksify", "socksify_ruby")
data/lib/soteria.rb ADDED
@@ -0,0 +1,10 @@
1
+ module Soteria
2
+
3
+ def self.client(cert_file, cert_key_file, password, should_log)
4
+ Client.new(cert_file, cert_key_file, password, should_log)
5
+ end
6
+
7
+ end
8
+
9
+ require "soteria/version"
10
+ require "soteria/client"
@@ -0,0 +1,326 @@
1
+ require 'savon'
2
+ require 'soteria/utilities'
3
+ require 'soteria/sms'
4
+ require 'soteria/credential'
5
+ require 'soteria/user'
6
+ require 'soteria/push'
7
+
8
+ module Soteria
9
+
10
+ class Client
11
+
12
+ # To use Soteria, SSL certificates for Symantec VIP Services are required. To obtain a certificate go to
13
+ # https://manager.vip.symantec.com/ and log in. From the dashboard go to Account -> Manage VIP Certificates -> Request
14
+ # a Certificate. From there follow the directions to create a new certificate. On the download screen select the PKCS#12
15
+ # format and enter the password you would like to use to secure the certificate. Once the certificate is downoaded run
16
+ # these two commands to split the PKCS#12 certificate into a public and private key.
17
+ #
18
+ # @param [String] cert_file The relative path to the SSL cert on the server.
19
+ # @param [String] cert_key_file The relative path to the SSL cert key on the server.
20
+ # @param [String] password The password for the cert key file.
21
+ # @param [Boolean] should_log if the client should log everything. This is good for development.
22
+ def initialize(cert_file, cert_key_file, password, should_log)
23
+ # @cert_file = cert_file
24
+ # @cert_key_file = cert_key_file
25
+ # @cert_key_password = password
26
+
27
+ #[:get_server_time, :get_user_info, :get_credential_info, :get_temporary_password_attributes, :poll_push_status]
28
+ @query_client = Utilities.create_client('http://webdev.cse.msu.edu/~yehanlin/vip/vipuserservices-query-1.7.wsdl', should_log, cert_file, cert_key_file, password)
29
+
30
+ #[:authenticate_user, :authenticate_user_with_push, :authenticate_credentials, :evaluate_risk, :confirm_risk, :deny_risk, :check_otp]
31
+ @auth_client = Utilities.create_client('http://webdev.cse.msu.edu/~yehanlin/vip/vipuserservices-auth-1.7.wsdl', should_log, cert_file, cert_key_file, password)
32
+
33
+ #[:create_user, :update_user, :delete_user, :clear_user_pin, :add_credential, :update_credential, :remove_credential, :set_temporary_password, :clear_temporary_password, :set_temporary_password_attributes, :send_otp, :register]
34
+ @management_client = Utilities.create_client('http://webdev.cse.msu.edu/~yehanlin/vip/vipuserservices-mgmt-1.7.wsdl', should_log, cert_file, cert_key_file, password)
35
+
36
+ @push = Push.new
37
+ @sms = SMS.new
38
+ @credential = Credential.new
39
+ @user = User.new
40
+ end
41
+
42
+
43
+ # Getter for the query client
44
+ #
45
+ # @return [Soteria.Client] The Query client
46
+ def get_query_client
47
+ @query_client
48
+ end
49
+
50
+
51
+ # Getter for the auth client
52
+ #
53
+ # @return [Soteria.Client] The Auth client
54
+ def get_auth_client
55
+ @auth_client
56
+ end
57
+
58
+
59
+ # Getter for the management client
60
+ #
61
+ # @return [Soteria.Client] The Management client
62
+ def get_management_client
63
+ @management_client
64
+ end
65
+
66
+
67
+ # Send a push notification to the specified user for authentication.
68
+ #
69
+ # @param [String] user_id Id of the user to authenticate. This is the user id that is stored in the Symantec database.
70
+ # @param [Hash] options
71
+ # @return [Hash]
72
+ def send_push(user_id, options)
73
+ @push.send_push(@auth_client, user_id, options)
74
+ end
75
+
76
+
77
+ # Polls for the status of the push notification. This is necessary because VIP does not have push support.
78
+ # This will poll until the response is no longer push in progress, then it will return a hash with the results.
79
+ #
80
+ # @param [String] transaction_id The id of the push transaction. id is in the hash returned from the send_push call
81
+ # @param [Int] interval An integer value in seconds that is the interval between polling VIP Services for a push response.
82
+ # @param [Int] time_out An integer value in seconds that is the timeout for polling. This should match the timeout that was set for the push message.
83
+ # @return [Hash] A hash with information on if the authentication was successful.
84
+ def poll_for_response(transaction_id, interval, time_out)
85
+ @push.poll_for_response(@query_client, transaction_id, interval, time_out)
86
+ end
87
+
88
+
89
+ # authenticate_with_push handles the process of sending the push to a user as well as polling for the response.
90
+ # It calls send_push, then takes the transaction id from that call and starts polling for the result. It has the
91
+ # same result as making the calls independently but requires only one call instead of two as well as handles any errors.
92
+ #
93
+ # @param [String] user_id Id of the user to authenticate. This is the user id that is stored in the Symantec database.
94
+ # @param [Int] interval An integer value in seconds that is the interval between polling VIP Services for a push response.
95
+ # @param [Int] time_out An integer value in seconds that is the timeout for polling. This should match the timeout that was set for the push message.
96
+ # @param [Hash] options
97
+ # @return [Hash] A hash with information on if the authentication was successful.
98
+ def authenticate_with_push(user_id, interval, time_out, options)
99
+ push_response = @push.send_push(@auth_client, user_id, options)
100
+
101
+ unless push_response[:success]
102
+ return push_response
103
+ end
104
+
105
+ transaction_id = push_response[:transaction_id]
106
+
107
+ @push.poll_for_response(@query_client, transaction_id, interval, time_out)
108
+ end
109
+
110
+
111
+ # Authenticate a user with a credential. A credential includes a physical token, the desktop VIP credential app or
112
+ # the mobile VIP credential app. Users must link their credential id to their user id for this authentication to work.
113
+ #
114
+ # @param [String] user_id Id of the user to authenticate. This is the user id that is stored in the Symantec database.
115
+ # @param [String] credential_code The code from the users credential that was entered into the website.
116
+ # @return [Hash] A hash with information on if the authentication was successful.
117
+ def authenticate_user_cridential(user_id, credential_code)
118
+ @credential.authenticate_user_credential(@auth_client, user_id, credential_code)
119
+ end
120
+
121
+
122
+ # Check if a otp is valid for a given credential.
123
+ #
124
+ # @param [Integer] otp The One Time Password to check if valid.
125
+ # @param [Array] credentials An array of hashes, with between 1 and 5 credentials. Each hash should contain 2 values :id - the id of the credential and :type - the type of the credential.
126
+ # @see CredentialTypes
127
+ # @return [Hash] A hash with all information about if the otp was successful
128
+ def authenticate_credentials(otp, credentials)
129
+ @credential.authenticate_credentials(@auth_client, otp, credentials)
130
+ end
131
+
132
+
133
+ # Send a sms One Time Password to a user.
134
+ #
135
+ # @param [String] user_id Id of the user to authenticate. This is the user id that is stored in the Symantec database.
136
+ # @param [Int] phone_number The phone number that the sms code should be sent to.
137
+ # @return [Hash] A hash with all the appropriate information about the status of the SMS.
138
+ def send_sms(user_id, phone_number)
139
+ @sms.send_sms(@management_client, user_id, phone_number)
140
+ end
141
+
142
+
143
+ # Check if the otp that a user entered is valid or not.
144
+ #
145
+ # @param [String] user_id Id of the user to authenticate. This is the user id that is stored in the Symantec database.
146
+ # @param [Object] otp The otp that was sent to the user via sms or voice
147
+ # @return [Hash] A hash with all information about if the otp was successful
148
+ def check_otp(user_id, otp)
149
+ @sms.check_otp(@auth_client, user_id, otp)
150
+ end
151
+
152
+
153
+ # Add a new user to the list of users in Symantec VIP database.
154
+ #
155
+ # @param [String] user_id Id of the user to create.
156
+ # @param [String] pin an optional value that is a pin for the user. The PIN may be 4 to 128 international characters in length, depending on restrictions of the PIN policy.
157
+ # @return [Hash] A hash that contains: :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
158
+ def create_user(user_id, pin)
159
+ @user.create(@management_client, user_id, pin)
160
+ end
161
+
162
+
163
+ # Delete a user from the database of Symantec VIP users.
164
+ #
165
+ # @param [String] user_id Id of the user to delete.
166
+ # @return [Hash] A hash that contains: :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
167
+ def delete_user(user_id)
168
+ @user.delete(@management_client, user_id)
169
+ end
170
+
171
+
172
+ # Use updateUser to update information about a user in VIP User Services.
173
+ #
174
+ # @param [String] user_id The unique ID for the user.
175
+ # @param [Object] options
176
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
177
+ def update_user(user_id, options)
178
+ @user.update_user(@management_client, user_id, options)
179
+ end
180
+
181
+
182
+ # Use clearUserPin to remove an assigned PIN from a user.
183
+ #
184
+ # @param [String] user_id The unique ID for the user.
185
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
186
+ def clear_user_pin(user_id)
187
+ @user.clear_user_pin(@management_client, user_id)
188
+ end
189
+
190
+
191
+ # Use setTemporaryPasswordAttributes to change the expiration date for a temporary security code you previously set.
192
+ #
193
+ # @param [String] user_id The unique ID for the user.
194
+ # @param [Object] options
195
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
196
+ def set_temp_pass_attr(user_id, options)
197
+ @user.set_temp_pass_attr(@management_client, user_id, options)
198
+ end
199
+
200
+
201
+ # Use getTemporaryPasswordAttributes to poll VIP User Services every three to five seconds to check the status of a
202
+ # push notification. The push notification is validated against the notification’s unique transaction ID.
203
+ #
204
+ # @param [String] user_id The unique ID for the user.
205
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
206
+ def get_temp_pass_attr(user_id)
207
+ @user.get_temp_pass_attr(@query_client, user_id)
208
+ end
209
+
210
+
211
+ # Use setTemporaryPassword to set a temporary security code for a user. You can optionally set an
212
+ # expiration date for the security code, or set it for one-time use only. The request requires the user ID and
213
+ # optionally, the temporary security code string. If you do not provide a security code, VIP User Services generates
214
+ # one for you.
215
+ #
216
+ # @param [String] user_id The unique ID for the user.
217
+ # @param [Int] phone The phone or mobile device number to which the VIP User Service should deliver the security code.
218
+ # @param [Hash] options
219
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
220
+ def set_temp_password(user_id, phone, options)
221
+ @user.set_temp_password(@management_client, user_id, phone, options)
222
+ end
223
+
224
+
225
+ # Use clearTemporaryPassword to add users to VIP User Services.to remove a temporary security code from a user. If the
226
+ # user attempts to use a temporary security that has been cleared, VIP User Services returns an error stating the
227
+ # security code is not set. If the user validates a security code using a valid credential, any temporary security
228
+ # code that is set for that user is automatically cleared.
229
+ #
230
+ # @param [String] user_id The unique ID for the user.
231
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
232
+ def clear_temp_pass(user_id)
233
+ @user.clear_temp_pass(@management_client, user_id)
234
+ end
235
+
236
+
237
+ # Use getCredentialInfo to get the credential that was last bound to the user, When the credential was last authenticated and
238
+ # the friendly name for the credential.
239
+ #
240
+ # @param [String] credential_id The unique ID for the credential.
241
+ # @param [String] credential_type The type of the credential.
242
+ # @param [Boolean] include_push If this flag is present and set to be true, the response contains all the push attributes in the field pushAttributes.
243
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes. Also contains :credential which is a hash with info about the credential.
244
+ def get_credential_info(credential_id, credential_type, include_push)
245
+ @credential.get_credential_info(@query_client, credential_id, credential_type, include_push)
246
+ end
247
+
248
+
249
+ # Use getServerTime to obtain the current server time.
250
+ #
251
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes. Also contains :time which is current server time.
252
+ def get_server_time()
253
+ @credential.get_server_time(@query_client)
254
+ end
255
+
256
+
257
+ # Add a credential to an existing user in the Symantec VIP database.
258
+ #
259
+ # @param [String] user_id Id of the user to add a credential to.
260
+ # @param [String] credential_id
261
+ # @param [String] credential_type must be one of the keys to the credential types from the Utilities class.
262
+ # @see Utilities::CREDENTIAL_TYPES
263
+ # @param [Hash] options A hash that can contain the following. :name adds a friendly name to the credential added to vip, :otp sends a otp from the credential with the request to verify that the user actually has possession of the credential
264
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
265
+ def add_credential(user_id, credential_id, credential_type, options)
266
+ @user.add_credential(@management_client, user_id, credential_id, credential_type, options)
267
+ end
268
+
269
+
270
+ # Get all the credentials that have been last bound to a user or the last authentication, as well as the friendly
271
+ # name for the user's credential.
272
+ #
273
+ # Returns an array with a hash for every credential that can be used as a second factor authentication option a user has. Each hash contains:
274
+ # * :type - The type of the credential.
275
+ # * :enabled - If the credential is enabled.
276
+ # * :friendly_name - The name the user gave the credential.
277
+ # * :push - A boolean if push is enabled for the credential.
278
+ # * :credential_id - The id of the credential. This is useful for SMS auth.
279
+ #
280
+ # @param [String] user_id Id of the user to get information about.
281
+ # @param [Boolean] include_push If the users push details should be returned.
282
+ def get_user_info(user_id, include_push)
283
+ @user.get_user_info(@query_client, user_id, include_push)
284
+ end
285
+
286
+
287
+ # Call to register a SMS credential to the VIP account. Before a user can add a SMS credential to their account
288
+ # it must first exist in the organizations list of credentials.
289
+ #
290
+ # @param [Integer] phone_number The phone number credential to register.
291
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
292
+ def register_sms(phone_number)
293
+ @credential.register_sms(@management_client, phone_number)
294
+ end
295
+
296
+
297
+ # Remove a credential from a given user. If the Device deletion policy for Remembered Devices is set to Admin Only,
298
+ # credentials can only be removed through VIP Manager. The removeCredential API will return the error 6010: This
299
+ # account is not authorized to perform the requested operation
300
+ #
301
+ # @param [String] user_id Id of the user to remove a credential from.
302
+ # @param [String] credential_id Unique identifier of the credential.
303
+ # @param [String] credential_type must be one of the keys to the credential types from the Utilities class.
304
+ # @see Utilities::CREDENTIAL_TYPES
305
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
306
+ def remove_credential(user_id, credential_id, credential_type)
307
+ puts @user.remove_credential(@management_client, user_id, credential_id, credential_type)
308
+ end
309
+
310
+
311
+ # Updates the friendly name of a users credential.
312
+ #
313
+ # @param [String] user_id Id of the user to remove a credential from.
314
+ # @param [String] credential_id Unique identifier of the credential.
315
+ # @param [String] credential_type must be one of the keys to the credential types from the Utilities class.
316
+ # @see Utilities::CREDENTIAL_TYPES
317
+ # @param [Object] name A user-defined name to identify the credential.
318
+ # @return [Hash] A hash that contains; :success a boolean if the call succeeded, :message a string with any error message, :id the id of the call for debugging purposes
319
+ def update_credential(user_id, credential_id, credential_type, name)
320
+ puts @user.update_credential(@management_client, user_id, credential_id, credential_type, name)
321
+ end
322
+
323
+
324
+ end
325
+
326
+ end