openstax_accounts 0.3.0 → 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.
- checksums.yaml +15 -0
- data/README.md +20 -0
- data/app/controllers/openstax/accounts/dev/base_controller.rb +19 -0
- data/app/controllers/openstax/accounts/dev/users_controller.rb +10 -9
- data/app/handlers/openstax/accounts/dev/users_index.rb +39 -0
- data/app/handlers/openstax/accounts/sessions_omniauth_authenticated.rb +2 -1
- data/app/models/openstax/accounts/application_user.rb +7 -0
- data/app/models/openstax/accounts/user.rb +15 -3
- data/app/representers/openstax/accounts/api/v1/application_user_representer.rb +5 -1
- data/app/representers/openstax/accounts/api/v1/application_user_search_representer.rb +19 -0
- data/app/representers/openstax/accounts/api/v1/application_users_representer.rb +16 -0
- data/app/representers/openstax/accounts/api/v1/user_representer.rb +2 -6
- data/app/routines/openstax/accounts/dev/create_user.rb +4 -4
- data/app/routines/openstax/accounts/dev/search_users.rb +27 -0
- data/app/routines/openstax/accounts/search_users.rb +174 -32
- data/app/routines/openstax/accounts/sync_users.rb +44 -0
- data/app/views/openstax/accounts/dev/users/_search_results.html.erb +50 -0
- data/app/views/openstax/accounts/dev/users/index.js.erb +3 -0
- data/app/views/openstax/accounts/dev/users/login.html.erb +6 -5
- data/app/views/openstax/accounts/shared/_attention.html.erb +1 -1
- data/app/views/openstax/accounts/shared/users/_index.html.erb +24 -0
- data/config/routes.rb +5 -4
- data/lib/generators/openstax/accounts/schedule/USAGE +8 -0
- data/lib/generators/openstax/accounts/schedule/schedule_generator.rb +18 -0
- data/lib/generators/openstax/accounts/schedule/templates/schedule.rb +3 -0
- data/lib/omniauth/strategies/openstax.rb +1 -1
- data/lib/openstax/accounts/engine.rb +2 -0
- data/lib/openstax/accounts/version.rb +1 -1
- data/lib/openstax_accounts.rb +69 -26
- data/spec/controllers/openstax/accounts/dev/users_controller_spec.rb +4 -3
- data/spec/dummy/app/controllers/api/application_users_controller.rb +12 -0
- data/spec/dummy/config/application.rb +3 -0
- data/spec/dummy/config/initializers/openstax_accounts.rb +1 -0
- data/spec/dummy/config/routes.rb +5 -4
- data/spec/lib/openstax_accounts_spec.rb +19 -11
- data/spec/routines/openstax/accounts/dev/create_user_spec.rb +26 -0
- data/spec/routines/openstax/accounts/search_users_spec.rb +129 -0
- metadata +47 -68
- data/app/controllers/openstax/accounts/dev/dev_controller.rb +0 -13
- data/app/handlers/openstax/accounts/dev/users_search.rb +0 -38
- data/app/representers/openstax/accounts/api/v1/contact_info_representer.rb +0 -23
- data/app/representers/openstax/accounts/api/v1/email_address_representer.rb +0 -9
- data/app/views/openstax/accounts/dev/users/search.js.erb +0 -21
- data/app/views/openstax/accounts/users/_action_create_form.html.erb +0 -9
- data/app/views/openstax/accounts/users/_action_dialog.html.erb +0 -10
- data/app/views/openstax/accounts/users/_action_list.html.erb +0 -33
- data/app/views/openstax/accounts/users/_action_search.html.erb +0 -25
- data/app/views/openstax/accounts/users/action_search.js.erb +0 -8
- data/spec/dummy/app/controllers/api/users_controller.rb +0 -7
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Mjc2YjE2MDk2NTlkODU2NWVkNjJhYjAzZjY2MzRiZmMxOTRmZDNkZg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NzZmMzllNDRiODQ1MWVhMmRjMWNmYWYxYzc4ODUzZjNiMjkyZWFlNA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzgxYzZkMjI5NDc5NTk3ZjQyOGFjMDVjYThiNDg4NDY2MTM1MWRlZTI4YTQ2
|
10
|
+
NDE2MzVkNDc4YzI1ODNkMDQ3ZWU0YjFkNmQxZmY5YWU2YTQzM2VmZjI4Zjk0
|
11
|
+
MWI1MzkyMzQ0NzA1MmQxMGZkYjFiZmRlOGI4NDczYzc5ZjVlMjc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODRkZDMzMDEwNGQwNTRhYjU5NzkwODU5YzljZGE4YzhiZWUwNDkzMzkwMWMx
|
14
|
+
ZmEwMmNlYTUzZDVjY2VhYzg5MWJiNzJkZjcwYjQ3MjVmZjE0ZTAwOGJjOWRl
|
15
|
+
MTE5ODIxN2NjYTY1MzFiZjI5NjNjMjE4ZTIwNTBlNzI5N2RlNDM=
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
accounts-rails
|
2
2
|
=============
|
3
3
|
|
4
|
+
[](http://badge.fury.io/rb/openstax_accounts)
|
5
|
+
[](https://travis-ci.org/openstax/accounts-rails)
|
6
|
+
|
4
7
|
A rails engine for interfacing with OpenStax's accounts server.
|
5
8
|
|
6
9
|
Usage
|
@@ -75,6 +78,23 @@ Make sure to install the engine's migrations:
|
|
75
78
|
|
76
79
|
rake openstax_accounts:install:migrations
|
77
80
|
|
81
|
+
Syncing with Accounts
|
82
|
+
---------------------
|
83
|
+
|
84
|
+
OpenStax::Accounts requires your app to periodically sync user information with the Accounts server. The easiest way to do this is to use the "whenever" gem.
|
85
|
+
|
86
|
+
To create or append to the schedule.rb file, run the following command:
|
87
|
+
|
88
|
+
```sh
|
89
|
+
rails g openstax:accounts:schedule
|
90
|
+
```
|
91
|
+
|
92
|
+
Then, after installing the "whenever" gem, run the `whenever` command for instructions to set up your crontab:
|
93
|
+
|
94
|
+
```sh
|
95
|
+
whenever
|
96
|
+
```
|
97
|
+
|
78
98
|
Accounts API
|
79
99
|
------------
|
80
100
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module OpenStax
|
2
|
+
module Accounts
|
3
|
+
module Dev
|
4
|
+
class BaseController < OpenStax::Accounts::ApplicationController
|
5
|
+
|
6
|
+
before_filter Proc.new{
|
7
|
+
raise SecurityTransgression if Rails.env.production?
|
8
|
+
}
|
9
|
+
|
10
|
+
skip_before_filter :authenticate_user!
|
11
|
+
skip_before_filter :require_registration!
|
12
|
+
|
13
|
+
fine_print_skip_signatures :general_terms_of_use, :privacy_policy \
|
14
|
+
if respond_to?(:fine_print_skip_signatures)
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,21 +1,22 @@
|
|
1
1
|
module OpenStax
|
2
2
|
module Accounts
|
3
3
|
module Dev
|
4
|
-
class UsersController < OpenStax::Accounts::Dev::
|
5
|
-
|
6
|
-
def login; end
|
4
|
+
class UsersController < OpenStax::Accounts::Dev::BaseController
|
7
5
|
|
8
|
-
def
|
9
|
-
handle_with(
|
10
|
-
complete: lambda { render '
|
6
|
+
def index
|
7
|
+
handle_with(UsersIndex,
|
8
|
+
complete: lambda { render 'index' })
|
11
9
|
end
|
12
10
|
|
11
|
+
def login; end
|
12
|
+
|
13
13
|
def become
|
14
|
-
|
15
|
-
|
14
|
+
@user = User.find(params[:id])
|
15
|
+
sign_in(@user)
|
16
|
+
redirect_to return_url
|
16
17
|
end
|
17
18
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
21
|
-
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module OpenStax
|
2
|
+
module Accounts
|
3
|
+
module Dev
|
4
|
+
class UsersIndex
|
5
|
+
|
6
|
+
lev_handler transaction: :no_transaction
|
7
|
+
|
8
|
+
paramify :search do
|
9
|
+
attribute :terms, type: String
|
10
|
+
attribute :type, type: String
|
11
|
+
attribute :page, type: Integer
|
12
|
+
end
|
13
|
+
|
14
|
+
uses_routine OpenStax::Accounts::Dev::SearchUsers,
|
15
|
+
as: :search_users,
|
16
|
+
translations: { outputs: {type: :verbatim} }
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def authorized?
|
21
|
+
!Rails.env.production?
|
22
|
+
end
|
23
|
+
|
24
|
+
def handle
|
25
|
+
case search_params.type
|
26
|
+
when 'Name'
|
27
|
+
query = "name:#{search_params.terms.gsub(/\s/,',')}"
|
28
|
+
when 'Username'
|
29
|
+
query = "username:#{search_params.terms.gsub(/\s/,',')}"
|
30
|
+
else
|
31
|
+
query = search_params.terms || ''
|
32
|
+
end
|
33
|
+
run(:search_users, query, page: search_params.page || 0)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -2,11 +2,17 @@ module OpenStax
|
|
2
2
|
module Accounts
|
3
3
|
class User < ActiveRecord::Base
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
USERNAME_DISCARDED_CHAR_REGEX = /[^A-Za-z\d_]/
|
6
|
+
USERNAME_MAX_LENGTH = 50
|
7
|
+
|
8
|
+
attr_accessor :updating_from_accounts
|
9
|
+
|
10
|
+
validates :username, uniqueness: true, presence: true
|
7
11
|
validates :openstax_uid, presence: true
|
8
12
|
|
9
|
-
|
13
|
+
attr_accessible :username, :first_name, :last_name, :full_name, :title
|
14
|
+
|
15
|
+
before_update :update_openstax_accounts
|
10
16
|
|
11
17
|
def name
|
12
18
|
(first_name || last_name) ? [first_name, last_name].compact.join(" ") : username
|
@@ -26,6 +32,12 @@ module OpenStax
|
|
26
32
|
@@anonymous ||= AnonymousUser.new
|
27
33
|
end
|
28
34
|
|
35
|
+
def update_openstax_accounts
|
36
|
+
return if updating_from_accounts || \
|
37
|
+
OpenStax::Accounts.configuration.enable_stubbing?
|
38
|
+
OpenStax::Accounts.user_update(self)
|
39
|
+
end
|
40
|
+
|
29
41
|
class AnonymousUser < User
|
30
42
|
before_save { false }
|
31
43
|
def initialize(attributes=nil)
|
@@ -11,7 +11,11 @@ module OpenStax
|
|
11
11
|
property :application_id,
|
12
12
|
type: Integer
|
13
13
|
|
14
|
-
property :
|
14
|
+
property :user,
|
15
|
+
class: OpenStax::Accounts::User,
|
16
|
+
decorator: UserRepresenter
|
17
|
+
|
18
|
+
property :unread_updates,
|
15
19
|
type: Integer
|
16
20
|
|
17
21
|
property :default_contact_info_id,
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module OpenStax
|
2
|
+
module Accounts
|
3
|
+
module Api
|
4
|
+
module V1
|
5
|
+
class ApplicationUserSearchRepresenter < UserSearchRepresenter
|
6
|
+
|
7
|
+
collection :application_users,
|
8
|
+
class: OpenStax::Accounts::ApplicationUser,
|
9
|
+
decorator: ApplicationUserRepresenter,
|
10
|
+
schema_info: {
|
11
|
+
description: "The ApplicationUsers associated with the matching Users",
|
12
|
+
minItems: 0
|
13
|
+
}
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'representable/json/collection'
|
2
|
+
|
3
|
+
module OpenStax
|
4
|
+
module Accounts
|
5
|
+
module Api
|
6
|
+
module V1
|
7
|
+
class ApplicationUsersRepresenter < Roar::Decorator
|
8
|
+
include Representable::JSON::Collection
|
9
|
+
|
10
|
+
items class: OpenStax::Accounts::ApplicationUser,
|
11
|
+
decorator: ApplicationUserRepresenter
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -5,7 +5,8 @@ module OpenStax
|
|
5
5
|
class UserRepresenter < Roar::Decorator
|
6
6
|
include Roar::Representer::JSON
|
7
7
|
|
8
|
-
property :
|
8
|
+
property :openstax_uid,
|
9
|
+
as: :id,
|
9
10
|
type: Integer
|
10
11
|
|
11
12
|
property :username,
|
@@ -23,11 +24,6 @@ module OpenStax
|
|
23
24
|
property :title,
|
24
25
|
type: String
|
25
26
|
|
26
|
-
# TODO: Not yet implemented in this gem
|
27
|
-
# collection :contact_infos,
|
28
|
-
# class: OpenStax::Accounts::ContactInfo,
|
29
|
-
# decorator: ContactInfoRepresenter
|
30
|
-
|
31
27
|
end
|
32
28
|
end
|
33
29
|
end
|
@@ -4,14 +4,14 @@ module OpenStax
|
|
4
4
|
class CreateUser
|
5
5
|
lev_routine
|
6
6
|
|
7
|
-
|
7
|
+
protected
|
8
8
|
|
9
9
|
def exec(inputs={})
|
10
10
|
|
11
11
|
username = inputs[:username]
|
12
12
|
|
13
13
|
if username.nil? || inputs[:ensure_no_errors]
|
14
|
-
loop do
|
14
|
+
loop do
|
15
15
|
break if !username.nil? && OpenStax::Accounts::User.where(username: username).none?
|
16
16
|
username = "#{inputs[:username] || 'user'}#{rand(1000000)}"
|
17
17
|
end
|
@@ -23,7 +23,7 @@ module OpenStax
|
|
23
23
|
user.username = username
|
24
24
|
user.openstax_uid = available_negative_openstax_uid
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
transfer_errors_from(outputs[:user], {type: :verbatim})
|
28
28
|
end
|
29
29
|
|
@@ -34,4 +34,4 @@ module OpenStax
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Routine for searching for users
|
2
|
+
#
|
3
|
+
# Caller provides a query and some options. The query follows the rules of
|
4
|
+
# https://github.com/bruce/keyword_search, e.g.:
|
5
|
+
#
|
6
|
+
# "username:jps,richb" --> returns the "jps" and "richb" users
|
7
|
+
# "name:John" --> returns Users with first, last, or full name starting with "John"
|
8
|
+
#
|
9
|
+
# Query terms can be combined, e.g. "username:jp first_name:john"
|
10
|
+
#
|
11
|
+
# There are currently two options to control query pagination:
|
12
|
+
#
|
13
|
+
# :per_page -- the max number of results to return (default: 20)
|
14
|
+
# :page -- the zero-indexed page to return (default: 0)
|
15
|
+
|
16
|
+
module OpenStax
|
17
|
+
module Accounts
|
18
|
+
module Dev
|
19
|
+
class SearchUsers < OpenStax::Accounts::SearchUsers
|
20
|
+
def exec(query, options={})
|
21
|
+
options = options.merge!(:max_matching_users => Float::INFINITY)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,47 +1,189 @@
|
|
1
|
-
|
1
|
+
# Routine for searching for users
|
2
|
+
#
|
3
|
+
# Caller provides a query and some options. The query follows the rules of
|
4
|
+
# https://github.com/bruce/keyword_search , e.g.:
|
5
|
+
#
|
6
|
+
# "username:jps,richb" --> returns the "jps" and "richb" users
|
7
|
+
# "name:John" --> returns Users with first, last, or full name
|
8
|
+
# starting with "John"
|
9
|
+
#
|
10
|
+
# Query terms can be combined, e.g. "username:jp first_name:john"
|
11
|
+
#
|
12
|
+
# There are currently two options to control query pagination:
|
13
|
+
#
|
14
|
+
# :per_page -- the max number of results to return per page (default: 20)
|
15
|
+
# :page -- the zero-indexed page to return (default: 0)
|
16
|
+
#
|
17
|
+
# There is also an option to control the ordering:
|
18
|
+
#
|
19
|
+
# :order_by -- comma-separated list of fields to sort by, with an optional
|
20
|
+
# space-separated sort direction (default: "username ASC")
|
21
|
+
#
|
22
|
+
# Finally, you can also specify a maximum allowed number of results:
|
23
|
+
#
|
24
|
+
# :max_matching_users -- the max number of results allowed (default: 10)
|
25
|
+
#
|
26
|
+
# This routine will return an empty relation if the number of results exceeds
|
27
|
+
# max_matching_users. You can tell that this happened because the result will
|
28
|
+
# have a non-zero num_matching_users.
|
2
29
|
|
3
30
|
module OpenStax
|
4
31
|
module Accounts
|
5
|
-
|
6
32
|
class SearchUsers
|
33
|
+
|
7
34
|
lev_routine transaction: :no_transaction
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
SORTABLE_FIELDS = ['username', 'first_name', 'last_name', 'id']
|
39
|
+
SORT_ASCENDING = 'ASC'
|
40
|
+
SORT_DESCENDING = 'DESC'
|
41
|
+
|
42
|
+
def exec(query, options={})
|
43
|
+
|
44
|
+
if !OpenStax::Accounts.configuration.enable_stubbing? &&\
|
45
|
+
KeywordSearch.search(query).values_at('email', :default).compact.any?
|
46
|
+
# Delegate to Accounts
|
47
|
+
|
48
|
+
response = OpenStax::Accounts.application_users_index(query)
|
49
|
+
|
50
|
+
user_search = OpenStruct.new
|
51
|
+
search_rep = OpenStax::Accounts::Api::V1::UserSearchRepresenter.new(user_search)
|
52
|
+
search_rep.from_json(response.body)
|
53
|
+
|
54
|
+
# Need to query local database in order to obtain ID's (primary keys)
|
55
|
+
outputs[:users] = OpenStax::Accounts::User.where{
|
56
|
+
openstax_uid.in user_search.users.collect{ |u| u.openstax_uid }
|
57
|
+
}
|
58
|
+
outputs[:query] = user_search.q
|
59
|
+
outputs[:per_page] = user_search.per_page
|
60
|
+
outputs[:page] = user_search.page
|
61
|
+
outputs[:order_by] = user_search.order_by
|
62
|
+
outputs[:num_matching_users] = user_search.num_matching_users
|
63
|
+
|
64
|
+
else
|
65
|
+
|
66
|
+
# Local search
|
67
|
+
users = OpenStax::Accounts::User.scoped
|
68
|
+
|
69
|
+
KeywordSearch.search(query) do |with|
|
70
|
+
|
71
|
+
with.default_keyword :any
|
72
|
+
|
73
|
+
with.keyword :username do |usernames|
|
74
|
+
users = users.where{username.like_any my{prep_usernames(usernames)}}
|
75
|
+
end
|
76
|
+
|
77
|
+
with.keyword :first_name do |first_names|
|
78
|
+
users = users.where{lower(first_name).like_any my{prep_names(first_names)}}
|
79
|
+
end
|
80
|
+
|
81
|
+
with.keyword :last_name do |last_names|
|
82
|
+
users = users.where{lower(last_name).like_any my{prep_names(last_names)}}
|
83
|
+
end
|
84
|
+
|
85
|
+
with.keyword :full_name do |full_names|
|
86
|
+
users = users.where{lower(full_name).like_any my{prep_names(full_names)}}
|
87
|
+
end
|
88
|
+
|
89
|
+
with.keyword :name do |names|
|
90
|
+
names = prep_names(names)
|
91
|
+
users = users.where{ (lower(full_name).like_any names) |
|
92
|
+
(lower(last_name).like_any names) |
|
93
|
+
(lower(first_name).like_any names) }
|
94
|
+
end
|
95
|
+
|
96
|
+
with.keyword :id do |ids|
|
97
|
+
users = users.where{openstax_uid.in ids}
|
98
|
+
end
|
99
|
+
|
100
|
+
with.keyword :email do |emails|
|
101
|
+
users = OpenStax::Accounts::User.where('0=1')
|
102
|
+
end
|
103
|
+
|
104
|
+
# Rerun the queries above for 'any' terms (which are ones without a
|
105
|
+
# prefix).
|
106
|
+
|
107
|
+
with.keyword :any do |terms|
|
108
|
+
names = prep_names(terms)
|
109
|
+
|
110
|
+
users = users.where{
|
111
|
+
( lower(username).like_any my{prep_usernames(terms)}) |
|
112
|
+
(lower(first_name).like_any names) |
|
113
|
+
(lower(last_name).like_any names) |
|
114
|
+
(lower(full_name).like_any names) |
|
115
|
+
(id.in terms)
|
116
|
+
}
|
117
|
+
end
|
8
118
|
|
9
|
-
protected
|
10
|
-
|
11
|
-
def exec(terms, type=:any)
|
12
|
-
# Return empty results if no search terms
|
13
|
-
return User.where{id == nil}.where{id != nil} if terms.blank?
|
14
|
-
|
15
|
-
# Note: % is the wildcard. This allows the user to search
|
16
|
-
# for stuff that "begins with" but not "ends with".
|
17
|
-
case type
|
18
|
-
when :name
|
19
|
-
users = User.scoped
|
20
|
-
terms.gsub(/[%,]/, '').split.each do |t|
|
21
|
-
next if t.blank?
|
22
|
-
query = t + '%'
|
23
|
-
users = users.where{(first_name =~ query) | (last_name =~ query)}
|
24
119
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
120
|
+
|
121
|
+
# Pagination
|
122
|
+
|
123
|
+
page = options[:page] || 0
|
124
|
+
per_page = options[:per_page] || 20
|
125
|
+
|
126
|
+
users = users.limit(per_page).offset(per_page*page)
|
127
|
+
|
128
|
+
#
|
129
|
+
# Ordering
|
130
|
+
#
|
131
|
+
|
132
|
+
# Parse the input
|
133
|
+
order_bys = (options[:order_by] || 'username').split(',').collect{|ob| ob.strip.split(' ')}
|
134
|
+
|
135
|
+
# Toss out bad input, provide default direction
|
136
|
+
order_bys = order_bys.collect do |order_by|
|
137
|
+
field, direction = order_by
|
138
|
+
next if !SORTABLE_FIELDS.include?(field)
|
139
|
+
direction ||= SORT_ASCENDING
|
140
|
+
next if direction != SORT_ASCENDING && direction != SORT_DESCENDING
|
141
|
+
[field, direction]
|
36
142
|
end
|
37
|
-
|
38
|
-
|
143
|
+
|
144
|
+
order_bys.compact!
|
145
|
+
|
146
|
+
# Use a default sort if none provided
|
147
|
+
order_bys = ['username', SORT_ASCENDING] if order_bys.empty?
|
148
|
+
|
149
|
+
# Convert to query style
|
150
|
+
order_bys = order_bys.collect{|order_by| "#{order_by[0]} #{order_by[1]}"}
|
151
|
+
|
152
|
+
# Make the ordering call
|
153
|
+
order_bys.each do |order_by|
|
154
|
+
users = users.order(order_by)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Translate to routine outputs
|
158
|
+
|
159
|
+
outputs[:users] = users
|
160
|
+
outputs[:query] = query
|
161
|
+
outputs[:per_page] = per_page
|
162
|
+
outputs[:page] = page
|
163
|
+
outputs[:order_by] = order_bys.join(', ') # convert back to one string
|
164
|
+
outputs[:num_matching_users] = users.except(:offset, :limit, :order).count
|
165
|
+
|
39
166
|
end
|
40
167
|
|
41
|
-
|
168
|
+
# Return no results if query exceeds maximum allowed number of matches
|
169
|
+
max_users = options[:max_matching_users] || \
|
170
|
+
OpenStax::Accounts.configuration.max_matching_users
|
171
|
+
outputs[:users] = OpenStax::Accounts::User.where('0=1') \
|
172
|
+
if outputs[:num_matching_users] > max_users
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
# Downcase, and put a wildcard at the end.
|
177
|
+
# For the moment don't exclude characters.
|
178
|
+
def prep_names(names)
|
179
|
+
names.collect{|name| name.downcase + '%'}
|
180
|
+
end
|
181
|
+
|
182
|
+
def prep_usernames(usernames)
|
183
|
+
usernames.collect{|username| username.gsub(OpenStax::Accounts::User::USERNAME_DISCARDED_CHAR_REGEX, '').downcase + '%'}
|
42
184
|
end
|
43
185
|
|
44
186
|
end
|
45
187
|
|
46
188
|
end
|
47
|
-
end
|
189
|
+
end
|