device-tracker 0.2.2 → 0.2.3

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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rspec +2 -0
  4. data/Readme.md +1 -0
  5. data/bin/console +1 -1
  6. data/device-tracker.gemspec +8 -2
  7. data/exe/device-tracker +48 -9
  8. data/lib/device_tracker/app.rb +21 -0
  9. data/lib/{device/tracker → device_tracker}/config-schema.json +0 -0
  10. data/lib/{device/tracker → device_tracker}/config.ru +0 -0
  11. data/lib/device_tracker/controllers/application_controller.rb +220 -0
  12. data/lib/device_tracker/controllers/devices_controller.rb +313 -0
  13. data/lib/device_tracker/controllers/heartbeat_controller.rb +54 -0
  14. data/lib/device_tracker/controllers/os_controller.rb +41 -0
  15. data/lib/device_tracker/controllers/transactions_controller.rb +19 -0
  16. data/lib/device_tracker/controllers/users_controller.rb +191 -0
  17. data/lib/{device/tracker → device_tracker}/db/migrate/20150521071815_create_users.rb +0 -0
  18. data/lib/{device/tracker → device_tracker}/db/migrate/20150521082155_create_devices.rb +0 -0
  19. data/lib/{device/tracker → device_tracker}/db/migrate/20150521120335_create_operating_systems.rb +0 -0
  20. data/lib/{device/tracker → device_tracker}/db/migrate/20150527162242_create_transactions.rb +0 -0
  21. data/lib/{device/tracker → device_tracker}/db/migrate/20151027073050_create_heartbeat.rb +0 -0
  22. data/lib/{device/tracker → device_tracker}/db/migrate/20151028132946_add_user_verification.rb +0 -0
  23. data/lib/{device/tracker → device_tracker}/db/migrate/20151028141328_remove_is_active_from_users.rb +0 -0
  24. data/lib/{device/tracker → device_tracker}/db/migrate/20151029085629_add_password_reset_code_to_users.rb +0 -0
  25. data/lib/{device/tracker → device_tracker}/db/migrate/20151030130341_add_missing_column_to_devices.rb +0 -0
  26. data/lib/{device/tracker → device_tracker}/db/migrate/20151102141601_add_serial_number_to_devices.rb +0 -0
  27. data/lib/{device/tracker → device_tracker}/db/schema.rb +0 -0
  28. data/lib/device_tracker/db/seeds.rb +46 -0
  29. data/lib/{device/tracker → device_tracker}/dependencies.rb +0 -1
  30. data/lib/device_tracker/device_tracker.rb +17 -0
  31. data/lib/device_tracker/helpers/application_helper.rb +82 -0
  32. data/lib/device_tracker/models/device.rb +35 -0
  33. data/lib/device_tracker/models/heartbeat.rb +7 -0
  34. data/lib/device_tracker/models/operating_system.rb +6 -0
  35. data/lib/device_tracker/models/transaction.rb +54 -0
  36. data/lib/device_tracker/models/user.rb +20 -0
  37. data/lib/{device/tracker → device_tracker}/public/css/bootstrap-sortable.css +0 -0
  38. data/lib/{device/tracker → device_tracker}/public/css/bootstrap.min.css +0 -0
  39. data/lib/{device/tracker → device_tracker}/public/css/custom.css +0 -0
  40. data/lib/{device/tracker → device_tracker}/public/favicon.png +0 -0
  41. data/lib/{device/tracker → device_tracker}/public/favicon/android-chrome-144x144.png +0 -0
  42. data/lib/{device/tracker → device_tracker}/public/favicon/android-chrome-192x192.png +0 -0
  43. data/lib/{device/tracker → device_tracker}/public/favicon/android-chrome-36x36.png +0 -0
  44. data/lib/{device/tracker → device_tracker}/public/favicon/android-chrome-48x48.png +0 -0
  45. data/lib/{device/tracker → device_tracker}/public/favicon/android-chrome-72x72.png +0 -0
  46. data/lib/{device/tracker → device_tracker}/public/favicon/android-chrome-96x96.png +0 -0
  47. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-114x114.png +0 -0
  48. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-120x120.png +0 -0
  49. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-144x144.png +0 -0
  50. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-152x152.png +0 -0
  51. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-180x180.png +0 -0
  52. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-57x57.png +0 -0
  53. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-60x60.png +0 -0
  54. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-72x72.png +0 -0
  55. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-76x76.png +0 -0
  56. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon-precomposed.png +0 -0
  57. data/lib/{device/tracker → device_tracker}/public/favicon/apple-touch-icon.png +0 -0
  58. data/lib/{device/tracker → device_tracker}/public/favicon/browserconfig.xml +0 -0
  59. data/lib/{device/tracker → device_tracker}/public/favicon/favicon-16x16.png +0 -0
  60. data/lib/{device/tracker → device_tracker}/public/favicon/favicon-32x32.png +0 -0
  61. data/lib/{device/tracker → device_tracker}/public/favicon/favicon-96x96.png +0 -0
  62. data/lib/{device/tracker → device_tracker}/public/favicon/favicon.ico +0 -0
  63. data/lib/{device/tracker → device_tracker}/public/favicon/manifest.json +0 -0
  64. data/lib/{device/tracker → device_tracker}/public/favicon/mstile-144x144.png +0 -0
  65. data/lib/{device/tracker → device_tracker}/public/favicon/mstile-150x150.png +0 -0
  66. data/lib/{device/tracker → device_tracker}/public/favicon/mstile-310x150.png +0 -0
  67. data/lib/{device/tracker → device_tracker}/public/favicon/mstile-310x310.png +0 -0
  68. data/lib/{device/tracker → device_tracker}/public/favicon/mstile-70x70.png +0 -0
  69. data/lib/{device/tracker → device_tracker}/public/favicon/safari-pinned-tab.svg +0 -0
  70. data/lib/{device/tracker → device_tracker}/public/fonts/glyphicons-halflings-regular.eot +0 -0
  71. data/lib/{device/tracker → device_tracker}/public/fonts/glyphicons-halflings-regular.svg +0 -0
  72. data/lib/{device/tracker → device_tracker}/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  73. data/lib/{device/tracker → device_tracker}/public/fonts/glyphicons-halflings-regular.woff +0 -0
  74. data/lib/{device/tracker → device_tracker}/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  75. data/lib/{device/tracker → device_tracker}/public/js/bootstrap-sortable.js +0 -0
  76. data/lib/{device/tracker → device_tracker}/public/js/bootstrap.min.js +0 -0
  77. data/lib/{device/tracker → device_tracker}/public/js/jquery-2.1.4.min.js +0 -0
  78. data/lib/device_tracker/version.rb +3 -0
  79. data/lib/{device/tracker → device_tracker}/views/404.erb +0 -0
  80. data/lib/{device/tracker → device_tracker}/views/_alert.erb +0 -0
  81. data/lib/{device/tracker → device_tracker}/views/_device_form.erb +0 -0
  82. data/lib/{device/tracker → device_tracker}/views/_device_list.erb +0 -0
  83. data/lib/{device/tracker → device_tracker}/views/_footer.erb +0 -0
  84. data/lib/{device/tracker → device_tracker}/views/_header.erb +0 -0
  85. data/lib/{device/tracker → device_tracker}/views/_heartbeat_list.erb +0 -0
  86. data/lib/{device/tracker → device_tracker}/views/_user_form.erb +0 -0
  87. data/lib/{device/tracker → device_tracker}/views/devices/edit.erb +0 -0
  88. data/lib/{device/tracker → device_tracker}/views/devices/index.erb +0 -0
  89. data/lib/{device/tracker → device_tracker}/views/devices/new.erb +0 -0
  90. data/lib/{device/tracker → device_tracker}/views/devices/show.erb +0 -0
  91. data/lib/{device/tracker → device_tracker}/views/devices/users.erb +0 -0
  92. data/lib/{device/tracker → device_tracker}/views/emails/new_password.erb +0 -0
  93. data/lib/{device/tracker → device_tracker}/views/emails/password_reset.erb +0 -0
  94. data/lib/{device/tracker → device_tracker}/views/emails/registration.erb +0 -0
  95. data/lib/{device/tracker → device_tracker}/views/emails/reminder.erb +0 -0
  96. data/lib/{device/tracker → device_tracker}/views/emails/verification.erb +0 -0
  97. data/lib/{device/tracker → device_tracker}/views/forgot_password.erb +0 -0
  98. data/lib/{device/tracker → device_tracker}/views/index.erb +0 -0
  99. data/lib/{device/tracker → device_tracker}/views/layout.erb +0 -0
  100. data/lib/{device/tracker → device_tracker}/views/login.erb +0 -0
  101. data/lib/{device/tracker → device_tracker}/views/operating_system/operating_systems.json.jbuilder +0 -0
  102. data/lib/{device/tracker → device_tracker}/views/os/manage.erb +0 -0
  103. data/lib/{device/tracker → device_tracker}/views/transactions/_transactions_list.erb +0 -0
  104. data/lib/{device/tracker → device_tracker}/views/transactions/index.erb +0 -0
  105. data/lib/{device/tracker → device_tracker}/views/users/edit.erb +0 -0
  106. data/lib/{device/tracker → device_tracker}/views/users/manage.erb +0 -0
  107. data/lib/{device/tracker → device_tracker}/views/users/new.erb +0 -0
  108. metadata +187 -103
  109. data/lib/device/tracker.rb +0 -19
  110. data/lib/device/tracker/app.rb +0 -25
  111. data/lib/device/tracker/controllers/application_controller.rb +0 -215
  112. data/lib/device/tracker/controllers/devices_controller.rb +0 -315
  113. data/lib/device/tracker/controllers/heartbeat_controller.rb +0 -55
  114. data/lib/device/tracker/controllers/os_controller.rb +0 -43
  115. data/lib/device/tracker/controllers/transactions_controller.rb +0 -21
  116. data/lib/device/tracker/controllers/users_controller.rb +0 -193
  117. data/lib/device/tracker/db/data/devices.xlsx +0 -0
  118. data/lib/device/tracker/db/seeds.rb +0 -25
  119. data/lib/device/tracker/helpers/application_helper.rb +0 -84
  120. data/lib/device/tracker/models/device.rb +0 -39
  121. data/lib/device/tracker/models/heartbeat.rb +0 -9
  122. data/lib/device/tracker/models/operating_system.rb +0 -8
  123. data/lib/device/tracker/models/transaction.rb +0 -56
  124. data/lib/device/tracker/models/user.rb +0 -22
  125. data/lib/device/tracker/version.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b7aa5c184e0fd1093576b5790a62ada3593fd65
