cyclid-ui 0.1.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 +7 -0
- data/LICENSE +178 -0
- data/README.md +20 -0
- data/app/cyclid_ui.rb +124 -0
- data/app/cyclid_ui/config.rb +64 -0
- data/app/cyclid_ui/controllers/auth.rb +102 -0
- data/app/cyclid_ui/controllers/base.rb +41 -0
- data/app/cyclid_ui/controllers/health.rb +96 -0
- data/app/cyclid_ui/controllers/organization.rb +64 -0
- data/app/cyclid_ui/controllers/user.rb +40 -0
- data/app/cyclid_ui/helpers.rb +55 -0
- data/app/cyclid_ui/memcache.rb +45 -0
- data/app/cyclid_ui/models/user.rb +91 -0
- data/app/cyclid_ui/templates/footer.mustache +8 -0
- data/app/cyclid_ui/templates/job.mustache +21 -0
- data/app/cyclid_ui/templates/job_info.mustache +40 -0
- data/app/cyclid_ui/templates/layout.mustache +102 -0
- data/app/cyclid_ui/templates/login.mustache +78 -0
- data/app/cyclid_ui/templates/organization.mustache +150 -0
- data/app/cyclid_ui/templates/user.mustache +97 -0
- data/app/cyclid_ui/views/job.rb +25 -0
- data/app/cyclid_ui/views/layout.rb +52 -0
- data/app/cyclid_ui/views/login.rb +25 -0
- data/app/cyclid_ui/views/organization.rb +25 -0
- data/app/cyclid_ui/views/user.rb +25 -0
- data/bin/cyclid-ui-assets +17 -0
- data/lib/cyclid_ui/app.rb +4 -0
- data/public/images/LICENSE +3 -0
- data/public/images/cyclid-logo-large.png +0 -0
- data/public/images/favicon16.png +0 -0
- data/public/images/favicon32.png +0 -0
- data/public/images/favicon48.png +0 -0
- data/public/images/favicon64.png +0 -0
- data/public/images/favicon96.png +0 -0
- data/public/js/api.js +34 -0
- data/public/js/cyclid.js +32 -0
- data/public/js/job.js +215 -0
- data/public/js/organization.js +345 -0
- data/public/js/user.js +145 -0
- data/public/vendor/bootstrap/css/bootstrap-theme.css +587 -0
- data/public/vendor/bootstrap/css/bootstrap-theme.css.map +1 -0
- data/public/vendor/bootstrap/css/bootstrap-theme.min.css +6 -0
- data/public/vendor/bootstrap/css/bootstrap-theme.min.css.map +1 -0
- data/public/vendor/bootstrap/css/bootstrap.css +6760 -0
- data/public/vendor/bootstrap/css/bootstrap.css.map +1 -0
- data/public/vendor/bootstrap/css/bootstrap.min.css +6 -0
- data/public/vendor/bootstrap/css/bootstrap.min.css.map +1 -0
- data/public/vendor/bootstrap/css/custom.css +193 -0
- data/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- data/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
- data/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- data/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/public/vendor/bootstrap/js/bootstrap.js +2363 -0
- data/public/vendor/bootstrap/js/bootstrap.min.js +7 -0
- data/public/vendor/bootstrap/js/npm.js +13 -0
- data/public/vendor/font-awesome/HELP-US-OUT.txt +7 -0
- data/public/vendor/font-awesome/css/font-awesome.css +2199 -0
- data/public/vendor/font-awesome/css/font-awesome.min.css +4 -0
- data/public/vendor/font-awesome/fonts/FontAwesome.otf +0 -0
- data/public/vendor/font-awesome/fonts/fontawesome-webfont.eot +0 -0
- data/public/vendor/font-awesome/fonts/fontawesome-webfont.svg +685 -0
- data/public/vendor/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
- data/public/vendor/font-awesome/fonts/fontawesome-webfont.woff +0 -0
- data/public/vendor/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/vendor/font-awesome/less/animated.less +34 -0
- data/public/vendor/font-awesome/less/bordered-pulled.less +25 -0
- data/public/vendor/font-awesome/less/core.less +12 -0
- data/public/vendor/font-awesome/less/fixed-width.less +6 -0
- data/public/vendor/font-awesome/less/font-awesome.less +18 -0
- data/public/vendor/font-awesome/less/icons.less +733 -0
- data/public/vendor/font-awesome/less/larger.less +13 -0
- data/public/vendor/font-awesome/less/list.less +19 -0
- data/public/vendor/font-awesome/less/mixins.less +60 -0
- data/public/vendor/font-awesome/less/path.less +15 -0
- data/public/vendor/font-awesome/less/rotated-flipped.less +20 -0
- data/public/vendor/font-awesome/less/screen-reader.less +5 -0
- data/public/vendor/font-awesome/less/stacked.less +20 -0
- data/public/vendor/font-awesome/less/variables.less +744 -0
- data/public/vendor/font-awesome/scss/_animated.scss +34 -0
- data/public/vendor/font-awesome/scss/_bordered-pulled.scss +25 -0
- data/public/vendor/font-awesome/scss/_core.scss +12 -0
- data/public/vendor/font-awesome/scss/_fixed-width.scss +6 -0
- data/public/vendor/font-awesome/scss/_icons.scss +733 -0
- data/public/vendor/font-awesome/scss/_larger.scss +13 -0
- data/public/vendor/font-awesome/scss/_list.scss +19 -0
- data/public/vendor/font-awesome/scss/_mixins.scss +60 -0
- data/public/vendor/font-awesome/scss/_path.scss +15 -0
- data/public/vendor/font-awesome/scss/_rotated-flipped.scss +20 -0
- data/public/vendor/font-awesome/scss/_screen-reader.scss +5 -0
- data/public/vendor/font-awesome/scss/_stacked.scss +20 -0
- data/public/vendor/font-awesome/scss/_variables.scss +744 -0
- data/public/vendor/font-awesome/scss/font-awesome.scss +18 -0
- data/public/vendor/jquery-2.2.4.min.js +4 -0
- data/public/vendor/jquery.md5.js +269 -0
- data/public/vendor/js.cookie.js +151 -0
- data/public/vendor/mustache.min.js +1 -0
- metadata +322 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'sinatra/base'
|
17
|
+
require 'sinatra/cookies'
|
18
|
+
require 'sinatra/flash'
|
19
|
+
require 'mustache'
|
20
|
+
require 'mustache/sinatra'
|
21
|
+
|
22
|
+
module Cyclid
|
23
|
+
module UI
|
24
|
+
module Controllers
|
25
|
+
# Base class for all Sinatra controllers
|
26
|
+
class Base < Sinatra::Base
|
27
|
+
register Mustache::Sinatra
|
28
|
+
|
29
|
+
set :mustache, templates: File.expand_path('../../templates/', __FILE__),
|
30
|
+
|
31
|
+
views: File.expand_path('../../views/', __FILE__),
|
32
|
+
|
33
|
+
namespace: Cyclid::UI
|
34
|
+
|
35
|
+
register Sinatra::Flash
|
36
|
+
|
37
|
+
helpers Sinatra::Cookies, Helpers, AuthHelpers
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
require 'sinatra-health-check'
|
16
|
+
require 'memcached'
|
17
|
+
|
18
|
+
# Top level module for all of the core Cyclid code.
|
19
|
+
module Cyclid
|
20
|
+
module UI
|
21
|
+
module Controllers
|
22
|
+
# Controller for all Health related API endpoints
|
23
|
+
class Health < Base
|
24
|
+
def initialize(_app)
|
25
|
+
super
|
26
|
+
@checker = SinatraHealthCheck::Checker.new(logger: Cyclid.logger,
|
27
|
+
timeout: 0)
|
28
|
+
|
29
|
+
# Add internal health checks
|
30
|
+
@checker.systems[:memcache] = Cyclid::UI::Health::Memcache
|
31
|
+
@checker.systems[:api] = Cyclid::UI::Health::API
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return either 200 (healthy) or 503 (unhealthy) based on the status of
|
35
|
+
# the healthchecks. This is intended to be used by things like load
|
36
|
+
# balancers and active monitors.
|
37
|
+
get '/health/status' do
|
38
|
+
@checker.healthy? ? 200 : 503
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return verbose information on the status of the individual checks;
|
42
|
+
# note that this method always returns 200 with a message body, so it is
|
43
|
+
# not suitable for general health checks unless the caller intends to
|
44
|
+
# parse the message body for the health status.
|
45
|
+
get '/health/info' do
|
46
|
+
@checker.status.to_json
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Healthchecks
|
52
|
+
module Health
|
53
|
+
# Internal Memcache connection health check
|
54
|
+
module Memcache
|
55
|
+
# Check if Memcache is available
|
56
|
+
def self.status
|
57
|
+
connected = begin
|
58
|
+
memcache = Memcached.new(Cyclid.config.memcached)
|
59
|
+
memcache.stats
|
60
|
+
true
|
61
|
+
rescue Memcached::SomeErrorsWereReported
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
if connected
|
66
|
+
SinatraHealthCheck::Status.new(:ok, 'memcache connection is okay')
|
67
|
+
else
|
68
|
+
SinatraHealthCheck::Status.new(:warning, 'memcache is not available')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Internal API connection health check
|
74
|
+
module API
|
75
|
+
# Check if we can connect to the Cyclid API
|
76
|
+
def self.status
|
77
|
+
connected = begin
|
78
|
+
client = Client::Tilapia.new(auth: Client::AUTH_NONE,
|
79
|
+
log_level: Logger::DEBUG,
|
80
|
+
server: Cyclid.config.server_api.host,
|
81
|
+
port: Cyclid.config.server_api.port)
|
82
|
+
client.health_ping
|
83
|
+
rescue
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
87
|
+
if connected
|
88
|
+
SinatraHealthCheck::Status.new(:ok, 'API connection is okay')
|
89
|
+
else
|
90
|
+
SinatraHealthCheck::Status.new(:error, 'API is not available')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
module Cyclid
|
17
|
+
module UI
|
18
|
+
module Controllers
|
19
|
+
# Controller for Organization related endpoints (including Jobs)
|
20
|
+
class Organization < Base
|
21
|
+
get '/:name' do
|
22
|
+
authenticate!
|
23
|
+
|
24
|
+
# Build breadcrumbs
|
25
|
+
name = params[:name]
|
26
|
+
|
27
|
+
@crumbs = []
|
28
|
+
@crumbs << { 'name' => name.capitalize }
|
29
|
+
|
30
|
+
@organization = name
|
31
|
+
@linkback_url = "/#{name}"
|
32
|
+
|
33
|
+
api_server = Cyclid.config.client_api
|
34
|
+
@organization_url = "#{api_server}/organizations/#{params[:name]}"
|
35
|
+
@current_user = current_user
|
36
|
+
|
37
|
+
mustache :organization
|
38
|
+
end
|
39
|
+
|
40
|
+
get '/:name/job/:id' do
|
41
|
+
authenticate!
|
42
|
+
|
43
|
+
# Build breadcrumbs
|
44
|
+
name = params[:name]
|
45
|
+
id = params[:id]
|
46
|
+
|
47
|
+
@crumbs = []
|
48
|
+
@crumbs << { 'url' => "/#{name}", 'name' => name.capitalize }
|
49
|
+
@crumbs << { 'name' => "Job ##{id}" }
|
50
|
+
|
51
|
+
@organization = name
|
52
|
+
@linkback_url = "/#{name}"
|
53
|
+
|
54
|
+
api_server = Cyclid.config.client_api
|
55
|
+
@job_url = "#{api_server}/organizations/#{params[:name]}/jobs/#{params[:id]}"
|
56
|
+
@job_id = id
|
57
|
+
@current_user = current_user
|
58
|
+
|
59
|
+
mustache :job
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
module Cyclid
|
17
|
+
module UI
|
18
|
+
module Controllers
|
19
|
+
# Sinatra controller for user related endpoints
|
20
|
+
class User < Base
|
21
|
+
get '/user/:username' do
|
22
|
+
authenticate!
|
23
|
+
|
24
|
+
# Build breadcrumbs
|
25
|
+
username = params[:username]
|
26
|
+
|
27
|
+
@crumbs = []
|
28
|
+
@crumbs << { 'name' => 'User' }
|
29
|
+
@crumbs << { 'url' => "/user/#{username}", 'name' => username }
|
30
|
+
|
31
|
+
@api_url = Cyclid.config.client_api
|
32
|
+
@user_url = "#{@api_url}/users/#{params[:username]}"
|
33
|
+
@current_user = current_user
|
34
|
+
|
35
|
+
mustache :user
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
module Cyclid
|
17
|
+
module UI
|
18
|
+
# Various helper methods for Sinatra controllers
|
19
|
+
module Helpers
|
20
|
+
# Raw CSRF token
|
21
|
+
def csrf_token(rack_env)
|
22
|
+
Rack::Csrf.csrf_token(rack_env)
|
23
|
+
end
|
24
|
+
|
25
|
+
# CSRF HTML forms tag
|
26
|
+
def csrf_tag(rack_env)
|
27
|
+
Rack::Csrf.csrf_tag(rack_env)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Standard unauthenticated 401 message
|
31
|
+
def halt_with_401
|
32
|
+
flash[:login_error] = 'Invalid username or password'
|
33
|
+
halt 401, flash.now[:login_error]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sinatra Warden AuthN/AuthZ helpers
|
38
|
+
module AuthHelpers
|
39
|
+
# Return the current Warden scope
|
40
|
+
def warden
|
41
|
+
env['warden']
|
42
|
+
end
|
43
|
+
|
44
|
+
# Call the Warden authenticate! method
|
45
|
+
def authenticate!
|
46
|
+
warden.authenticate!
|
47
|
+
end
|
48
|
+
|
49
|
+
# Current User object from the session
|
50
|
+
def current_user
|
51
|
+
warden.user
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Modified from https://gist.github.com/mralex/956592
|
3
|
+
#
|
4
|
+
# Original licensed under MIT: https://github.com/gioext/sinatra-memcache
|
5
|
+
require 'memcached'
|
6
|
+
|
7
|
+
module Cyclid
|
8
|
+
module UI
|
9
|
+
# Simple Memcache caching layer on top of the Memcached client. Keys are
|
10
|
+
# retrieved or set via. the cache method; if the key exists it is returned,
|
11
|
+
# if the key does not exist the given block is called and its output is
|
12
|
+
# stored in Memcached.
|
13
|
+
class Memcache
|
14
|
+
attr_reader :client, :server, :expiry
|
15
|
+
|
16
|
+
def initialize(args)
|
17
|
+
@server = args[:server]
|
18
|
+
@expiry = args[:expiry] || 3600
|
19
|
+
end
|
20
|
+
|
21
|
+
def cache(key)
|
22
|
+
begin
|
23
|
+
output = memcached.get(key)
|
24
|
+
rescue Memcached::NotFound
|
25
|
+
output = yield
|
26
|
+
memcached.set(key, output, @expiry)
|
27
|
+
end
|
28
|
+
output
|
29
|
+
end
|
30
|
+
|
31
|
+
def expire(key)
|
32
|
+
memcached.delete key
|
33
|
+
true
|
34
|
+
rescue Memcached::NotFound
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def memcached
|
41
|
+
@client ||= Memcached.new(@server)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright 2016 Liqwyd Ltd.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
module Cyclid
|
17
|
+
module UI
|
18
|
+
module Models
|
19
|
+
# A User object. This is really no more than a simple wrapper around the
|
20
|
+
# Cyclid user data that is returned from the API, with the added layer
|
21
|
+
# of Memecached caching of the object to avoid API calls.
|
22
|
+
class User
|
23
|
+
attr_reader :username, :email, :organizations, :id
|
24
|
+
|
25
|
+
def initialize(args = {})
|
26
|
+
@username = args['username'] || nil
|
27
|
+
@email = args['email'] || nil
|
28
|
+
@organizations = args['organizations'] || []
|
29
|
+
@id = args['id'] || nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_hash
|
33
|
+
{ 'username' => @username,
|
34
|
+
'email' => @email,
|
35
|
+
'organizations' => @organizations,
|
36
|
+
'id' => @id }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Try to find the user object in Memcached; if it does not exist,
|
40
|
+
# fallback to the API. If the API returns the user data, it will be
|
41
|
+
# cached into Memcache for future use.
|
42
|
+
#
|
43
|
+
# If we have to fall back to the API we assume that the username is
|
44
|
+
# valid and either the HTTP Basic password or an API token are available
|
45
|
+
# and valid.
|
46
|
+
def self.get(args)
|
47
|
+
username = args[:username] || args['username']
|
48
|
+
memcache = Memcache.new(server: Cyclid.config.memcached)
|
49
|
+
|
50
|
+
user_data = begin
|
51
|
+
memcache.cache username do
|
52
|
+
user_fetch(args)
|
53
|
+
end
|
54
|
+
rescue Memcached::ServerIsMarkedDead => ex
|
55
|
+
Cyclid.logger.fatal "cannot connect to memcached: #{ex}"
|
56
|
+
# Fall back to a direct API connection
|
57
|
+
user_fetch(args)
|
58
|
+
end
|
59
|
+
|
60
|
+
new(user_data)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.user_fetch(args)
|
64
|
+
username = args[:username] || args['username']
|
65
|
+
password = args[:password] || args['password']
|
66
|
+
token = args[:token] || args['token']
|
67
|
+
|
68
|
+
auth_method = token.nil? ? Client::AUTH_BASIC : Client::AUTH_TOKEN
|
69
|
+
|
70
|
+
user_data = nil
|
71
|
+
begin
|
72
|
+
Cyclid.logger.debug "api=#{Cyclid.config.server_api.inspect}"
|
73
|
+
client = Client::Tilapia.new(auth: auth_method,
|
74
|
+
server: Cyclid.config.server_api.host,
|
75
|
+
port: Cyclid.config.server_api.port,
|
76
|
+
username: username,
|
77
|
+
password: password,
|
78
|
+
token: token)
|
79
|
+
user_data = client.user_get(username)
|
80
|
+
Cyclid.logger.debug "got #{user_data}"
|
81
|
+
rescue StandardError => ex
|
82
|
+
Cyclid.logger.fatal "failed to get user details: #{ex}"
|
83
|
+
raise ex
|
84
|
+
end
|
85
|
+
|
86
|
+
user_data
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div id="footer">
|
2
|
+
<div class="container">
|
3
|
+
<div class="row">
|
4
|
+
<div class="col-md-2"><p class="text-left">©2016 Cyclid</p></div>
|
5
|
+
<div class="col-md-1 col-md-offset-9"><a class="text-right" href="http://cyclid.io">cyclid.io</a></div>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
</div>
|