openstax_connect 0.0.1
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.
- data/MIT-LICENSE +20 -0
- data/README.md +70 -0
- data/Rakefile +49 -0
- data/app/algorithms/openstax/connect/search_users.rb +47 -0
- data/app/assets/javascripts/openstax/connect/application.js +15 -0
- data/app/assets/javascripts/openstax/connect/sessions.js +2 -0
- data/app/assets/stylesheets/openstax/connect/application.css +13 -0
- data/app/assets/stylesheets/openstax/connect/dev.css.scss +31 -0
- data/app/assets/stylesheets/openstax/connect/sessions.css +4 -0
- data/app/controllers/openstax/connect/application_controller.rb +9 -0
- data/app/controllers/openstax/connect/dev/dev_controller.rb +16 -0
- data/app/controllers/openstax/connect/dev/sessions_controller.rb +21 -0
- data/app/controllers/openstax/connect/dev/users_controller.rb +28 -0
- data/app/controllers/openstax/connect/sessions_controller.rb +44 -0
- data/app/handlers/openstax/connect/dev/users_create.rb +31 -0
- data/app/handlers/openstax/connect/dev/users_generate.rb +36 -0
- data/app/handlers/openstax/connect/dev/users_search.rb +64 -0
- data/app/handlers/openstax/connect/sessions_omniauth_authenticated.rb +35 -0
- data/app/helpers/openstax/connect/application_helper.rb +20 -0
- data/app/helpers/openstax/connect/sessions_helper.rb +4 -0
- data/app/models/anonymous_user.rb +40 -0
- data/app/models/user.rb +21 -0
- data/app/views/layouts/openstax/connect/application.html.erb +14 -0
- data/app/views/openstax/connect/dev/users/index.html.erb +31 -0
- data/app/views/openstax/connect/dev/users/search.js.erb +21 -0
- data/app/views/openstax/connect/sessions/create.html.erb +10 -0
- data/app/views/openstax/connect/shared/_attention.html.erb +3 -0
- data/app/views/openstax/connect/users/_action_create_form.html.erb +9 -0
- data/app/views/openstax/connect/users/_action_dialog.html.erb +10 -0
- data/app/views/openstax/connect/users/_action_list.html.erb +33 -0
- data/app/views/openstax/connect/users/_action_search.html.erb +25 -0
- data/app/views/openstax/connect/users/action_search.js.erb +8 -0
- data/config/initializers/02_extend_builtins.rb +48 -0
- data/config/routes.rb +32 -0
- data/db/migrate/20130729213800_create_users.rb +9 -0
- data/db/migrate/20130909215452_add_fields_to_user.rb +11 -0
- data/lib/omniauth/strategies/openstax.rb +28 -0
- data/lib/openstax/connect/action_list.rb +40 -0
- data/lib/openstax/connect/engine.rb +34 -0
- data/lib/openstax/connect/route_helper.rb +34 -0
- data/lib/openstax/connect/utilities.rb +12 -0
- data/lib/openstax/connect/version.rb +5 -0
- data/lib/openstax_connect.rb +72 -0
- data/lib/tasks/connect-rails_tasks.rake +4 -0
- metadata +191 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
<% handler_errors.each do |error| %>
|
3
|
+
<%= error.translate %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<%= osu_section_block "Register a new user" do %>
|
7
|
+
|
8
|
+
|
9
|
+
<%= lev_form_for :register, url: dev_users_create_path do |f| %>
|
10
|
+
|
11
|
+
First name <%= f.text_field :first_name %><br/>
|
12
|
+
Last name <%= f.text_field :last_name %><br/>
|
13
|
+
Username <%= f.text_field :username %><br/>
|
14
|
+
Admin? <%= f.check_box :is_administrator %><br/>
|
15
|
+
|
16
|
+
<%= submit_tag 'Register' %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<%= osu_section_block "Generate new users" do %>
|
22
|
+
<%= lev_form_for :generate, url: dev_users_generate_path do |f| %>
|
23
|
+
Generate <%= f.text_field :count, style: 'width:30px' %> user(s) <%= submit_tag 'Do it now!' %>
|
24
|
+
<% end %>
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
<%= osu_section_block "Login as an existing user" do %>
|
28
|
+
|
29
|
+
<%= render 'openstax/connect/users/action_search', action_search_path: dev_users_search_path %>
|
30
|
+
|
31
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
<%= render template: 'openstax/connect/users/action_search',
|
3
|
+
locals: {
|
4
|
+
users: @results[:users],
|
5
|
+
list: OpenStax::Connect::ActionList.new(
|
6
|
+
headings: ['First Name', 'Last Name', 'Username', ''],
|
7
|
+
widths: ['25%', '25%', '25%', '25%'],
|
8
|
+
data_procs:
|
9
|
+
[
|
10
|
+
Proc.new { |user| user.first_name },
|
11
|
+
Proc.new { |user| user.last_name },
|
12
|
+
Proc.new { |user| user.username },
|
13
|
+
Proc.new { |user|
|
14
|
+
link_to 'Sign in as',
|
15
|
+
sessions_become_path(:user_id => user.id),
|
16
|
+
method: :post
|
17
|
+
}
|
18
|
+
]
|
19
|
+
)
|
20
|
+
}
|
21
|
+
%>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
|
2
|
+
License version 3 or later. See the COPYRIGHT file for details. %>
|
3
|
+
|
4
|
+
<%# Callers must supply a 'user' local variable %>
|
5
|
+
|
6
|
+
<%= form_for target, :method => :post, :remote => true do |f| %>
|
7
|
+
<%= f.hidden_field :user_id, :value => user.id %>
|
8
|
+
<%= f.submit "Add", :onclick => please_wait_js %>
|
9
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
|
2
|
+
License version 3 or later. See the COPYRIGHT file for details. %>
|
3
|
+
|
4
|
+
<div id="user_action_dialog" style="display:none" title="<%= @action_dialog_title %>">
|
5
|
+
<div id="user_action_dialog_errors"></div>
|
6
|
+
|
7
|
+
<%= render :partial => 'users/action_search',
|
8
|
+
:locals => { :action_search_path => @action_search_path } %>
|
9
|
+
|
10
|
+
</div>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
|
2
|
+
License version 3 or later. See the COPYRIGHT file for details. %>
|
3
|
+
|
4
|
+
<%
|
5
|
+
users ||= []
|
6
|
+
%>
|
7
|
+
|
8
|
+
<% if list.num_columns > 0 %>
|
9
|
+
<table class="list" width="100%">
|
10
|
+
<% if list.has_headings? %>
|
11
|
+
<tr>
|
12
|
+
<% for ii in 0..list.num_columns - 1 %>
|
13
|
+
<th><%= list.get_heading(ii) %></th>
|
14
|
+
<% end %>
|
15
|
+
</tr>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<% if users.empty? %>
|
19
|
+
<tr>
|
20
|
+
<td colspan="<%= list.num_columns %>">No results</td>
|
21
|
+
</tr>
|
22
|
+
<% else %>
|
23
|
+
<% users.all.each_with_index do |user, uu| %>
|
24
|
+
<tr>
|
25
|
+
<% for cc in 0..list.num_columns - 1 %>
|
26
|
+
<% width = uu == 0 ? list.get_width(cc) : nil %>
|
27
|
+
<td <%= "width=#{width}" if width %>><%= list.get_data(cc, user) %></td>
|
28
|
+
<% end %>
|
29
|
+
</tr>
|
30
|
+
<% end %>
|
31
|
+
<% end %>
|
32
|
+
</table>
|
33
|
+
<% end %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
|
2
|
+
License version 3 or later. See the COPYRIGHT file for details. %>
|
3
|
+
|
4
|
+
<%
|
5
|
+
# Clients of this partial must supply the following variables:
|
6
|
+
# action_search_path
|
7
|
+
%>
|
8
|
+
|
9
|
+
<div id="action-search-errors"></div>
|
10
|
+
|
11
|
+
<%= lev_form_for :search,
|
12
|
+
url: action_search_path,
|
13
|
+
id: 'action_search_form',
|
14
|
+
remote: true do |f| %>
|
15
|
+
|
16
|
+
Search for
|
17
|
+
<%= f.text_field :search_terms, style: 'width:300px' %>
|
18
|
+
in
|
19
|
+
<%= f.select :search_type, options_for_select(['Any', 'Name', 'Username']) %>
|
20
|
+
|
21
|
+
<%= submit_tag 'Search' %>
|
22
|
+
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<div id="action-search-results-list"></div>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class ActionController::Base
|
2
|
+
# References:
|
3
|
+
# http://railscasts.com/episodes/356-dangers-of-session-hijacking
|
4
|
+
|
5
|
+
# Always return an object
|
6
|
+
def current_user
|
7
|
+
if !request.ssl? || cookies.signed[:secure_user_id] == "secure#{session[:user_id]}"
|
8
|
+
@current_user ||= AnonymousUser.instance
|
9
|
+
|
10
|
+
if @current_user.is_anonymous? && session[:user_id]
|
11
|
+
# Use current_user= to clear out bad state if any
|
12
|
+
self.current_user = User.where(id: session[:user_id]).first
|
13
|
+
end
|
14
|
+
|
15
|
+
@current_user
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def current_user=(user)
|
20
|
+
@current_user = user || AnonymousUser.instance
|
21
|
+
if user.is_anonymous?
|
22
|
+
session[:user_id] = nil
|
23
|
+
cookies.delete(:secure_user_id)
|
24
|
+
else
|
25
|
+
session[:user_id] = user.id
|
26
|
+
cookies.signed[:secure_user_id] = {secure: true, value: "secure#{user.id}"}
|
27
|
+
end
|
28
|
+
@current_user
|
29
|
+
end
|
30
|
+
|
31
|
+
def sign_in(user)
|
32
|
+
self.current_user = user
|
33
|
+
end
|
34
|
+
|
35
|
+
def sign_out!
|
36
|
+
self.current_user = AnonymousUser.instance
|
37
|
+
end
|
38
|
+
|
39
|
+
def signed_in?
|
40
|
+
!current_user.is_anonymous?
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
helper_method :current_user, :current_user=, :signed_in?
|
46
|
+
|
47
|
+
end
|
48
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
OpenStax::Connect::Engine.routes.draw do
|
2
|
+
match '/auth/openstax/callback', to: 'sessions#omniauth_authenticated' #omniauth route
|
3
|
+
get '/auth/openstax', :as => 'openstax_login'
|
4
|
+
get 'sessions/new', :as => 'login'
|
5
|
+
post 'sessions/become'
|
6
|
+
|
7
|
+
# See https://github.com/plataformatec/devise/commit/f3385e96abf50e80d2ae282e1fb9bdad87a83d3c
|
8
|
+
match 'sessions/destroy', :as => 'logout', :via => OpenStax::Connect.configuration.logout_via
|
9
|
+
|
10
|
+
if OpenStax::Connect.configuration.enable_stubbing?
|
11
|
+
namespace :dev do
|
12
|
+
# get 'sessions/new'
|
13
|
+
# post 'sessions/create'
|
14
|
+
# post 'sessions/search'
|
15
|
+
get 'users', to: 'users#index'
|
16
|
+
post 'users/create'
|
17
|
+
post 'users/generate'
|
18
|
+
post 'users/search'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
module OpenStax
|
25
|
+
module Connect
|
26
|
+
hh = Engine.routes.url_helpers
|
27
|
+
|
28
|
+
RouteHelper.register_path(:login, hh.openstax_login_path) { hh.dev_users_path }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AddFieldsToUser < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
add_column :users, :first_name, :string
|
4
|
+
add_column :users, :last_name, :string
|
5
|
+
add_column :users, :username, :string
|
6
|
+
add_column :users, :is_administrator, :boolean, :default => false
|
7
|
+
|
8
|
+
add_index :users, :openstax_uid, :unique => true
|
9
|
+
add_index :users, :username, :unique => true
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'omniauth'
|
2
|
+
require 'omniauth-oauth2'
|
3
|
+
|
4
|
+
module OmniAuth
|
5
|
+
module Strategies
|
6
|
+
class Openstax < OAuth2
|
7
|
+
option :name, "openstax"
|
8
|
+
|
9
|
+
option :client_options, {
|
10
|
+
:site => OpenStax::Connect.configuration.openstax_services_url,
|
11
|
+
:authorize_url => "/oauth/authorize"
|
12
|
+
}
|
13
|
+
|
14
|
+
uid { raw_info["uid"] }
|
15
|
+
|
16
|
+
info do
|
17
|
+
{
|
18
|
+
:username => raw_info["username"]
|
19
|
+
# and anything else you want to return to your API consumers
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def raw_info
|
24
|
+
@raw_info ||= access_token.get('/api/v1/me.json').parsed
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module OpenStax::Connect
|
2
|
+
class ActionList
|
3
|
+
|
4
|
+
def initialize(options={})
|
5
|
+
@options = options
|
6
|
+
|
7
|
+
raise IllegalArgument, "must supply data procs" if options[:data_procs].nil?
|
8
|
+
|
9
|
+
if options[:headings].present? && options[:data_procs].size != options[:headings].size
|
10
|
+
raise IllegalArgument, "if you supply headings, you must supply one for each column"
|
11
|
+
end
|
12
|
+
|
13
|
+
if options[:widths].present? && options[:data_procs].size != options[:widths].size
|
14
|
+
raise IllegalArgument, "if you supply widths, you must supply one for each column"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def num_columns
|
20
|
+
@options[:data_procs].size
|
21
|
+
end
|
22
|
+
|
23
|
+
def has_headings?
|
24
|
+
@options[:headings].present?
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_heading(column)
|
28
|
+
@options[:headings].nil? ? nil : @options[:headings][column]
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_width(column)
|
32
|
+
@options[:widths].nil? ? nil : @options[:widths][column]
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_data(column, *args)
|
36
|
+
@options[:data_procs][column].call(*args)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
2
|
+
inflect.acronym 'OpenStax'
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'omniauth'
|
6
|
+
require 'squeel'
|
7
|
+
|
8
|
+
module OpenStax
|
9
|
+
module Connect
|
10
|
+
class Engine < ::Rails::Engine
|
11
|
+
isolate_namespace OpenStax::Connect
|
12
|
+
|
13
|
+
config.autoload_paths << File.expand_path("../../../app/algorithms", __FILE__)
|
14
|
+
config.autoload_paths << File.expand_path("../../../app/handlers", __FILE__)
|
15
|
+
|
16
|
+
config.generators do |g|
|
17
|
+
g.test_framework :rspec, :view_specs => false
|
18
|
+
end
|
19
|
+
|
20
|
+
# Doesn't work to put this omniauth code in an engine initializer, instead:
|
21
|
+
# https://gist.github.com/pablomarti/5243118
|
22
|
+
middleware.use ::OmniAuth::Builder do
|
23
|
+
provider :openstax,
|
24
|
+
OpenStax::Connect.configuration.openstax_application_id,
|
25
|
+
OpenStax::Connect.configuration.openstax_application_secret
|
26
|
+
end
|
27
|
+
|
28
|
+
config.after_initialize do
|
29
|
+
# The omniauth strategy requires values given during application init
|
30
|
+
require "omniauth/strategies/openstax"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module OpenStax
|
4
|
+
module Connect
|
5
|
+
class RouteHelper
|
6
|
+
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
# Registers a path against a canonical name. An optional
|
10
|
+
# block can be provided to give the stubbed path
|
11
|
+
def self.register_path(canonical_name, path, &block)
|
12
|
+
instance.paths[canonical_name] = path
|
13
|
+
if block.present? && OpenStax::Connect.configuration.enable_stubbing?
|
14
|
+
instance.stubbed_paths[canonical_name] = block.call
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_path(canonical_name)
|
19
|
+
OpenStax::Connect.configuration.enable_stubbing? ?
|
20
|
+
instance.stubbed_paths[canonical_name] :
|
21
|
+
instance.paths[canonical_name]
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
self.paths = {}
|
26
|
+
self.stubbed_paths = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :paths
|
30
|
+
attr_accessor :stubbed_paths
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module OpenStax
|
2
|
+
module Connect
|
3
|
+
|
4
|
+
class SecurityTransgression < StandardError; end
|
5
|
+
class AbstractMethodCalled < StandardError; end
|
6
|
+
class NotYetImplemented < StandardError; end
|
7
|
+
class IllegalArgument < StandardError; end
|
8
|
+
class IllegalState < StandardError; end
|
9
|
+
class IllegalOperation < StandardError; end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "openstax/connect/engine"
|
2
|
+
require "openstax/connect/version"
|
3
|
+
require "openstax/connect/utilities"
|
4
|
+
require "openstax/connect/route_helper"
|
5
|
+
require "openstax/connect/action_list"
|
6
|
+
|
7
|
+
module OpenStax
|
8
|
+
module Connect
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
###########################################################################
|
13
|
+
#
|
14
|
+
# Configuration machinery.
|
15
|
+
#
|
16
|
+
# To configure OpenStax Utilities, put the following code in your applications
|
17
|
+
# initialization logic (eg. in the config/initializers in a Rails app)
|
18
|
+
#
|
19
|
+
# OpenStax::Connect.configure do |config|
|
20
|
+
# config.<parameter name> = <parameter value>
|
21
|
+
# ...
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Set enable_stubbing to true iff you want this engine to fake all
|
25
|
+
# interaction with the services site.
|
26
|
+
#
|
27
|
+
|
28
|
+
def configure
|
29
|
+
yield configuration
|
30
|
+
end
|
31
|
+
|
32
|
+
def configuration
|
33
|
+
@configuration ||= Configuration.new
|
34
|
+
end
|
35
|
+
|
36
|
+
class Configuration
|
37
|
+
attr_accessor :openstax_application_id
|
38
|
+
attr_accessor :openstax_application_secret
|
39
|
+
attr_accessor :enable_stubbing
|
40
|
+
attr_reader :openstax_services_url
|
41
|
+
attr_accessor :logout_via
|
42
|
+
attr_accessor :default_errors_partial
|
43
|
+
attr_accessor :default_errors_html_id
|
44
|
+
attr_accessor :default_errors_added_trigger
|
45
|
+
|
46
|
+
def openstax_services_url=(url)
|
47
|
+
url.gsub!(/https|http/,'https') if !(url =~ /localhost/)
|
48
|
+
url = url + "/" if url[url.size-1] != '/'
|
49
|
+
@openstax_services_url = url
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize
|
53
|
+
@openstax_application_id = 'SET ME!'
|
54
|
+
@openstax_application_secret = 'SET ME!'
|
55
|
+
@openstax_services_url = 'https://services.openstax.org/'
|
56
|
+
@enable_stubbing = true
|
57
|
+
@logout_via = :get
|
58
|
+
@default_errors_partial = 'openstax/connect/shared/attention'
|
59
|
+
@default_errors_html_id = 'openstax-connect-attention'
|
60
|
+
@default_errors_added_trigger = 'openstax-connect-errors-added'
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
64
|
+
def enable_stubbing?
|
65
|
+
!Rails.env.production? && enable_stubbing
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|