4
- data.tar.gz: 64894ad46f5bf3ee7e8e825fc731d464faa099b1
3
+ metadata.gz: 83f4b95d5d9d1f5c8204a70f048e888414ab3e9a
4
+ data.tar.gz: caa35c654efdd961f99ae2d290481e7077e26a77
5
5
  SHA512:
6
- metadata.gz: e2f07af494decec02d8f0930346369f4be55e752d11c819bdabfaf3a2744086ab17e1daedb879e62c1de225f8a5bcc8f862ec93a3a517297b87ad32c660460d3
7
- data.tar.gz: 5e79c8eecb4a83d0ea66fd87c969d654b710f1582546827a73b792224d26dba97cd95eb7905ef06fcdb0b1fa98f22cc2f64bedf6c3488af4e7d9b98a8e91b92b
6
+ metadata.gz: 69021e135d7479c49e8303d5ca15a8d37070044af39486931bad18b59afe9f49c94f18bb94c22cccb571f609e976d4fcdd136a456167efe2acefcc31906a1480
7
+ data.tar.gz: d34875d902978747356500b5e047505234931c66e84e90013feb196c58ab7ef089f33899180f138fa4d1578c32e1246acc83560fcee78b006c9ea5409e42be77
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  .idea/*
2
2
  *.sqlite3
3
+ *.sqlite
3
4
  src/bin
4
5
  backup.sql
5
6
  /.bundle/
@@ -11,4 +12,5 @@ backup.sql
11
12
  /pkg/
12
13
  /spec/reports/
13
14
  /tmp/
14
-
15
+ capybara-*
16
+ development.json
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format NyanCatFormatter
data/Readme.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![Gem Version](https://badge.fury.io/rb/device-tracker.svg)](https://badge.fury.io/rb/device-tracker)
1
2
  # Device Tracker
2
3
 
3
4
  ## Installation
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "device/tracker"
4
+ require "device_tracker"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'device/tracker/version'
4
+ require 'device_tracker/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "device-tracker"
8
- spec.version = Device::Tracker::VERSION
8
+ spec.version = DeviceTracker::VERSION
9
9
  spec.authors = ["James Ruston", "John Crossley"]
10
10
  spec.email = ["james.ruston@bbc.com", "john.crossley@bbc.co.uk"]
11
11
 
@@ -38,6 +38,11 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency "tux", "~> 0.3"
39
39
  spec.add_development_dependency "shotgun", "~> 0.9"
40
40
  spec.add_development_dependency "byebug", "~> 8.1"
41
+ spec.add_development_dependency "nyan-cat-formatter"
42
+ spec.add_development_dependency "capybara"
43
+ spec.add_development_dependency "poltergeist"
44
+ spec.add_development_dependency "database_cleaner"
45
+ spec.add_development_dependency "factory_girl"
41
46
 
42
47
  spec.add_dependency "sinatra", "~> 1.4"
43
48
  spec.add_dependency "activerecord", "~> 4.0"
@@ -53,4 +58,5 @@ Gem::Specification.new do |spec|
53
58
  spec.add_dependency "pony", "~> 1.11"
54
59
  spec.add_dependency "mysql2", "~> 0.3.20"
55
60
  spec.add_dependency "json-schema", "~> 2.5"
61
+ spec.add_dependency "faker"
56
62
  end
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "device/tracker"
3
+ require "device_tracker/device_tracker"
4
4
  require "optparse"
5
5
  require "json-schema"
6
6
  require "json"
7
7
 
8
8
  config_path = "./development.json"
9
+ dummy_data = false
9
10
 
10
- opts = OptionParser.new do |opts|
11
+ OptionParser.new do |opts|
11
12
  opts.banner = "Usage: device-tracker [configuration]"
12
13
 
13
14
  opts.separator ""
@@ -16,6 +17,10 @@ opts = OptionParser.new do |opts|
16
17
  config_path = path
17
18
  end
18
19
 
20
+ opts.on("-d", "--dummy", "run the application in dummy mode, with dummy data") do
21
+ dummy_data = true
22
+ end
23
+
19
24
  opts.parse! ARGV
20
25
  end
21
26
 
@@ -28,7 +33,7 @@ end
28
33
 
29
34
  json = File.read(config_path)
30
35
 
31
- errors = JSON::Validator.fully_validate(File.expand_path('../../lib/device/tracker/config-schema.json', __FILE__), json)
36
+ errors = JSON::Validator.fully_validate(File.expand_path('../../lib/device_tracker/config-schema.json', __FILE__), json)
32
37
 
33
38
  unless errors.empty?
34
39
  puts errors
@@ -38,7 +43,36 @@ end
38
43
  config = JSON.parse(json)
39
44
 
40
45
  set :database, config["database"]
41
- Pony.options = config["email"]
46
+
47
+ config["email"].symbolize_keys!
48
+ pony_options = {}
49
+
50
+ # TODO - CLEAN ME .. OMG, I KNOW
51
+ config["email"].each do |key, value|
52
+
53
+ if key == :via
54
+ pony_options[key] = value.to_sym if key == :via
55
+ else
56
+ if key == :via_options
57
+ pony_options[key] = value.symbolize_keys!
58
+
59
+ # Iterate via_options
60
+ pony_options[:via_options].each do |i_key, i_val|
61
+ if i_key == :authentication
62
+ pony_options[:via_options][i_key] = i_val.to_sym
63
+ else
64
+ pony_options[:via_options][i_key] = i_val
65
+ end
66
+ end
67
+
68
+ else
69
+ pony_options[key] = value
70
+ end
71
+ end
72
+ end
73
+
74
+ Pony.options = pony_options
75
+
42
76
  set :google_maps_api_key, config["google_maps_api_key"]
43
77
  port = config["port"] || "3000"
44
78
  host = config["host"] || "127.0.0.1"
@@ -46,10 +80,15 @@ name = config["admin"]["name"]
46
80
  password = config["admin"]["password"]
47
81
  email = config["admin"]["email"]
48
82
 
49
- ActiveRecord::Migrator.migrate(File.expand_path('../../lib/device/tracker/db/migrate', __FILE__))
83
+ ActiveRecord::Migrator.migrate(File.expand_path('../../lib/device_tracker/db/migrate', __FILE__))
84
+
85
+ require_relative '../lib/device_tracker/dependencies'
86
+ require_relative '../lib/device_tracker/db/seeds'
50
87
 
51
- require_relative '../lib/device/tracker/dependencies'
52
- require_relative '../lib/device/tracker/db/seeds'
88
+ DeviceTracker::Seed.seed(name: name, password: password, email: email)
89
+
90
+ if dummy_data
91
+ DeviceTracker::Seed.seed_dummy_data
92
+ end
53
93
 
54
- Device::Tracker::Seed.seed(name: name, password: password, email: email)
55
- Device::Tracker.start(host, port)
94
+ DeviceTracker.start(host, port)
@@ -0,0 +1,21 @@
1
+ require_relative 'dependencies'
2
+ require 'rack'
3
+
4
+ module DeviceTracker
5
+ class App
6
+ def initialize
7
+ @app = Rack::Builder.new do
8
+ map('/heartbeats') { run HeartbeatController }
9
+ map('/transactions') { run TransactionsController }
10
+ map('/users') { run UsersController }
11
+ map('/devices') { run DevicesController }
12
+ map('/os') { run OSController }
13
+ map('/') { run ApplicationController }
14
+ end
15
+ end
16
+
17
+ def call(env)
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,220 @@
1
+ module DeviceTracker
2
+ class ApplicationController < Sinatra::Base
3
+ helpers ApplicationHelper
4
+
5
+ register Sinatra::ActiveRecordExtension
6
+ register Sinatra::Partial
7
+ register Sinatra::Flash
8
+
9
+ enable :sessions
10
+ enable :partial_underscores
11
+
12
+ set :views, File.expand_path('../../views', __FILE__)
13
+ set :public_dir, File.expand_path('../../public', __FILE__)
14
+ set :partial_template_engine, :erb
15
+ set :session_secret, SECRET
16
+
17
+ use Rack::MethodOverride
18
+
19
+ EMAILS_PATH = File.expand_path('../../views/emails/', __FILE__)
20
+
21
+ configure :development do
22
+ require 'byebug'
23
+ end
24
+
25
+ configure :test do
26
+ set database: {
27
+ adapter: 'sqlite3',
28
+ database: File.expand_path('../../db/test.sqlite', __FILE__)
29
+ }
30
+ end
31
+
32
+ configure :production, :development do
33
+ enable :logging
34
+ end
35
+
36
+ not_found do
37
+ @administrators = User.where(is_verified: true, is_admin: true)
38
+ erb :"404"
39
+ end
40
+
41
+ get "/version" do
42
+ halt 200, {
43
+ error: false,
44
+ version: $version
45
+ }
46
+ end
47
+
48
+ get "/" do
49
+ @devices = Device.where(available: false).order(checked_out_since: :desc).limit(10)
50
+ erb :index, devices: @devices
51
+ end
52
+
53
+ get "/forgot-password" do
54
+
55
+ if !params[:user_id].nil? and !params[:password_reset].nil?
56
+
57
+ # Check to see if the user_id matches the password_reset
58
+
59
+ @user = User.where(id: params[:user_id], reset_code: params[:password_reset]).first
60
+
61
+ if @user.nil?
62
+ create_flash "warning", ["Sorry, but something went wrong. Did you click on the correct link?"]
63
+ redirect "/"
64
+ end
65
+
66
+ # Reset that back
67
+ @user.reset_code = nil
68
+
69
+ @new_password = generate_activation_code 12
70
+
71
+ @user.password = @new_password
72
+
73
+ @user.save
74
+
75
+ body = ERB.new(File.read(EMAILS_PATH + "/new_password.erb")).result(binding)
76
+
77
+ begin
78
+ Pony.mail(
79
+ :to => @user.email,
80
+ :from => 'no-reply@device-tracker',
81
+ :subject => 'New password | Device Tracker',
82
+ :html_body => body
83
+ )
84
+ rescue Net::OpenTimeout => e
85
+ puts "ERROR: Error sending email"
86
+ end
87
+
88
+ create_flash "success", ["Your new password has been emailed to #{@user.email}"]
89
+ redirect "/login"
90
+
91
+ else
92
+ erb :"forgot_password"
93
+ end
94
+ end
95
+
96
+ put "/:device_id/found" do |device_id|
97
+
98
+ if Device.exists?(device_id)
99
+
100
+ user = get_logged_in_user
101
+
102
+ device = Device.find(device_id)
103
+ device.missing = false
104
+ device.save
105
+
106
+ report_transaction("#{user[:email]} reported #{device.full_name} as found", Transaction.found, device)
107
+
108
+ create_flash "success", ["Yay.. The device has been returned successfully!"]
109
+ redirect back
110
+ else
111
+ raise Siatra::NotFound
112
+ end
113
+ end
114
+
115
+ put "/:device_id/missing" do |device_id|
116
+ if Device.exists?(device_id)
117
+
118
+ user = get_logged_in_user
119
+
120
+ device = Device.find(device_id)
121
+ device.missing = true
122
+ device.save
123
+
124
+ report_transaction("#{user[:email]} reported #{device.full_name} missing", Transaction.missing, device)
125
+
126
+ create_flash "success", ["Oh no, the device has been reported missing!"]
127
+ redirect back
128
+ else
129
+ raise Sinatra::NotFound
130
+ end
131
+ end
132
+
133
+ post "/forgot-password" do
134
+ # user = User.find(params[:email])
135
+ if User.exists?(email: params[:email])
136
+
137
+ # Generate a random string
138
+ random_string = generate_activation_code 24
139
+
140
+ @user = User.find_by_email(params[:email])
141
+ @user.reset_code = random_string
142
+ @user.save
143
+
144
+ @password_reset_url = request.url + "?user_id=#{@user.id}&password_reset=#{random_string}"
145
+
146
+ body = ERB.new(File.read(EMAILS_PATH + "/password_reset.erb")).result(binding)
147
+
148
+ # Email that user with the link
149
+ # /password-reset?user_id=1&reset_code=MWAZ9JT9WKRP7RPTF3RHEG9J
150
+ begin
151
+ Pony.mail(
152
+ :to => @user.email,
153
+ :subject => 'Password Reset | Device Tracker',
154
+ :html_body => body
155
+ )
156
+ rescue Net::OpenTimeout => e
157
+ puts "ERROR: Error sending email"
158
+ end
159
+
160
+ # Validate the link
161
+ # Send the user a new password
162
+
163
+ create_flash "success", ["We have sent you a password reset link to #{@user.email}"]
164
+ redirect back
165
+
166
+ else
167
+ create_flash "warning", ["Sorry, but the email #{params[:email]} doesn't exist."]
168
+ redirect back
169
+ end
170
+ end
171
+
172
+ get "/logout" do
173
+ session[:user] = nil
174
+ redirect to("/")
175
+ end
176
+
177
+ get "/login" do
178
+ erb :login
179
+ end
180
+
181
+ post "/login" do
182
+
183
+ # Parse the form
184
+ email = params[:user][:email]
185
+ password = params[:user][:password]
186
+
187
+ if email.empty? or password.empty?
188
+ create_flash "warning", ["Please supply a username and or password"]
189
+ redirect back
190
+ end
191
+
192
+ flash[:email] = email
193
+
194
+ user = User.find_by_email(email)
195
+
196
+ unless user.is_verified
197
+ create_flash "warning", ["Your account is waiting verification."]
198
+ redirect back
199
+ end
200
+
201
+ if user.nil? or !user.authenticate(password)
202
+ create_flash "warning", ["You entered an invalid username and or password, please try again."]
203
+ redirect back
204
+ end
205
+
206
+
207
+ session[:user] = {
208
+ id: user.id,
209
+ name: user.name,
210
+ email: user.email,
211
+ is_admin: user.is_admin,
212
+ is_verified: user.is_verified
213
+ }
214
+
215
+ redirect to("devices/users/#{session[:user][:id]}")
216
+
217
+ end
218
+
219
+ end
220
+ end
@@ -0,0 +1,313 @@
1
+ require_relative 'application_controller'
2
+
3
+ module DeviceTracker
4
+
5
+ class DevicesController < ApplicationController
6
+
7
+ before do
8
+ protected!
9
+ end
10
+
11
+ get "/new" do
12
+ perform_admin_check
13
+
14
+ @device = Device.new
15
+
16
+ @operating_systems = OperatingSystem.select(:name, :id).distinct.order(:name)
17
+
18
+ erb :"devices/new"
19
+ end
20
+
21
+ post "/create" do
22
+ perform_admin_check
23
+
24
+ attributes = {
25
+ unid: params[:device][:unid],
26
+ manufacturer: params[:device][:manufacturer],
27
+ device: params[:device][:device],
28
+ description: params[:device][:description],
29
+ imei: params[:device][:imei],
30
+ serial_number: params[:device][:serial_number],
31
+ operating_system_id: params[:device][:operating_system_id]
32
+ }
33
+
34
+ if params[:device][:sim_card]
35
+ attributes[:sim_card] = true
36
+ end
37
+
38
+ if params[:device][:debug_device]
39
+ attributes[:debug_device] = true
40
+ end
41
+
42
+ attributes.each do |key, value|
43
+ flash[key] = value
44
+ end
45
+
46
+ @device = Device.new(attributes)
47
+
48
+ if @device.valid?
49
+ @device.save
50
+ create_flash "success", ["Created new device #{@device.full_name}"]
51
+ redirect "/devices/#{@device.id}"
52
+ else
53
+ create_flash "warning", @device.errors.full_messages
54
+ redirect back
55
+ end
56
+ end
57
+
58
+ get "/" do
59
+ @title = "All Devices"
60
+
61
+ @devices = Device.all
62
+ @users = User.all
63
+
64
+ @show_search = true
65
+
66
+ if params[:device_name] && ! params[:device_name].empty?
67
+ @show_search = false
68
+ @devices = @devices.where("device like ? or manufacturer like ?", "%#{params[:device_name]}%", "%#{params[:device_name]}%")
69
+ end
70
+
71
+ @devices = @devices.sort { |a, b| a.full_name <=> b.full_name }
72
+
73
+ erb :"devices/index"
74
+ end
75
+
76
+ get "/checked-out" do
77
+ @devices = Device.where(available: false).order(checked_out_since: :desc)
78
+ @users = User.all
79
+
80
+ if params[:device_name] && ! params[:device_name].empty?
81
+ @devices = @devices.where("description like ?", "%#{params[:device_name]}%")
82
+ end
83
+
84
+ @title = "Checked out Devices"
85
+
86
+ erb :"devices/index"
87
+ end
88
+
89
+ get "/:device_id" do |device_id|
90
+
91
+ unless Device.exists?(device_id)
92
+ raise Sinatra::NotFound
93
+ end
94
+
95
+ @users = User.where(is_verified: true).order(email: :desc)
96
+
97
+ @device = Device.find(device_id)
98
+
99
+ if @device.missing?
100
+ @last_checkout_transaction = Transaction
101
+ .where(transaction_type: 'CHECKOUT', device_id: @device.id)
102
+ .order(id: :desc).first
103
+ end
104
+
105
+ @transactions = @device.transactions.order(created_at: :desc).take(10)
106
+
107
+ @current_user = get_logged_in_user
108
+
109
+ erb :"devices/show"
110
+ end
111
+
112
+ put "/:device_id" do |device_id|
113
+ perform_admin_check
114
+
115
+ unless Device.exists?(device_id)
116
+ raise Sinatra::NotFound
117
+ end
118
+
119
+ params[:device].each do |key, value|
120
+ flash[key.to_sym] = value
121
+ end
122
+
123
+ @device = Device.find(device_id)
124
+ @device.update(params[:device])
125
+
126
+ if @device.save
127
+
128
+ create_flash "success", ["The device has been successfully updated."]
129
+ redirect "/devices/#{device_id}"
130
+ else
131
+ create_flash "warning", @device.errors.full_messages
132
+ redirect back
133
+ end
134
+
135
+ end
136
+
137
+ # devices/users/1
138
+ get "/users/:user_id" do |user_id|
139
+
140
+ user = get_logged_in_user
141
+
142
+ if user[:id] != user_id.to_i
143
+ create_flash "warning", ["You don't have permission to view this page."]
144
+ redirect back
145
+ end
146
+
147
+ unless User.exists?(user_id)
148
+ raise Sinatra::NotFound
149
+ end
150
+
151
+ # Get the user
152
+ @user = User.find(user_id)
153
+
154
+ @devices = @user.devices
155
+
156
+ erb :"devices/users", devices: @devices
157
+ end
158
+
159
+ put "/:device_id/return" do |device_id|
160
+
161
+ unid = device_id.upcase
162
+
163
+ if Device.exists?(unid: unid)
164
+ @device = Device.find_by_unid(unid)
165
+
166
+ user = @device.user
167
+
168
+ current_user = get_logged_in_user
169
+ if current_user[:id] == @device.user.id
170
+ report_transaction("#{user.email} returned #{@device.device}", Transaction.return, @device)
171
+ else
172
+ report_transaction("#{current_user[:email]} returned #{@device.device} on behalf of #{@device.user.email}", Transaction.return, @device)
173
+ end
174
+
175
+ @device.user = nil
176
+ @device.available = true
177
+ @device.checked_out_since = nil
178
+
179
+ @device.save
180
+
181
+ create_flash "success", ["The device has been successfully returned, thank you."]
182
+ redirect back
183
+ else
184
+ create_flash "warning", ["Device not found with id #{device_id}."]
185
+ redirect back
186
+ end
187
+ end
188
+
189
+ put "/:device_id/checkout" do |device_id|
190
+
191
+ unid = device_id.upcase
192
+
193
+ if Device.exists?(unid: unid)
194
+
195
+ @user = User.find(session[:user][:id])
196
+
197
+ device = Device.find_by_unid(unid)
198
+ device.user = @user
199
+
200
+ device.available = false
201
+ device.checked_out_since = Time.now.utc.iso8601
202
+
203
+ if device.save
204
+ report_transaction("#{@user.email} checked out #{device.device}.", Transaction.checkout, device)
205
+
206
+ create_flash "success", ["You have successfully checked out the device."]
207
+ redirect back
208
+
209
+ else
210
+ create_flash "warning", device.errors.full_messages
211
+ redirect back
212
+ end
213
+
214
+ end
215
+
216
+ end
217
+
218
+ # /devices/<%= @device.id %>/assign
219
+ put "/:device_id/assign" do |device_id|
220
+ perform_admin_check
221
+
222
+ if Device.exists?(device_id)
223
+
224
+ user_id = params[:user_id]
225
+
226
+ if user_id.nil?
227
+ create_flash "warning", ["You must select a user to assign the device to"]
228
+ redirect back
229
+ end
230
+
231
+ @current_user = User.find(session[:user][:id])
232
+ if ! User.exists?(user_id)
233
+ create_flash "danger", ["User not found with id #{user_id}"]
234
+ end
235
+
236
+ @assigned_user = User.find(user_id)
237
+
238
+ device = Device.find(device_id)
239
+ device.user = @assigned_user
240
+
241
+ device.available = false
242
+ device.checked_out_since = Time.now.utc.iso8601
243
+
244
+ if device.save
245
+ report_transaction("#{@current_user.email} checked out #{device.device} on behalf of #{@assigned_user.email}", Transaction.checkout, device)
246
+ end
247
+
248
+ create_flash "success", ["You have successfully assigned out the device to #{@assigned_user.name}."]
249
+ redirect back
250
+
251
+ end
252
+ end
253
+
254
+ post "/:device_id/send_reminder" do |device_id|
255
+ perform_admin_check
256
+
257
+ if Device.exists?(device_id)
258
+
259
+ @device = Device.find(device_id)
260
+ @device_url = request.base_url + '/devices/' + device_id
261
+
262
+ body = ERB.new(File.read(EMAILS_PATH + "/reminder.erb")).result(binding)
263
+
264
+ begin
265
+ Pony.mail(
266
+ :to => [@device.user.email],
267
+ :from => 'no-reply@device-tracker',
268
+ :subject => 'Reminder | Device Tracker',
269
+ :html_body => body
270
+ )
271
+ rescue Net::OpenTimeout => e
272
+ puts "ERROR: Error sending email"
273
+ end
274
+
275
+ # Send email
276
+ create_flash "success", ["A reminder email has been sent out to #{@device.user.name}."]
277
+ redirect "/devices/#{device_id}"
278
+
279
+ else
280
+ # Feedback
281
+ create_flash "warning", ["Sorry but that device doesn't exists.."]
282
+ redirect "/devices/#{device_id}"
283
+ end
284
+
285
+ end
286
+
287
+ get "/:device_id/edit" do |device_id|
288
+ perform_admin_check
289
+
290
+ unless Device.exists?(device_id)
291
+ raise Sinatra::NotFound
292
+ end
293
+
294
+ @device = Device.find(device_id)
295
+ @operating_systems = OperatingSystem.select(:name, :id).distinct.order(:name)
296
+
297
+ erb :"devices/edit"
298
+ end
299
+
300
+ delete "/:device_id" do |device_id|
301
+ perform_admin_check
302
+
303
+ unless Device.exists?(device_id)
304
+ raise Sinatra::NotFound
305
+ end
306
+
307
+ @device = Device.find(device_id).destroy
308
+ create_flash "success", ["Deleted device #{@device.unid}"]
309
+ redirect "/devices"
310
+ end
311
+
312
+ end
313
+ end