ae_easy-login 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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +7 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +16 -0
- data/Rakefile +22 -0
- data/ae_easy-login.gemspec +49 -0
- data/doc/AeEasy.html +117 -0
- data/doc/AeEasy/Login.html +146 -0
- data/doc/AeEasy/Login/Flow.html +2489 -0
- data/doc/AeEasy/Login/Plugin.html +117 -0
- data/doc/AeEasy/Login/Plugin/EnabledBehavior.html +588 -0
- data/doc/_index.html +167 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +496 -0
- data/doc/file.README.html +92 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +92 -0
- data/doc/js/app.js +303 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +283 -0
- data/doc/top-level-namespace.html +110 -0
- data/lib/ae_easy/login.rb +10 -0
- data/lib/ae_easy/login/flow.rb +295 -0
- data/lib/ae_easy/login/plugin.rb +8 -0
- data/lib/ae_easy/login/plugin/enabled_behavior.rb +47 -0
- data/lib/ae_easy/login/version.rb +6 -0
- metadata +192 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.20
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
16
|
+
|
17
|
+
<script type="text/javascript" charset="utf-8">
|
18
|
+
pathId = "";
|
19
|
+
relpath = '';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="class_list.html?1"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="_index.html">Index</a> »
|
40
|
+
|
41
|
+
|
42
|
+
<span class="title">Top Level Namespace</span>
|
43
|
+
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div id="search">
|
47
|
+
|
48
|
+
<a class="full_list_link" id="class_list_link"
|
49
|
+
href="class_list.html">
|
50
|
+
|
51
|
+
<svg width="24" height="24">
|
52
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
54
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
55
|
+
</svg>
|
56
|
+
</a>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
<div class="clear"></div>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<div id="content"><h1>Top Level Namespace
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
</h1>
|
67
|
+
<div class="box_info">
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<h2>Defined Under Namespace</h2>
|
82
|
+
<p class="children">
|
83
|
+
|
84
|
+
|
85
|
+
<strong class="modules">Modules:</strong> <span class='object_link'><a href="AeEasy.html" title="AeEasy (module)">AeEasy</a></span>
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
</p>
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<div id="footer">
|
103
|
+
Generated on Fri Sep 27 07:10:16 2019 by
|
104
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
105
|
+
0.9.20 (ruby-2.5.3).
|
106
|
+
</div>
|
107
|
+
|
108
|
+
</div>
|
109
|
+
</body>
|
110
|
+
</html>
|
@@ -0,0 +1,295 @@
|
|
1
|
+
module AeEasy
|
2
|
+
module Login
|
3
|
+
# Login flow executor designed to recover from an expired or invalid
|
4
|
+
# session.
|
5
|
+
class Flow
|
6
|
+
include AeEasy::Core::Plugin::Executor
|
7
|
+
|
8
|
+
# App configuration to store login flow configuration.
|
9
|
+
# @return [AeEasy::Core::Config]
|
10
|
+
attr_accessor :app_config
|
11
|
+
|
12
|
+
# Output collection used to store held pages to be fixed and fetched.
|
13
|
+
# @return [String]
|
14
|
+
attr_accessor :collection
|
15
|
+
|
16
|
+
# Batch size used on query outputs.
|
17
|
+
# @return [Integer]
|
18
|
+
attr_accessor :per_page
|
19
|
+
|
20
|
+
# Key to be used to store login flow configuration data at #app_config.
|
21
|
+
# @return [String]
|
22
|
+
attr_accessor :config_key
|
23
|
+
|
24
|
+
# Page's "vars" key to store the login cookie used to fetch.
|
25
|
+
# @return [String]
|
26
|
+
attr_accessor :vars_key
|
27
|
+
|
28
|
+
# Block with custom user defined fixing logic to be executed on help page
|
29
|
+
# fix.
|
30
|
+
# @return [Proc,Lambda,nil]
|
31
|
+
attr_accessor :custom_fix
|
32
|
+
|
33
|
+
# Force held pages to keep response_keys on save.
|
34
|
+
# @return [Boolean] `true` when enabled, else `false`.
|
35
|
+
attr_accessor :keep_response_keys
|
36
|
+
|
37
|
+
# Hook to initialize login flow configuration.
|
38
|
+
#
|
39
|
+
# @param [Hash] opts ({}) Configuration options.
|
40
|
+
# @option opts [AeEasy::Core::Config] :app_config (nil) App configuration to
|
41
|
+
# use.
|
42
|
+
# @option opts [Integer] :per_page (100) Batch size used on query outputs.
|
43
|
+
# @option opts [String] :collection ('login_flow_held_pages') Output
|
44
|
+
# collection used to store held pages to be fixed and fetched.
|
45
|
+
# @option opts [String] :config_key ('login_flow') Key to be used to
|
46
|
+
# store login flow configuration data at #app_config.
|
47
|
+
# @option opts [String] :vars_key ('login_flow_cookie') Page's "vars" key
|
48
|
+
# to store the login cookie used to fetch.
|
49
|
+
# @option opts [String] :reponse_keys (nil) Response keys to remove from
|
50
|
+
# a held page before enqueue it again.
|
51
|
+
# @option opts [Block] :custom_fix (nil) Custom block to be executed on
|
52
|
+
# fixing a held page.
|
53
|
+
#
|
54
|
+
# @raise [ArgumentError] When `opts[:app_config]` is not provided or
|
55
|
+
# `nil`.
|
56
|
+
#
|
57
|
+
# @note `opts[:response_keys]` will default to a predefined list whenever
|
58
|
+
# `nil`.
|
59
|
+
def initialize_hook_login_flow opts = {}
|
60
|
+
self.per_page = opts[:per_page] || 100
|
61
|
+
self.collection = opts[:collection] || 'login_flow_held_pages'
|
62
|
+
self.config_key = opts[:config_key] || 'login_flow'
|
63
|
+
self.vars_key = opts[:vars_key] || 'login_flow_cookie'
|
64
|
+
self.response_keys = opts[:reponse_keys] || nil
|
65
|
+
self.app_config = opts[:app_config] || nil
|
66
|
+
self.custom_fix = opts[:custom_fix] || nil
|
67
|
+
self.keep_response_keys = opts[:keep_response_keys] || false
|
68
|
+
|
69
|
+
if self.app_config.nil?
|
70
|
+
raise ArgumentError.new('":app_config" option is required!')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Response keys to remove from a held page before enqueue it again.
|
75
|
+
#
|
76
|
+
# @return [Array<String>]
|
77
|
+
def response_keys
|
78
|
+
@response_keys ||= [
|
79
|
+
'content_size',
|
80
|
+
'content_type',
|
81
|
+
'created_at',
|
82
|
+
'effective_url',
|
83
|
+
'failed_at',
|
84
|
+
'failed_cid',
|
85
|
+
'failed_content_size',
|
86
|
+
'failed_content_type',
|
87
|
+
'failed_effective_url',
|
88
|
+
'failed_response_checksum',
|
89
|
+
'failed_response_cookie',
|
90
|
+
'failed_response_headers',
|
91
|
+
'failed_response_proto',
|
92
|
+
'failed_response_status_code',
|
93
|
+
'failed_response_status',
|
94
|
+
'fetched_at',
|
95
|
+
'fetched_from',
|
96
|
+
'fetching_at',
|
97
|
+
'fetching_try_count',
|
98
|
+
'forced_fetch',
|
99
|
+
'fresh',
|
100
|
+
'gid',
|
101
|
+
'hostname',
|
102
|
+
'job_id',
|
103
|
+
'job_status',
|
104
|
+
'parsed_at',
|
105
|
+
'parsing_at',
|
106
|
+
'parsing_fail_count',
|
107
|
+
'parsing_failed_at',
|
108
|
+
'parsing_status',
|
109
|
+
'parsing_try_count',
|
110
|
+
'parsing_updated_at',
|
111
|
+
'response_checksum',
|
112
|
+
'response_cookie',
|
113
|
+
'response_headers',
|
114
|
+
'response_proto',
|
115
|
+
'response_status_code',
|
116
|
+
'response_status',
|
117
|
+
'status',
|
118
|
+
'to_fetch',
|
119
|
+
'total_failures',
|
120
|
+
'total_requests',
|
121
|
+
'total_successes'
|
122
|
+
]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Set response key list to remove from a page before enqueue it again.
|
126
|
+
#
|
127
|
+
# @param [Array<String>] value Response key list.
|
128
|
+
def response_keys= value
|
129
|
+
@response_keys = value
|
130
|
+
end
|
131
|
+
|
132
|
+
# Invalidates login flow config, so it is reloaded on next config usage.
|
133
|
+
def reload_config
|
134
|
+
@config = nil
|
135
|
+
end
|
136
|
+
|
137
|
+
# Gets the existing login flow config or load it from app config when
|
138
|
+
# invalid.
|
139
|
+
#
|
140
|
+
# @return [Hash]
|
141
|
+
def config
|
142
|
+
@config ||= nil
|
143
|
+
return @config unless @config.nil?
|
144
|
+
@config = app_config.find_config config_key
|
145
|
+
@config.freeze
|
146
|
+
@config
|
147
|
+
end
|
148
|
+
|
149
|
+
# Indicates whenever login flow has been seeded. Useful when using files
|
150
|
+
# to held pages.
|
151
|
+
#
|
152
|
+
# @return [Boolean] `true` if seeded, else `false`.
|
153
|
+
def seeded?
|
154
|
+
config['seeded'] || false
|
155
|
+
end
|
156
|
+
|
157
|
+
# Updates app configuration.
|
158
|
+
#
|
159
|
+
# @param [Hash] data ({}) Data to be saved on app configuration.
|
160
|
+
def update_config data = {}
|
161
|
+
reload_config
|
162
|
+
new_config = {}.merge(config)
|
163
|
+
new_config.merge!(data)
|
164
|
+
save new_config
|
165
|
+
reload_config
|
166
|
+
end
|
167
|
+
|
168
|
+
# Set seeded flag as `true`.
|
169
|
+
def seeded!
|
170
|
+
update_config 'seeded' => true
|
171
|
+
end
|
172
|
+
|
173
|
+
# Indicates whenever latest session has been set as expired.
|
174
|
+
#
|
175
|
+
# @return [Boolean] `true` when expired, else `false`.
|
176
|
+
def expired?
|
177
|
+
config['expired'] || false
|
178
|
+
end
|
179
|
+
|
180
|
+
# Set expire flag as `true`.
|
181
|
+
def expire!
|
182
|
+
update_config 'expired' => true
|
183
|
+
end
|
184
|
+
|
185
|
+
# Check whenever a key name is categorized as a response key.
|
186
|
+
#
|
187
|
+
# @param [String] key Key name to check.
|
188
|
+
#
|
189
|
+
# @return [Boolean] `true` when key name is a response key, else `false`.
|
190
|
+
def response_key? key
|
191
|
+
self.response_keys.include? key.to_s.strip
|
192
|
+
end
|
193
|
+
|
194
|
+
# Remove all response keys from a held page hash.
|
195
|
+
#
|
196
|
+
# @param [Hash] held_page Held page to clean.
|
197
|
+
def clean_page_response! held_page
|
198
|
+
keys = held_page.keys + []
|
199
|
+
keys.each do |key|
|
200
|
+
held_page.delete key if response_key? key
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Updates an old cookie with current cookie saved on app configuration.
|
205
|
+
#
|
206
|
+
# @param [String,Array,Hash] old_cookie Old cookie to update.
|
207
|
+
def merge_cookie old_cookie
|
208
|
+
return config['cookie'] if old_cookie.nil?
|
209
|
+
AeEasy::Core::Helper::Cookie.update old_cookie, config['cookie']
|
210
|
+
end
|
211
|
+
|
212
|
+
# Add login flow reserved vars into a page.
|
213
|
+
#
|
214
|
+
# @param [Hash] new_page Page to add login flow reserved vars.
|
215
|
+
def add_vars! new_page
|
216
|
+
key = new_page.has_key?(:vars) ? :vars : 'vars'
|
217
|
+
new_page[key] = {} if new_page[key].nil?
|
218
|
+
new_page[key][vars_key] = config['cookie']
|
219
|
+
end
|
220
|
+
|
221
|
+
# Execute #custom_fix block into a held page.
|
222
|
+
#
|
223
|
+
# @param [Hash] held_page Held page to fix.
|
224
|
+
def custom_fix! held_page
|
225
|
+
self.custom_fix.call held_page unless self.custom_fix.nil?
|
226
|
+
end
|
227
|
+
|
228
|
+
# Fixes a held page session.
|
229
|
+
#
|
230
|
+
# @param [Hash] held_page Held page to fix.
|
231
|
+
def fix_page! held_page
|
232
|
+
clean_page_response! held_page
|
233
|
+
held_page['cookie'] = merge_cookie held_page['cookie']
|
234
|
+
held_page['headers'] = {} unless held_page.has_key? 'headers'
|
235
|
+
if held_page['headers'].has_key? 'Cookie'
|
236
|
+
held_page['headers']['Cookie'] = merge_cookie held_page['headers']['Cookie']
|
237
|
+
end
|
238
|
+
add_vars! held_page
|
239
|
+
custom_fix! held_page
|
240
|
+
end
|
241
|
+
|
242
|
+
# Fixes current page session by enqueue it using latest working session or
|
243
|
+
# held it for fix and enqueue login page by executing block.
|
244
|
+
def fix_session &enqueue_login
|
245
|
+
# Expire cookie when same as current page
|
246
|
+
old_cookie_hash = AeEasy::Core::Helper::Cookie.parse_from_request page['vars'][vars_key]
|
247
|
+
newest_cookie_hash = AeEasy::Core::Helper::Cookie.parse_from_request config['cookie']
|
248
|
+
same_cookie = AeEasy::Core::Helper::Cookie.include? old_cookie_hash, newest_cookie_hash
|
249
|
+
expire! if same_cookie && !config['expired']
|
250
|
+
|
251
|
+
# Hold self page
|
252
|
+
if config['expired'].nil? || config['expired']
|
253
|
+
held_page = page.merge({})
|
254
|
+
clean_page_response!(held_page) unless keep_response_keys
|
255
|
+
save(
|
256
|
+
'_collection' => collection,
|
257
|
+
'_id' => page['gid'],
|
258
|
+
'page' => held_page,
|
259
|
+
'fetched' => '0'
|
260
|
+
)
|
261
|
+
enqueue_login.call unless enqueue_login.nil?
|
262
|
+
return
|
263
|
+
end
|
264
|
+
|
265
|
+
# Refetch self with new session
|
266
|
+
new_page = {}.merge page
|
267
|
+
fix_page! new_page
|
268
|
+
enqueue new_page
|
269
|
+
end
|
270
|
+
|
271
|
+
# Restore all held pages stored as outputs.
|
272
|
+
def restore_held_pages
|
273
|
+
current_page = 1
|
274
|
+
held_pages = find_outputs collection, {'fetched' => '0'}, current_page, per_page
|
275
|
+
while !held_pages&.first.nil? do
|
276
|
+
held_pages.each do |output|
|
277
|
+
# Parse and seed pages
|
278
|
+
held_page = output['page'].is_a?(String) ? JSON.parse(output['page']) : output['page']
|
279
|
+
fix_page! held_page
|
280
|
+
pages << held_page
|
281
|
+
|
282
|
+
output['fetched'] = '1'
|
283
|
+
outputs << output
|
284
|
+
end
|
285
|
+
|
286
|
+
# Fetch next page
|
287
|
+
current_page += 1
|
288
|
+
enqueue pages
|
289
|
+
save outputs
|
290
|
+
held_pages = find_outputs collection, {'fetched' => '0'}, current_page, per_page
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module AeEasy
|
2
|
+
module Login
|
3
|
+
module Plugin
|
4
|
+
# Abstract module that provides a template with minimal common logic to
|
5
|
+
# implement a login flow enabled plugin.
|
6
|
+
# @abstract
|
7
|
+
module EnabledBehavior
|
8
|
+
include AeEasy::Core::Plugin::InitializeHook
|
9
|
+
|
10
|
+
# Login flow tool.
|
11
|
+
attr_reader :login_flow
|
12
|
+
|
13
|
+
# Hook to initialize login_flow configuration.
|
14
|
+
#
|
15
|
+
# @param [Hash] opts ({}) Configuration options (see
|
16
|
+
# AeEasy::Login::Flow#initialize_hook_login_flow).
|
17
|
+
def initialize_hook_login_plugin_enabled_behavior opts = {}
|
18
|
+
@login_flow = AeEasy::Login::Flow.new opts
|
19
|
+
end
|
20
|
+
|
21
|
+
# Generates a salt value based on the current page's login flow vars.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
def salt
|
25
|
+
old_cookie = page['vars'][login_flow.vars_key]
|
26
|
+
old_cookie = '' if old_cookie.nil?
|
27
|
+
Digest::SHA1.hexdigest old_cookie
|
28
|
+
end
|
29
|
+
|
30
|
+
# Validates that the current page's session hasn't expired.
|
31
|
+
#
|
32
|
+
# @return [Boolean] `true` when session is valid, else `false`.
|
33
|
+
def valid_session?
|
34
|
+
raise NotImplementedError.new('Must implement "session_valid?" function.')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Fixes current page's session.
|
38
|
+
#
|
39
|
+
# @return [Boolean] `true` when session is valid and no need to fix,
|
40
|
+
# else `false`.
|
41
|
+
def fix_session
|
42
|
+
raise NotImplementedError.new('Must implement "fix_session" function.')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|