printos 0.3.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 230957d84ddad83f0a55858924a71927273b0a7c
4
+ data.tar.gz: 426e66437488d7f3cef2b431dccde5ac0e22340c
5
+ SHA512:
6
+ metadata.gz: d445d62246be55d5156abeb786236e6a1a0ce6d493a73689d0d727cefd62afd5fd684b86070dcd505d248b85af1fb2119ac2210d3b93a2aae78086b3bf221a22
7
+ data.tar.gz: f6b661becb78f75afbfdd84ea1e0e251648d074655849f2b4e76929d531990d4dd5ebc5f4f235d7b91e0c01c6582fce1dd564de50402d9803d2ecb04bafb05d6
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ .idea/
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ printos
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.3.1
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.1.7
5
+ before_install: gem install bundler -v 1.16.0
@@ -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 ptp-green@hp.com. 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,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ ruby '2.3.1'
4
+
5
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,128 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ printos (0.3.13)
5
+ request_store (~> 1.3.2)
6
+ rest-client (~> 2.0.2)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionpack (4.2.10)
12
+ actionview (= 4.2.10)
13
+ activesupport (= 4.2.10)
14
+ rack (~> 1.6)
15
+ rack-test (~> 0.6.2)
16
+ rails-dom-testing (~> 1.0, >= 1.0.5)
17
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
18
+ actionview (4.2.10)
19
+ activesupport (= 4.2.10)
20
+ builder (~> 3.1)
21
+ erubis (~> 2.7.0)
22
+ rails-dom-testing (~> 1.0, >= 1.0.5)
23
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
24
+ activesupport (4.2.10)
25
+ i18n (~> 0.7)
26
+ minitest (~> 5.1)
27
+ thread_safe (~> 0.3, >= 0.3.4)
28
+ tzinfo (~> 1.1)
29
+ builder (3.2.3)
30
+ concurrent-ruby (1.0.5)
31
+ crass (1.0.2)
32
+ diff-lcs (1.3)
33
+ docile (1.1.5)
34
+ domain_name (0.5.20170404)
35
+ unf (>= 0.0.5, < 1.0.0)
36
+ erubis (2.7.0)
37
+ http-cookie (1.0.3)
38
+ domain_name (~> 0.5)
39
+ i18n (0.9.1)
40
+ concurrent-ruby (~> 1.0)
41
+ json (2.1.0)
42
+ loofah (2.1.1)
43
+ crass (~> 1.0.2)
44
+ nokogiri (>= 1.5.9)
45
+ mime-types (3.1)
46
+ mime-types-data (~> 3.2015)
47
+ mime-types-data (3.2016.0521)
48
+ mini_portile2 (2.3.0)
49
+ minitest (5.10.3)
50
+ netrc (0.11.0)
51
+ nokogiri (1.8.1)
52
+ mini_portile2 (~> 2.3.0)
53
+ pivotal_git_scripts (1.4.0)
54
+ rack (1.6.8)
55
+ rack-test (0.6.3)
56
+ rack (>= 1.0)
57
+ rails-deprecated_sanitizer (1.0.3)
58
+ activesupport (>= 4.2.0.alpha)
59
+ rails-dom-testing (1.0.8)
60
+ activesupport (>= 4.2.0.beta, < 5.0)
61
+ nokogiri (~> 1.6)
62
+ rails-deprecated_sanitizer (>= 1.0.1)
63
+ rails-html-sanitizer (1.0.3)
64
+ loofah (~> 2.0)
65
+ railties (4.2.10)
66
+ actionpack (= 4.2.10)
67
+ activesupport (= 4.2.10)
68
+ rake (>= 0.8.7)
69
+ thor (>= 0.18.1, < 2.0)
70
+ rake (10.5.0)
71
+ request_store (1.3.2)
72
+ rest-client (2.0.2)
73
+ http-cookie (>= 1.0.2, < 2.0)
74
+ mime-types (>= 1.16, < 4.0)
75
+ netrc (~> 0.8)
76
+ rspec (3.7.0)
77
+ rspec-core (~> 3.7.0)
78
+ rspec-expectations (~> 3.7.0)
79
+ rspec-mocks (~> 3.7.0)
80
+ rspec-core (3.7.0)
81
+ rspec-support (~> 3.7.0)
82
+ rspec-expectations (3.7.0)
83
+ diff-lcs (>= 1.2.0, < 2.0)
84
+ rspec-support (~> 3.7.0)
85
+ rspec-mocks (3.7.0)
86
+ diff-lcs (>= 1.2.0, < 2.0)
87
+ rspec-support (~> 3.7.0)
88
+ rspec-rails (3.7.1)
89
+ actionpack (>= 3.0)
90
+ activesupport (>= 3.0)
91
+ railties (>= 3.0)
92
+ rspec-core (~> 3.7.0)
93
+ rspec-expectations (~> 3.7.0)
94
+ rspec-mocks (~> 3.7.0)
95
+ rspec-support (~> 3.7.0)
96
+ rspec-support (3.7.0)
97
+ simplecov (0.15.1)
98
+ docile (~> 1.1.0)
99
+ json (>= 1.8, < 3)
100
+ simplecov-html (~> 0.10.0)
101
+ simplecov-html (0.10.2)
102
+ thor (0.20.0)
103
+ thread_safe (0.3.6)
104
+ tzinfo (1.2.4)
105
+ thread_safe (~> 0.1)
106
+ unf (0.1.4)
107
+ unf_ext
108
+ unf_ext (0.0.7.4)
109
+
110
+ PLATFORMS
111
+ ruby
112
+
113
+ DEPENDENCIES
114
+ actionpack (~> 4.2.7)
115
+ activesupport (~> 4.2.7)
116
+ bundler (~> 1.16)
117
+ pivotal_git_scripts (~> 1.4.0)
118
+ printos!
119
+ rake (~> 10.0)
120
+ rspec (~> 3.7.0)
121
+ rspec-rails (~> 3.7.0)
122
+ simplecov (~> 0.15.1)
123
+
124
+ RUBY VERSION
125
+ ruby 2.3.1p112
126
+
127
+ BUNDLED WITH
128
+ 1.16.1
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 ptp-green
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,43 @@
1
+ # Printos
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/printos`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'printos'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install printos
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ 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.
30
+
31
+ 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).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/printos. 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.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
+
41
+ ## Code of Conduct
42
+
43
+ Everyone interacting in the Printos project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/printos/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'printos'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require 'pry'
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,145 @@
1
+ require 'uri'
2
+
3
+ module Printos
4
+
5
+ API_BASE_PATH = 'api/aaa/v3'
6
+
7
+ module AaaOrganization
8
+
9
+ ORGANIZATIONS_PATH = "#{API_BASE_PATH}/organizations"
10
+
11
+ def organization
12
+ get_resource(ORGANIZATIONS_PATH)
13
+ end
14
+
15
+ def update_organization(payload)
16
+ put_resource(ORGANIZATIONS_PATH, payload)
17
+ end
18
+ end
19
+
20
+ module AaaOrganizationSite
21
+
22
+ ORGANIZATION_SITES_PATH = "#{API_BASE_PATH}/organizations/sites"
23
+
24
+ def sites
25
+ get_resource(ORGANIZATION_SITES_PATH)
26
+ end
27
+
28
+ def site(resource_id)
29
+ get_resource("#{ORGANIZATION_SITES_PATH}/#{resource_id}")
30
+ end
31
+
32
+ def create_site(payload)
33
+ post_resource(ORGANIZATION_SITES_PATH, payload)
34
+ end
35
+
36
+ def update_site(resource_id, payload)
37
+ put_resource("#{ORGANIZATION_SITES_PATH}/#{resource_id}", payload)
38
+ end
39
+ end
40
+
41
+ module AaaOrganizationAddress
42
+
43
+ ORGANIZATION_ADDRESSES_PATH = "#{API_BASE_PATH}/organizations/addresses"
44
+
45
+ def addresses
46
+ get_resource(ORGANIZATION_ADDRESSES_PATH)
47
+ end
48
+
49
+ def address(resource_id)
50
+ get_resource("#{ORGANIZATION_ADDRESSES_PATH}/#{resource_id}")
51
+ end
52
+
53
+ def create_address(payload)
54
+ post_resource(ORGANIZATION_ADDRESSES_PATH, payload)
55
+ end
56
+
57
+ def update_address(resource_id, payload)
58
+ put_resource("#{ORGANIZATION_ADDRESSES_PATH}/#{resource_id}", payload)
59
+ end
60
+ end
61
+
62
+ class AaaService < BaseService
63
+
64
+ extend AaaOrganization
65
+ extend AaaOrganizationSite
66
+ extend AaaOrganizationAddress
67
+
68
+ def self.user
69
+ get_resource("#{API_BASE_PATH}/users")
70
+ end
71
+
72
+ def self.device(resource_id)
73
+ get_resource("#{API_BASE_PATH}/organizations/devices/#{resource_id}")
74
+ end
75
+
76
+ def self.devices
77
+ get_resource("#{API_BASE_PATH}/organizations/devices/v2")
78
+ end
79
+
80
+ def self.admin_context
81
+ get_resource("#{API_BASE_PATH}/admin/context")
82
+ end
83
+
84
+ def self.admin_device(resource_id)
85
+ get_resource("#{API_BASE_PATH}/admin/devices/#{resource_id}")
86
+ end
87
+
88
+ def self.admin_device_gbu_organizations(offset, limit, device_gbu_filter, device_type_filter)
89
+ uri = URI.join("#{API_BASE_PATH}/admin/devicegbu/organizations", org_id)
90
+ query_params = URI.decode_www_form(uri.query || '')
91
+ query_params << ['offset', offset] unless offset.blank?
92
+ query_params << ['limit', limit] unless limit.blank?
93
+ query_params << ['deviceType', device_type_filter] unless device_type_filter.blank?
94
+ query_params << ['deviceGBU', device_gbu_filter] unless device_gbu_filter.blank?
95
+ uri.query = URI.encode_www_form(query_params)
96
+
97
+ get_resource(uri.to_s)
98
+ end
99
+
100
+ def self.admin_organization(org_id)
101
+ get_resource("#{API_BASE_PATH}/admin/organizations/#{org_id}")
102
+ end
103
+
104
+ def self.admin_organizations(offset, limit, name_filter, gbu_filter)
105
+ uri = URI.parse("#{API_BASE_PATH}/admin/organizations")
106
+ query_params = URI.decode_www_form(uri.query || '')
107
+ query_params << ['offset', offset] unless offset.blank?
108
+ query_params << ['limit', limit] unless limit.blank?
109
+ query_params << ['name', name_filter] unless name_filter.blank?
110
+ query_params << ['gbu', gbu_filter] unless gbu_filter.blank?
111
+ uri.query = URI.encode_www_form(query_params)
112
+
113
+ get_resource(uri.to_s)
114
+ end
115
+
116
+ def self.admin_site(org_id, resource_id)
117
+ # AAA v3 does not have a method to directly retrieve a site by resource id
118
+ # so we have to get all sites for the organization and select it
119
+ sites = get_resource("#{API_BASE_PATH}/admin/organizations/#{org_id}/sites")
120
+
121
+ sites[:sites].select { |site| site[:siteId] == resource_id }.first
122
+ end
123
+
124
+ def self.authorize(payload, as_service=false)
125
+ # The authorization API implementation is odd in that a response code of 412 is returned to indicate
126
+ # that the service token has expired (normally 401 would be used)
127
+ service_token_expired_code = 412
128
+
129
+ begin
130
+ parse PrintosRestClient.post("#{API_BASE_PATH}/authorize", payload, as_service, service_token_expired_code)
131
+ rescue RestClient::Unauthorized
132
+ Printos.config.logger.error('User token is invalid.')
133
+ {}
134
+ end
135
+ end
136
+
137
+ def self.system_roles(as_service=false)
138
+ get_resource("#{API_BASE_PATH}/systemroles", as_service)
139
+ end
140
+
141
+ def self.system_role_users(org_id, role_id)
142
+ get_resource("#{API_BASE_PATH}/admin/organizations/#{org_id}/users/systemroles/#{role_id}", true)
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,20 @@
1
+ module Printos
2
+ class BaseService
3
+
4
+ def self.get_resource(resource_url, as_service=false)
5
+ parse(PrintosRestClient.get(resource_url, as_service))
6
+ end
7
+
8
+ def self.post_resource(resource_url, payload, as_service=false)
9
+ parse(PrintosRestClient.post(resource_url, payload, as_service))
10
+ end
11
+
12
+ def self.put_resource(resource_url, payload, as_service=false)
13
+ parse(PrintosRestClient.put(resource_url, payload, as_service))
14
+ end
15
+
16
+ def self.parse(response)
17
+ JSON.parse(response.body, symbolize_names: :true) rescue nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ module Printos
2
+
3
+ require 'ostruct'
4
+
5
+ class << self
6
+
7
+ def config
8
+ @config ||= OpenStruct.new(default_params)
9
+ end
10
+
11
+ def configure
12
+ yield config
13
+ end
14
+
15
+ private
16
+
17
+ def default_params
18
+ if defined?(Rails)
19
+ YAML.load_file(File.join(Rails.root, 'config', 'printos.yml')) rescue {}
20
+ else
21
+ {}
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,63 @@
1
+ module Printos
2
+
3
+ class EmailService < BaseService
4
+
5
+ API_BASE = 'api/email-service/v1'
6
+
7
+ def self.email_role(org_id, role_name, subject, body)
8
+ user_ids = role_users(org_id, role_name)
9
+
10
+ if user_ids && user_ids.size > 0
11
+ email_users(user_ids, subject, body)
12
+ end
13
+ end
14
+
15
+ def self.email_users(user_ids, subject, body)
16
+ pay_load = {
17
+ userIds: user_ids,
18
+ emailInfo: {
19
+ subject: subject,
20
+ body: body
21
+ }
22
+ }
23
+ post_resource("#{API_BASE}/emails/users", pay_load, true)
24
+ end
25
+
26
+ def self.invite_user(cust_id, email, fname = "", lname = "")
27
+ payload = {
28
+ invitation: {
29
+ email: email,
30
+ firstName: fname,
31
+ lastName: lname,
32
+ internalId: {
33
+ gbu: 'ThreeD',
34
+ gbuInternalId: cust_id,
35
+ internalIdType: 'PSPId'
36
+ },
37
+ organizationType: 'PSP',
38
+ invitationType: 'PSP_ADMIN',
39
+ subType: '3dpaas',
40
+ ext_payload: {
41
+ onboard: { redirectAppId: '3dpaas', '3dpaas' => { customerRef: cust_id } }
42
+ }
43
+ }
44
+ }
45
+ post_resource("#{API_BASE}/invitations", payload, true)
46
+ end
47
+
48
+ private
49
+
50
+ def self.role_users(org_id, role_name)
51
+ system_role_users = Printos::AaaService.system_role_users(org_id, role_id(role_name))
52
+ system_role_users[:users].map {|user| user[:userId]}
53
+ end
54
+
55
+ def self.role_id(role_name)
56
+ response = Printos::AaaService.system_roles(true)
57
+ id = response[:systemRoles].select {|role| role[:name] == role_name}&.first&.dig(:id)
58
+
59
+ raise "Unable to lookup id for role '#{role_name}'" unless (id)
60
+ id
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,43 @@
1
+ module Printos
2
+ module Helpers
3
+
4
+ def authorization
5
+ @authorization ||= PrintosClient.get_instance.authorization
6
+ end
7
+
8
+ def user_permissions
9
+ @permissions ||= authorization[:permissions]&.map { |p| p[:name] }
10
+ end
11
+
12
+ def has_admin_permission?
13
+ user_permissions&.include?('admin')
14
+ end
15
+
16
+ def check_admin_permission
17
+ redirect_to signin_url unless has_admin_permission?
18
+ end
19
+
20
+ def printos_login
21
+ authenticated = false
22
+ token = cookies[Printos.config.auth_token_key]
23
+ if token
24
+ begin
25
+ PrintosClient.set_instance(token)
26
+ authenticated = user_permissions.any?
27
+ rescue RestClient::Unauthorized
28
+ end
29
+ end
30
+ unless authenticated
31
+ if request.format.json?
32
+ render json: '', status: 401, head: :no_content
33
+ else
34
+ redirect_to signin_url
35
+ end
36
+ end
37
+ end
38
+
39
+ def signin_url
40
+ "#{Printos.config.api_host}/start/#/signin"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ module Printos
2
+
3
+ class NotificationService < BaseService
4
+
5
+ API_BASE = 'api/notification-service/v1'
6
+
7
+ def self.send_notification(event_name, link_label, entity_id, sub_value, sub_value_params, org_id)
8
+
9
+ Printos.config.logger.debug { "Sending notification: #{{
10
+ event_name: event_name,
11
+ link_label: link_label,
12
+ entity_id: entity_id,
13
+ sub_value: sub_value,
14
+ sub_value_params: sub_value_params,
15
+ org_id: org_id}}" }
16
+
17
+ body = {
18
+ 'eventName': event_name,
19
+ 'linkLabel': link_label,
20
+ 'entityId': entity_id,
21
+ 'subValue': sub_value,
22
+ 'subValueParams': sub_value_params,
23
+ 'orgId': org_id,
24
+ 'timestamp': Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
25
+ }
26
+
27
+ post_resource("#{API_BASE}/event/notify", body, true)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,110 @@
1
+ require 'rest-client'
2
+
3
+ class PrintosClient
4
+
5
+ API_BASE = 'api/aaa/v3'
6
+
7
+ USER_PERMISSIONS=%w(admin user hpAdmin).freeze
8
+
9
+ def self.set_instance(token)
10
+ @token = token
11
+ ::RequestStore.store[:printos_token] = token
12
+ get_instance
13
+ end
14
+
15
+ def self.get_instance
16
+ ::RequestStore.store[:print_os_client] ||= PrintosClient.new(@token)
17
+ end
18
+
19
+ def logged_in?
20
+ @token.present?
21
+ end
22
+
23
+ def user
24
+ @user ||= Printos::AaaService.user
25
+ end
26
+
27
+ def organization
28
+ @org ||= Printos::AaaService.organization
29
+ end
30
+
31
+ def site(resource_id)
32
+ @site_resource[resource_id] ||= Printos::AaaService.site(resource_id)
33
+ end
34
+
35
+ def sites
36
+ @sites ||= Printos::AaaService.sites
37
+ end
38
+
39
+ def printer(resource_id)
40
+ @printer_resource[resource_id] ||= Printos::AaaService.device(resource_id)
41
+ end
42
+
43
+ def devices
44
+ org = organization
45
+ site_id = org[:organizationId]
46
+
47
+ @devices ||= Printos::AaaService.devices
48
+ device_list = @devices[:devicesWithContext].first[:devices]
49
+
50
+ device_list.select { |device| device[:site] && device[:site][:organizationId] == site_id }
51
+ end
52
+
53
+ def authorization
54
+ body = {
55
+ requestToken: @token,
56
+ permissions: USER_PERMISSIONS,
57
+ checkedObjectName: 'checkSuluPermissions'
58
+ }
59
+
60
+ @authorization ||= Printos::AaaService.authorize(body, true)
61
+
62
+ # Cache user
63
+ @user = @authorization[:user] unless @authorization[:user].nil?
64
+
65
+ @authorization
66
+ end
67
+
68
+ def admin_context
69
+ Printos::AaaService.admin_context
70
+ end
71
+
72
+ def admin_device_gbu_organizations(offset, limit, device_gbu_filter, device_type_filter)
73
+ Printos::AaaService.admin_device_gbu_organizations(offset, limit, device_gbu_filter, device_type_filter)
74
+ end
75
+
76
+ def admin_organization(org_id)
77
+ Printos::AaaService.admin_organization(org_id)
78
+ end
79
+
80
+ def admin_organizations(offset, limit, name_filter, gbu_filter)
81
+ Printos::AaaService.admin_organizations(offset, limit, name_filter, gbu_filter)
82
+ end
83
+
84
+ def admin_printer(resource_id)
85
+ @printer_resource[resource_id] ||= Printos::AaaService.admin_device(resource_id)
86
+ end
87
+
88
+ def admin_site(org_id, resource_id)
89
+ @site_resource[resource_id] ||= Printos::AaaService.admin_site(org_id, resource_id)
90
+ end
91
+
92
+ def update_organization(payload)
93
+ Printos::AaaService.update_organization(payload)
94
+ end
95
+
96
+ def create_site(payload)
97
+ Printos::AaaService.create_site(payload)
98
+ end
99
+
100
+ def update_site(resource_id, payload)
101
+ Printos::AaaService.update_site(resource_id, payload)
102
+ end
103
+
104
+ private
105
+ def initialize(token)
106
+ @token = token
107
+ @site_resource = {}
108
+ @printer_resource = {}
109
+ end
110
+ end
@@ -0,0 +1,60 @@
1
+ module Printos
2
+
3
+ class PrintosRestClient
4
+
5
+ # Default reponse code that is expected from PrintOS when a service token has expired
6
+ SERVICE_TOKEN_EXPIRED_CODE = 401
7
+
8
+ def self.get(url, as_service, expired_code=SERVICE_TOKEN_EXPIRED_CODE)
9
+ execute(:get, url, {}, as_service, expired_code)
10
+ end
11
+
12
+ def self.post(url, payload, as_service, expired_code=SERVICE_TOKEN_EXPIRED_CODE)
13
+ execute(:post, url, payload, as_service, expired_code)
14
+ end
15
+
16
+ def self.put(url, payload, as_service, expired_code=SERVICE_TOKEN_EXPIRED_CODE)
17
+ execute(:put, url, payload, as_service, expired_code)
18
+ end
19
+
20
+ def self.execute(method, url, payload, as_service, service_token_expired_code, allow_retry=true)
21
+ return nil if url.nil?
22
+
23
+ if as_service
24
+ service_token = PrintosServiceToken.get_token
25
+ token = service_token.auth_token
26
+ else
27
+ token = ::RequestStore.store[:printos_token]
28
+ end
29
+
30
+ Printos.config.logger.debug { "PrintOS API request: method=#{method}, url=#{url}, as_service=#{as_service}, payload=#{payload}" }
31
+
32
+ begin
33
+ response = RestClient::Request.execute(
34
+ method: method,
35
+ url: "#{Printos.config.api_host}/#{url}",
36
+ payload: payload.to_json,
37
+ headers: {
38
+ :content_type => :json,
39
+ :accept => :json,
40
+ :cookies => {Printos.config.auth_token_key => token}
41
+ }
42
+ )
43
+
44
+ Printos.config.logger.debug { "PrintOS API response: status_code#{response.code}, body=#{response.body}" }
45
+ response
46
+ rescue RestClient::ExceptionWithResponse => e
47
+ response = e.response
48
+ Printos.config.logger.debug { "PrintOS API response: status_code#{response.code}, body=#{response.body}" }
49
+
50
+ if as_service && allow_retry && response.code == service_token_expired_code
51
+ Printos.config.logger.error('Service token is invalid. Will reset the token and retry request.')
52
+ PrintosServiceToken.reset_token service_token
53
+ execute(method, url, payload, as_service, service_token_expired_code, false)
54
+ else
55
+ raise
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,78 @@
1
+ class PrintosServiceToken
2
+
3
+ MUTEX = Mutex.new
4
+
5
+ attr_reader :auth_token
6
+
7
+ # Get an authentication token which can be used to login to PrintOS as
8
+ # a Sulu service account.
9
+ def self.get_token
10
+
11
+ # Quick check for existing cached token
12
+ result = @token
13
+ return result if result.present?
14
+
15
+ # Synchronized check for cached token
16
+ MUTEX.synchronize do
17
+ return @token if @token.present?
18
+
19
+ # Acquire new token
20
+ @token = acquire_service_token
21
+ end
22
+ end
23
+
24
+ # Reset the specified service token.
25
+ # Call this method if a previously acquired token is bad (e.g., expired, etc.)
26
+ def self.reset_token(service_token)
27
+ raise 'Invalid token' unless service_token.instance_of? PrintosServiceToken
28
+
29
+ MUTEX.synchronize do
30
+ #Only reset if the tokens match. It is possible that another thread
31
+ #has already reset the token and do not want to reset when unnecessary.
32
+ if @token != nil && @token.equal?(service_token)
33
+ Printos.config.logger.debug 'Resetting printos service authentication token.'
34
+
35
+ # Set token to nil so that other threads stop using the old token while we
36
+ # acquire a new one
37
+ @token = nil
38
+ else
39
+ Printos.config.logger.debug 'Not going to reset printos service token, looks like it has already been reset.'
40
+ end
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def self.acquire_service_token
47
+ body = {
48
+ login: Printos.config.service_user,
49
+ password: Printos.config.service_password
50
+ }
51
+
52
+ url = "#{Printos.config.api_host}/#{PrintosClient::API_BASE}/services/login"
53
+ response = RestClient.post(url, body.to_json, :content_type => 'application/json')
54
+
55
+ if response.code == 401
56
+ Printos.config.logger.error 'Printos service login failed with 401.'
57
+ raise "Unauthorized: #{response.body}"
58
+ end
59
+
60
+ result = {}
61
+ result = JSON.parse(response.body, symbolize_names: :true) if response.body.present?
62
+ auth_token = result[:authToken]
63
+
64
+ unless auth_token.present?
65
+ Printos.config.logger.error 'Printos service login failed. Authentication token not found in response.'
66
+ raise "Unauthorized: #{response.body}"
67
+ end
68
+
69
+ PrintosServiceToken.new(auth_token)
70
+ end
71
+
72
+ def initialize(token)
73
+ # For now just keep track of the printos auth_token. In future we can expand
74
+ # to capture the token expiration time and optimize to fetch a new token
75
+ # before token expires.
76
+ @auth_token = token
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module Printos
2
+ VERSION = '0.3.13'
3
+ end
data/lib/printos.rb ADDED
@@ -0,0 +1,17 @@
1
+ require_relative 'printos/version'
2
+ require_relative 'printos/configuration'
3
+ require_relative 'printos/base_service'
4
+ require_relative 'printos/aaa_service'
5
+ require_relative 'printos/printos_client'
6
+ require_relative 'printos/email_service'
7
+ require_relative 'printos/notification_service'
8
+ require_relative 'printos/printos_rest_client'
9
+ require_relative 'printos/printos_service_token'
10
+ require_relative 'printos/helpers'
11
+
12
+ require 'yaml'
13
+ require 'request_store'
14
+
15
+ module Printos
16
+
17
+ end
data/printos.gemspec ADDED
@@ -0,0 +1,35 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'printos/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'printos'
8
+ spec.version = Printos::VERSION
9
+ spec.authors = %w('Dalmir da Silva' 'Marlon Lopes')
10
+ spec.email = %w(dalmirsilva@hp.com marlon.lopes@hp.com)
11
+
12
+ spec.summary = %q{PrintOS gem that wraps the API.}
13
+ spec.description = %q{PrintOS gem that wraps the API.}
14
+ spec.homepage = 'https://github.com/IPGPTP/printos'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.16'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.7.0'
25
+ spec.add_development_dependency 'simplecov', '~> 0.15.1'
26
+
27
+ spec.add_development_dependency 'rspec-rails', '~> 3.7.0'
28
+ spec.add_development_dependency 'actionpack', '~> 4.2.7'
29
+ spec.add_development_dependency 'activesupport', '~> 4.2.7'
30
+
31
+ spec.add_development_dependency 'pivotal_git_scripts', '~> 1.4.0'
32
+
33
+ spec.add_runtime_dependency 'request_store', '~> 1.3.2'
34
+ spec.add_runtime_dependency 'rest-client', '~> 2.0.2'
35
+ end
metadata ADDED
@@ -0,0 +1,214 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: printos
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.13
5
+ platform: ruby
6
+ authors:
7
+ - "'Dalmir"
8
+ - da
9
+ - Silva'
10
+ - "'Marlon"
11
+ - Lopes'
12
+ autorequire:
13
+ bindir: exe
14
+ cert_chain: []
15
+ date: 2018-03-27 00:00:00.000000000 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: bundler
19
+ requirement: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "~>"
22
+ - !ruby/object:Gem::Version
23
+ version: '1.16'
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '1.16'
31
+ - !ruby/object:Gem::Dependency
32
+ name: rake
33
+ requirement: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - "~>"
36
+ - !ruby/object:Gem::Version
37
+ version: '10.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '10.0'
45
+ - !ruby/object:Gem::Dependency
46
+ name: rspec
47
+ requirement: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - "~>"
50
+ - !ruby/object:Gem::Version
51
+ version: 3.7.0
52
+ type: :development
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: 3.7.0
59
+ - !ruby/object:Gem::Dependency
60
+ name: simplecov
61
+ requirement: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: 0.15.1
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: 0.15.1
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec-rails
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: 3.7.0
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: 3.7.0
87
+ - !ruby/object:Gem::Dependency
88
+ name: actionpack
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: 4.2.7
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: 4.2.7
101
+ - !ruby/object:Gem::Dependency
102
+ name: activesupport
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: 4.2.7
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: 4.2.7
115
+ - !ruby/object:Gem::Dependency
116
+ name: pivotal_git_scripts
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: 1.4.0
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: 1.4.0
129
+ - !ruby/object:Gem::Dependency
130
+ name: request_store
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: 1.3.2
136
+ type: :runtime
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: 1.3.2
143
+ - !ruby/object:Gem::Dependency
144
+ name: rest-client
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: 2.0.2
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - "~>"
155
+ - !ruby/object:Gem::Version
156
+ version: 2.0.2
157
+ description: PrintOS gem that wraps the API.
158
+ email:
159
+ - dalmirsilva@hp.com
160
+ - marlon.lopes@hp.com
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - ".gitignore"
166
+ - ".rspec"
167
+ - ".ruby-gemset"
168
+ - ".ruby-version"
169
+ - ".travis.yml"
170
+ - CODE_OF_CONDUCT.md
171
+ - Gemfile
172
+ - Gemfile.lock
173
+ - LICENSE.txt
174
+ - README.md
175
+ - Rakefile
176
+ - bin/console
177
+ - bin/setup
178
+ - lib/printos.rb
179
+ - lib/printos/aaa_service.rb
180
+ - lib/printos/base_service.rb
181
+ - lib/printos/configuration.rb
182
+ - lib/printos/email_service.rb
183
+ - lib/printos/helpers.rb
184
+ - lib/printos/notification_service.rb
185
+ - lib/printos/printos_client.rb
186
+ - lib/printos/printos_rest_client.rb
187
+ - lib/printos/printos_service_token.rb
188
+ - lib/printos/version.rb
189
+ - printos.gemspec
190
+ homepage: https://github.com/IPGPTP/printos
191
+ licenses:
192
+ - MIT
193
+ metadata: {}
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ requirements: []
209
+ rubyforge_project:
210
+ rubygems_version: 2.6.10
211
+ signing_key:
212
+ specification_version: 4
213
+ summary: PrintOS gem that wraps the API.
214
+ test_files: []