jive_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/jive_rails/application.js +13 -0
  6. data/app/assets/javascripts/jive_rails/oauth2client.js +182 -0
  7. data/app/assets/stylesheets/jive_rails/addons.css +4 -0
  8. data/app/assets/stylesheets/jive_rails/application.css +15 -0
  9. data/app/assets/stylesheets/jive_rails/oauth.css +4 -0
  10. data/app/assets/stylesheets/jive_rails/tiles.css +4 -0
  11. data/app/controllers/jive_rails/addons_controller.rb +48 -0
  12. data/app/controllers/jive_rails/application_controller.rb +4 -0
  13. data/app/controllers/jive_rails/oauth_controller.rb +101 -0
  14. data/app/controllers/jive_rails/tiles_controller.rb +51 -0
  15. data/app/helpers/jive_rails/addons_helper.rb +4 -0
  16. data/app/helpers/jive_rails/application_helper.rb +4 -0
  17. data/app/helpers/jive_rails/oauth_helper.rb +4 -0
  18. data/app/helpers/jive_rails/tiles_helper.rb +4 -0
  19. data/app/models/jive_rails/add_on.rb +4 -0
  20. data/app/views/jive_rails/oauth/authorizeUrl.json +0 -0
  21. data/app/views/jive_rails/oauth/oauth2Callback.html.erb +9 -0
  22. data/app/views/jive_rails/oauth/oauth2Callback.json +0 -0
  23. data/config/routes.rb +10 -0
  24. data/db/migrate/20150718193211_create_jive_rails_add_ons.rb +16 -0
  25. data/lib/jive_rails.rb +4 -0
  26. data/lib/jive_rails/engine.rb +5 -0
  27. data/lib/jive_rails/version.rb +3 -0
  28. data/lib/tasks/jive_rails_tasks.rake +4 -0
  29. data/test/controllers/jive_rails/addons_controller_test.rb +13 -0
  30. data/test/controllers/jive_rails/oauth_controller_test.rb +13 -0
  31. data/test/controllers/jive_rails/tiles_controller_test.rb +13 -0
  32. data/test/dummy/README.rdoc +28 -0
  33. data/test/dummy/Rakefile +6 -0
  34. data/test/dummy/app/assets/javascripts/application.js +13 -0
  35. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  36. data/test/dummy/app/controllers/application_controller.rb +5 -0
  37. data/test/dummy/app/helpers/application_helper.rb +2 -0
  38. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  39. data/test/dummy/bin/bundle +3 -0
  40. data/test/dummy/bin/rails +4 -0
  41. data/test/dummy/bin/rake +4 -0
  42. data/test/dummy/bin/setup +29 -0
  43. data/test/dummy/config.ru +4 -0
  44. data/test/dummy/config/application.rb +26 -0
  45. data/test/dummy/config/boot.rb +5 -0
  46. data/test/dummy/config/database.yml +25 -0
  47. data/test/dummy/config/environment.rb +5 -0
  48. data/test/dummy/config/environments/development.rb +41 -0
  49. data/test/dummy/config/environments/production.rb +79 -0
  50. data/test/dummy/config/environments/test.rb +42 -0
  51. data/test/dummy/config/initializers/assets.rb +11 -0
  52. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  53. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  54. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  55. data/test/dummy/config/initializers/inflections.rb +16 -0
  56. data/test/dummy/config/initializers/mime_types.rb +4 -0
  57. data/test/dummy/config/initializers/session_store.rb +3 -0
  58. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  59. data/test/dummy/config/locales/en.yml +23 -0
  60. data/test/dummy/config/routes.rb +4 -0
  61. data/test/dummy/config/secrets.yml +22 -0
  62. data/test/dummy/public/404.html +67 -0
  63. data/test/dummy/public/422.html +67 -0
  64. data/test/dummy/public/500.html +66 -0
  65. data/test/dummy/public/favicon.ico +0 -0
  66. data/test/fixtures/jive_rails/add_ons.yml +19 -0
  67. data/test/integration/navigation_test.rb +10 -0
  68. data/test/jive_rails_test.rb +7 -0
  69. data/test/models/jive_rails/add_on_test.rb +9 -0
  70. data/test/test_helper.rb +20 -0
  71. metadata +211 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 88c38d3144f4414cfe5df91349a9de4d4c82174c
