cyclid-ui 0.2.4 → 0.2.5
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 +4 -4
- data/app/cyclid_ui.rb +16 -3
- data/app/cyclid_ui/config.rb +4 -1
- data/app/cyclid_ui/controllers/auth.rb +1 -0
- data/app/cyclid_ui/controllers/user.rb +18 -0
- data/app/cyclid_ui/helpers.rb +27 -0
- data/app/cyclid_ui/models/user.rb +14 -0
- data/app/cyclid_ui/templates/intro.mustache +1 -1
- data/app/cyclid_ui/templates/layout.mustache +1 -1
- data/app/cyclid_ui/templates/user.mustache +1 -1
- data/lib/cyclid_ui/version.rb +1 -1
- data/public/js/job.js +1 -1
- data/public/js/organization.js +1 -1
- data/public/js/user.js +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 858197a4f94db4bbeb1e4960410c1fda2605918e
|
4
|
+
data.tar.gz: 7d97dd2d8908244cfd2243d0e180f4fa4818c72d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 448e078b6f05216fb65078bdd758b4ebf430b9a7851a659f194fccc03c90ab757f66566aceba5cc232c22e611ed791fffb0176e61575e460db313190ff347bd8
|
7
|
+
data.tar.gz: 7af9088a91c768294cc16a41840f60dcd30faf40bb79f0915bc047fe0258c9a3b819234ef4010b50b4e3aea3e0dc0bdc89f3a333da398b2e65181cd89bb3fc91
|
data/app/cyclid_ui.rb
CHANGED
@@ -55,16 +55,24 @@ module Cyclid
|
|
55
55
|
# Sinatra application
|
56
56
|
class App < Sinatra::Application
|
57
57
|
use Rack::Deflater
|
58
|
-
use Rack::Session::
|
58
|
+
use Rack::Session::Cookie,
|
59
59
|
expire_after: 31_557_600,
|
60
|
-
secret: ENV['COOKIE_SECRET'] || '8f54749dcb0ae0843cdd9669b797d311'
|
60
|
+
secret: ENV['COOKIE_SECRET'] || '8f54749dcb0ae0843cdd9669b797d311',
|
61
|
+
domain: Cyclid.config.domain
|
61
62
|
use Rack::Csrf,
|
62
63
|
raise: true,
|
63
64
|
skip: ['POST:/login',
|
64
|
-
'POST:/unauthenticated'
|
65
|
+
'POST:/unauthenticated',
|
66
|
+
'POST:/user/.*/invalidate']
|
65
67
|
|
66
68
|
helpers Helpers
|
67
69
|
|
70
|
+
if production?
|
71
|
+
error do
|
72
|
+
redirect to '/'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
68
76
|
register Sinatra::Flash
|
69
77
|
|
70
78
|
configure do
|
@@ -145,6 +153,11 @@ module Cyclid
|
|
145
153
|
use Controllers::User
|
146
154
|
use Controllers::Health
|
147
155
|
use Controllers::Default
|
156
|
+
|
157
|
+
# Catch-all route
|
158
|
+
get '*' do
|
159
|
+
redirect to '/'
|
160
|
+
end
|
148
161
|
end
|
149
162
|
end
|
150
163
|
end
|
data/app/cyclid_ui/config.rb
CHANGED
@@ -20,7 +20,7 @@ module Cyclid
|
|
20
20
|
module UI
|
21
21
|
# Cyclid UI configuration
|
22
22
|
class Config
|
23
|
-
attr_reader :memcached, :log, :server_api, :client_api, :signup
|
23
|
+
attr_reader :memcached, :log, :server_api, :client_api, :signup, :domain
|
24
24
|
|
25
25
|
def initialize(path)
|
26
26
|
# Try to load the configuration file. If it can't be loaded, we'll
|
@@ -58,6 +58,9 @@ module Cyclid
|
|
58
58
|
|
59
59
|
# URL of the signup link, if one is defined
|
60
60
|
@signup = manage['signup'] || nil
|
61
|
+
|
62
|
+
# Our domain; used when setting cookies
|
63
|
+
@domain = manage['domain'] || nil
|
61
64
|
rescue StandardError => ex
|
62
65
|
abort "Failed to load configuration file #{path}: #{ex}"
|
63
66
|
end
|
@@ -13,11 +13,15 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
+
require 'sinatra/cross_origin'
|
17
|
+
|
16
18
|
module Cyclid
|
17
19
|
module UI
|
18
20
|
module Controllers
|
19
21
|
# Sinatra controller for user related endpoints
|
20
22
|
class User < Base
|
23
|
+
register Sinatra::CrossOrigin
|
24
|
+
|
21
25
|
get '/user/:username' do
|
22
26
|
authenticate!
|
23
27
|
|
@@ -37,6 +41,20 @@ module Cyclid
|
|
37
41
|
mustache :user
|
38
42
|
end
|
39
43
|
|
44
|
+
post '/user/:username/invalidate' do
|
45
|
+
cross_origin
|
46
|
+
|
47
|
+
username = params[:username]
|
48
|
+
|
49
|
+
payload = parse_request_body
|
50
|
+
token = payload['token']
|
51
|
+
|
52
|
+
# Ensure the User is removed from Memcached
|
53
|
+
Models::User.invalidate(username: username, token: token)
|
54
|
+
|
55
|
+
200
|
56
|
+
end
|
57
|
+
|
40
58
|
get '/user/:username/intro' do
|
41
59
|
authenticate!
|
42
60
|
|
data/app/cyclid_ui/helpers.rb
CHANGED
@@ -13,6 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
+
require 'oj'
|
17
|
+
|
16
18
|
module Cyclid
|
17
19
|
module UI
|
18
20
|
# Various helper methods for Sinatra controllers
|
@@ -32,6 +34,31 @@ module Cyclid
|
|
32
34
|
flash[:login_error] = 'Invalid username or password'
|
33
35
|
halt 401, flash.now[:login_error]
|
34
36
|
end
|
37
|
+
|
38
|
+
# Safely parse & validate the request body
|
39
|
+
def parse_request_body
|
40
|
+
# Parse the the request
|
41
|
+
begin
|
42
|
+
request.body.rewind
|
43
|
+
|
44
|
+
if request.content_type == 'application/json' or \
|
45
|
+
request.content_type == 'text/json'
|
46
|
+
|
47
|
+
data = Oj.load request.body.read
|
48
|
+
else
|
49
|
+
halt(415, "unsupported content type #{request.content_type}")
|
50
|
+
end
|
51
|
+
rescue Oj::ParseError, YAML::Exception => ex
|
52
|
+
Cyclid.logger.debug ex.message
|
53
|
+
halt(400, ex.message)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Sanity check the request
|
57
|
+
halt(400, 'request body can not be empty') if data.nil?
|
58
|
+
halt(400, 'request body is invalid') unless data.is_a?(Hash)
|
59
|
+
|
60
|
+
return data
|
61
|
+
end
|
35
62
|
end
|
36
63
|
|
37
64
|
# Sinatra Warden AuthN/AuthZ helpers
|
@@ -90,6 +90,20 @@ module Cyclid
|
|
90
90
|
|
91
91
|
user_data
|
92
92
|
end
|
93
|
+
|
94
|
+
def self.invalidate(args)
|
95
|
+
username = args[:username] || args['username']
|
96
|
+
memcache = Memcache.new(server: Cyclid.config.memcached)
|
97
|
+
begin
|
98
|
+
user_fetch(args)
|
99
|
+
memcache.expire(username)
|
100
|
+
rescue Memcached::ServerIsMarkedDead => ex
|
101
|
+
Cyclid.logger.fatal "cannot connect to memcached: #{ex}"
|
102
|
+
# If Memcache is down there is nothing to expire
|
103
|
+
rescue StandardError => ex
|
104
|
+
Cyclid.logger.debug "user invalidate failed: #{ex}"
|
105
|
+
end
|
106
|
+
end
|
93
107
|
end
|
94
108
|
end
|
95
109
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<div class="col-md-8">
|
4
4
|
<h1>Welcome to Cyclid!</h1>
|
5
5
|
<p><span style="font-size:140%;">You currently don't belong to any organizations. Without an organization, you won't be able to run any jobs!</span></p>
|
6
|
-
<p>You can either <a href="{{signup}}/
|
6
|
+
<p>You can either <a href="{{signup}}/manage/{{username}}">create a new organization</a>, or ask someone to add you to an existing organization.</p>
|
7
7
|
<hr>
|
8
8
|
<p>While you're here, there are some useful links which can help you get the most from Cyclid:</p>
|
9
9
|
<ul style="line-height: 1.75;">
|
@@ -51,7 +51,7 @@
|
|
51
51
|
{{#organization}}
|
52
52
|
<li role="separator" class="divider"></li>
|
53
53
|
{{/organization}}
|
54
|
-
<li><a href="{{signup}}/
|
54
|
+
<li><a href="{{signup}}/manage/{{username}}" target="_blank">Manage your Organizations</a></li>
|
55
55
|
{{/signup}}
|
56
56
|
</ul>
|
57
57
|
</li>
|
@@ -24,7 +24,7 @@
|
|
24
24
|
<dt>Email</dt><dd id="user_email"></dd>
|
25
25
|
<dt>Organizations</dt><dd id="user_org_list"></dd>
|
26
26
|
{{#signup}}
|
27
|
-
<dd><a href="{{signup}}/
|
27
|
+
<dd><a href="{{signup}}/manage/{{username}}" target="_blank">Manage your Organizations</a></dd>
|
28
28
|
{{/signup}}
|
29
29
|
</div>
|
30
30
|
</div>
|
data/lib/cyclid_ui/version.rb
CHANGED
data/public/js/job.js
CHANGED
@@ -179,7 +179,7 @@ function ji_get_failed(xhr) {
|
|
179
179
|
// the worst (cyclid.token is invalid) and force re-authentication, too.
|
180
180
|
if(xhr.status == 401 || xhr.status == 0){
|
181
181
|
console.log(`Failed to retrieve job list: status was ${xhr.status}`);
|
182
|
-
window.location = '/
|
182
|
+
window.location = '/';
|
183
183
|
} else {
|
184
184
|
var failure_message = `<p>
|
185
185
|
<h2>Failed to retrieve job</h2><br>
|
data/public/js/organization.js
CHANGED
@@ -76,7 +76,7 @@ function org_job_list_failed(xhr) {
|
|
76
76
|
// the worst (cyclid.token is invalid) and force re-authentication, too.
|
77
77
|
if(xhr.status == 401 || xhr.status == 0){
|
78
78
|
console.log(`Failed to retrieve job list: status was ${xhr.status}`);
|
79
|
-
window.location = '/
|
79
|
+
window.location = '/';
|
80
80
|
} else {
|
81
81
|
var failure_message = `Failed to retrieve job list<br>
|
82
82
|
<strong>${xhr.status}:</strong> ${xhr.responseText}`;
|
data/public/js/user.js
CHANGED
@@ -10,7 +10,7 @@ function user_get_failed(xhr){
|
|
10
10
|
// the worst (cyclid.token is invalid) and force re-authentication, too.
|
11
11
|
if(xhr.status == 401 || xhr.status == 0){
|
12
12
|
console.log(`Failed to retrieve job list: status was ${xhr.status}`);
|
13
|
-
window.location = '/
|
13
|
+
window.location = '/';
|
14
14
|
} else {
|
15
15
|
var failure_message = `Failed to retrieve user details<br>
|
16
16
|
<strong>${xhr.status}:</strong> ${xhr.responseText}`;
|
@@ -41,7 +41,7 @@ function user_update_details(user){
|
|
41
41
|
config_org.click(function(e) {
|
42
42
|
var org = $(this).data('org');
|
43
43
|
|
44
|
-
var config = `
|
44
|
+
var config = `url: ${gblAPIURL}\n` +
|
45
45
|
`organization: ${org}\n` +
|
46
46
|
`username: ${user.username}\n` +
|
47
47
|
`secret: ${user.secret}\n`;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cyclid-ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kristian Van Der Vliet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: require_all
|