4
+ data.tar.gz: 2aea2d8d81be11e62f3114c7dc434d93296843e1
5
+ SHA512:
6
+ metadata.gz: 5b457ae6d7086a091abce0be38dc6b1d6bc0fe9ef45c42a18aaddddf77a3220aeda3b60209a11742bdd7a51dd66304240b062993b32d57397a00fad39ab29090
7
+ data.tar.gz: 4b187fb0d2f5c64ed126f23a236ea94a532b2c4e5b6e7eb25d0c0dc6132590cdd86e31ae02993308045bccc50cb3fa50765fad97fca38bbdbc276eefea01a9b3
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Butch Marshall
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.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = JiveRails
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'JiveRails'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task default: :test
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,182 @@
1
+ var realTile = Boolean(jive.tile);//flag for later usage determination.
2
+ jive.tile = jive.tile || {};//if is not defined then define it so that callback ticket can be set internally.
3
+ var OAuth2ServerFlow = null;//defined here so it is visible in other files.
4
+
5
+
6
+ if (!gadgets.oauth || !gadgets.oauth.Popup) {
7
+ osapi.jive.core.container.sendNotification({message: 'Use of oauth2client.js requires the oauthpopup feature to be in app.xml. ( &lt;Require feature="oauthpopup"/&gt; )', severity: 'error'});
8
+ } else {
9
+
10
+ OAuth2ServerFlow = function(options) {
11
+
12
+ // required
13
+ var serviceHost = options['serviceHost'];
14
+ var grantDOMElementID = options['grantDOMElementID'];
15
+ var ticketErrorCallback = options['ticketErrorCallback'];
16
+ var jiveAuthorizeUrlErrorCallback = options['jiveAuthorizeUrlErrorCallback'];
17
+ var oauth2SuccessCallback = options['oauth2SuccessCallback'];
18
+ var preOauth2DanceCallback = options['preOauth2DanceCallback'];
19
+ var onLoadCallback = options['onLoadCallback'];
20
+ var jiveOAuth2Dance = options['jiveOAuth2Dance'];
21
+
22
+ // has defaults
23
+ var authorizeUrl = options['authorizeUrl'] || serviceHost + '/authorizeUrl';
24
+ var ticketURL = options['ticketURL'];
25
+ var authz = options['authz'] || 'signed';
26
+ var context = options['context'];
27
+ var extraAuthParams = options['extraAuthParams'];
28
+ var popupWindowHeight = options['popupWindowHeight'] || '600';
29
+ var popupWindowWidth = options['popupWindowWidth'] || '400';
30
+ var popupWindowProps = options['popUpWindowProps'];
31
+
32
+ var doOAuthDance = function (viewerID, oauth2CallbackUrl, jiveTenantID) {
33
+ // do any preparation things necessary
34
+ if (preOauth2DanceCallback) {
35
+ preOauth2DanceCallback();
36
+ }
37
+
38
+ //Fetch the jive callback url - eg. http://server//gadgets/jiveOAuth2Callback
39
+ var url = authorizeUrl + "?callback=" + oauth2CallbackUrl
40
+ + "&ts=" + new Date().getTime() + "&viewerID=" + viewerID;
41
+
42
+ if (jiveTenantID && jiveOAuth2Dance) {
43
+ url += "&jiveTenantID=" + jiveTenantID;
44
+ }
45
+
46
+ // any extra state to inform downstream operations
47
+ if (context) {
48
+ url += "&context=" + encodeURIComponent(JSON.stringify(context));
49
+ }
50
+
51
+ // any extra auth parameters to attach
52
+ if (extraAuthParams) {
53
+ url += "&extraAuthParams=" + encodeURIComponent(JSON.stringify(extraAuthParams));
54
+ }
55
+
56
+ //Pre open condition check
57
+ var openCallback = function () {
58
+ return true;
59
+ };
60
+
61
+ //Post condition check
62
+ var closeCallback = function () {
63
+ oauth2SuccessCallback(jive.tile.oauthReceivedCallbackTicket_);
64
+ };
65
+
66
+ // obtain the oauth url (points to oauth creds store like SFDC)
67
+ osapi.http.get({
68
+ 'href': url,
69
+ 'authz': authz,
70
+ 'noCache': true
71
+ }).execute(function (response) {
72
+ if (response.status >= 400 && response.status <= 599) {
73
+ jiveAuthorizeUrlErrorCallback(response);
74
+ return;
75
+ }
76
+
77
+ // pop open oauth url
78
+ var data = JSON.parse(response.content);
79
+
80
+ $(grantDOMElementID).click(
81
+ new gadgets.oauth.Popup(data.url,
82
+ popupWindowProps || ( 'width=' + popupWindowWidth + ',height=' + popupWindowHeight + ',scrollbars=yes'),
83
+ openCallback, closeCallback
84
+ ).createOpenerOnClick());
85
+
86
+ });
87
+ };
88
+
89
+ return {
90
+ launch: function (addOptions) {
91
+
92
+ addOptions = addOptions || {};
93
+
94
+ var doLaunch = function (config, options) {
95
+
96
+ gadgets.window.adjustHeight();
97
+ if (typeof config === "string") {
98
+ config = JSON.parse(config);
99
+ }
100
+
101
+ // state
102
+ var identifiers = realTile ? jive.tile.getIdentifiers() : {};
103
+ var viewerID = addOptions.viewerID || identifiers['viewer']; // user ID
104
+ if(!realTile && !viewerID){
105
+ osapi.jive.core.container.sendNotification({message: 'Apps must pass viewerID into OAuth 2 launch function', severity: 'error'});
106
+ }
107
+ var ticket = config["ticketID"]; // may or may not be there
108
+ var oauth2CallbackUrl = realTile ? jive.tile.getOAuth2CallbackUrl() :
109
+ function () {
110
+ var containerUrl = location.href;
111
+ if (containerUrl && containerUrl.indexOf('/gadgets/ifr') > -1) {
112
+ containerUrl = containerUrl.substr(0, containerUrl.indexOf('/gadgets/ifr'));
113
+ }
114
+
115
+ return containerUrl + '/gadgets/jiveOAuth2Callback';
116
+ }();
117
+ var jiveTenantID = gadgets.config.get()['jive-opensocial-ext-v1']['jiveTenantID'];
118
+
119
+ if (onLoadCallback) {
120
+ onLoadCallback(config, identifiers);
121
+ }
122
+
123
+ if (ticketURL) {
124
+ //
125
+ // check ticket state
126
+ // since a ticket endpoint was provided
127
+ //
128
+ osapi.http.get({
129
+ 'href': serviceHost + ticketURL + '?' + (
130
+ ticket ? ('ticketID=' + ticket) : ('viewerID=' + viewerID + "&ts=" +
131
+ new Date().getTime())
132
+ ),
133
+ 'format': 'json',
134
+ 'authz': authz,
135
+ 'noCache': true
136
+ }).execute(function (response) {
137
+ if (response.status >= 400 && response.status <= 599) {
138
+ if (ticketErrorCallback) {
139
+ ticketErrorCallback(response);
140
+ }
141
+ return;
142
+ }
143
+
144
+ var data = response.content;
145
+ if (data.status === 'ok') {
146
+ // ticket is still ok
147
+ // skip authentication
148
+ ticket = data.ticketID;
149
+ if (!ticket) {
150
+ doOAuthDance(viewerID, oauth2CallbackUrl, jiveTenantID);
151
+ }
152
+ else {
153
+ oauth2SuccessCallback();
154
+ }
155
+ }
156
+ else {
157
+ // ticket is not ok
158
+ // proceed with authentication
159
+ doOAuthDance(viewerID, oauth2CallbackUrl, jiveTenantID);
160
+ }
161
+ });
162
+
163
+ }
164
+ else {
165
+ // proceed with authentication since
166
+ // there is no ticket endpoint to check for
167
+ // origin server access token validity.
168
+ doOAuthDance(viewerID, oauth2CallbackUrl, jiveTenantID);
169
+ }
170
+
171
+ };
172
+ if (realTile) {
173
+ jive.tile.onOpen(doLaunch);
174
+ }
175
+ else {
176
+ doLaunch(addOptions, addOptions);
177
+ }
178
+ }
179
+ };
180
+
181
+ }
182
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,48 @@
1
+ require_dependency "jive_rails/application_controller"
2
+
3
+ module JiveRails
4
+ class AddonsController < ApplicationController
5
+ respond_to :json
6
+
7
+ def install
8
+ JiveRails::AddOn.create(install_params)
9
+
10
+ respond_to do |format|
11
+ format.json { render :json => {} }
12
+ end
13
+ end
14
+
15
+ def uninstall
16
+ @add_on = JiveRails::AddOn.where(uninstall_params).first
17
+
18
+ respond_to do |format|
19
+ if @add_on && @add_on.update_attributes(:uninstalled => true)
20
+ format.json { render :json => {} }
21
+ else
22
+ format.json { render :json => {}, status: :not_found }
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+ def uninstall_params
29
+ params.tap { |whitelisted|
30
+ whitelisted[:tenant_id] = params[:tenantId]
31
+ whitelisted[:client_id] = params[:clientId]
32
+ whitelisted[:jive_url] = params[:jiveUrl]
33
+ whitelisted[:jive_signature_url] = params[:jiveSignatureURL]
34
+ }.permit(:tenant_id,:client_id,:jive_url,:jive_signature_url)
35
+ end
36
+
37
+ def install_params
38
+ params.tap { |whitelisted|
39
+ whitelisted[:tenant_id] = params[:tenantId]
40
+ whitelisted[:client_id] = params[:clientId]
41
+ whitelisted[:client_secret] = params[:clientSecret]
42
+ whitelisted[:jive_url] = params[:jiveUrl]
43
+ whitelisted[:jive_signature] = params[:jiveSignature]
44
+ whitelisted[:jive_signature_url] = params[:jiveSignatureURL]
45
+ }.permit(:tenant_id,:client_id,:client_secret,:jive_url,:jive_signature,:jive_signature_url)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,4 @@
1
+ module JiveRails
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,101 @@
1
+ require_dependency "jive_rails/application_controller"
2
+ require "cgi"
3
+ require "jive/signed_request"
4
+ require "jive/oauth2"
5
+
6
+ module JiveRails
7
+ class OauthController < ApplicationController
8
+ respond_to :json, :html
9
+
10
+ def oauth2Callback
11
+ code = params[:code]
12
+ @state = params[:state]
13
+
14
+ # Decode state
15
+ @state = ::Base64.decode64 @state
16
+ # No idea why JSON.parse doesn't work here...
17
+ @state = ActiveSupport::JSON.decode @state
18
+ @state = ActiveSupport::JSON.decode @state
19
+
20
+ jive_tenant_id = (@state["context"].is_a?(Hash) && !@state["context"]["jiveTenantID"].to_s.empty?) ? @state["context"]["jiveTenantID"] : nil
21
+ viewer_id = @state["viewerID"] || nil
22
+ client_id = @state["client_id"] || nil
23
+ origin_jive_tenant_id = (@state["context"].is_a?(Hash) && !@state["context"]["originJiveTenantID"].to_s.empty?) ? @state["context"]["originJiveTenantID"] : nil
24
+
25
+ app = JiveRails::AddOn.where(:client_id => client_id, :tenant_id => jive_tenant_id).first
26
+ jive_url = app.jive_url
27
+
28
+ args = {
29
+ :jiveTenantID => jive_tenant_id,
30
+ :originJiveTenantID => origin_jive_tenant_id,
31
+ :clientId => client_id,
32
+ :clientOAuth2CallbackUrl => oauth_oauth2Callback_url,
33
+ :oauth2ConsumerKey => client_id,
34
+ :oauth2ConsumerSecret => app.client_secret,
35
+ :originServerTokenRequestUrl => "#{jive_url}/oauth2/token",
36
+ }
37
+ post_object = Jive::OAuth2.build_oauth2_callback_object(args, code)
38
+
39
+ @result = Jive::OAuth2.get_oauth2_token(args, post_object);
40
+ @jive_redirect_url = "#{@state["jiveRedirectUrl"]}?ticket=#{viewer_id}"
41
+
42
+ respond_to do |format|
43
+ format.html
44
+ end
45
+ end
46
+
47
+ def authorizeUrl
48
+ authorization = CGI.parse((request.headers["Authorization"] || "").gsub(/^JiveEXTN\s/,''))
49
+ client_id = authorization["client_id"].first
50
+ jive_url = authorization["jive_url"].first
51
+
52
+ viewerId = params[:viewerID]
53
+ jiveTenantID = params[:jiveTenantID]
54
+ callback = params[:callback]
55
+ extra_auth_params = {}
56
+ context = {}
57
+
58
+ originJiveTenantID = request.headers["X-Tenant-Id"] || ""
59
+ targetJiveTenantID = (authorization["tenant_id"] || []).first
60
+
61
+ app = JiveRails::AddOn.where(:client_id => client_id, :tenant_id => targetJiveTenantID).first
62
+ client_secret = app.client_secret
63
+
64
+ if !params[:context].to_s.empty?
65
+ context = ::JSON.parse(params[:context].to_s)
66
+ end
67
+
68
+ # encode the origin jiveTenantID in the context
69
+ if !originJiveTenantID.empty?
70
+ context[:originJiveTenantID] = originJiveTenantID
71
+ end
72
+
73
+ # encode the jiveTenantID in the context
74
+ if !jiveTenantID.empty?
75
+ context[:jiveTenantID] = jiveTenantID
76
+ end
77
+
78
+ if !params[:extraAuthParams].to_s.empty?
79
+ extra_auth_params = ::JSON.parse(URI.unescape(params[:extraAuthParams].to_s))
80
+ end
81
+
82
+ args = {
83
+ :clientOAuth2CallbackUrl => oauth_oauth2Callback_url,
84
+ :oauth2ConsumerKey => client_id,
85
+ :oauth2ConsumerSecret => client_secret,
86
+ :originServerAuthorizationUrl => "#{jive_url}/oauth2/authorize",
87
+ :originServerTokenRequestUrl => "#{jive_url}/oauth2/token",
88
+ :oauth2CallbackExtraParams => nil,
89
+ }
90
+
91
+ response = Jive::OAuth2.build_authorize_url_response_map(args, callback, {
92
+ :viewerID => viewerId,
93
+ :context => context
94
+ }, extra_auth_params)
95
+
96
+ respond_to do |format|
97
+ format.json { render :json => response }
98
+ end
99
+ end
100
+ end
101
+ end