cpaas-sdk 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.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CHANGELOG.md +11 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +1 -0
  8. data/README.md +25 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/cpaas-sdk.gemspec +32 -0
  13. data/docs/Cpaas.html +446 -0
  14. data/docs/Cpaas/Conversation.html +1742 -0
  15. data/docs/Cpaas/Notification.html +301 -0
  16. data/docs/Cpaas/TwoFactor.html +908 -0
  17. data/docs/_index.html +146 -0
  18. data/docs/_index.md +21 -0
  19. data/docs/class_list.html +51 -0
  20. data/docs/css/common.css +1 -0
  21. data/docs/css/full_list.css +58 -0
  22. data/docs/css/style.css +496 -0
  23. data/docs/file.README.html +102 -0
  24. data/docs/file._index.html +94 -0
  25. data/docs/file_list.html +56 -0
  26. data/docs/frames.html +17 -0
  27. data/docs/index.html +94 -0
  28. data/docs/js/app.js +303 -0
  29. data/docs/js/full_list.js +216 -0
  30. data/docs/js/jquery.js +4 -0
  31. data/docs/method_list.html +251 -0
  32. data/docs/mv_index.html +102 -0
  33. data/docs/top-level-namespace.html +663 -0
  34. data/examples/2fa/.env.example +6 -0
  35. data/examples/2fa/.gitignore +159 -0
  36. data/examples/2fa/.ruby-gemset +1 -0
  37. data/examples/2fa/.ruby-version +1 -0
  38. data/examples/2fa/Gemfile +8 -0
  39. data/examples/2fa/README.md +34 -0
  40. data/examples/2fa/app.rb +134 -0
  41. data/examples/2fa/config.ru +10 -0
  42. data/examples/2fa/helper.rb +37 -0
  43. data/examples/2fa/public/stylesheets/forms.css +28 -0
  44. data/examples/2fa/public/stylesheets/global.css +7 -0
  45. data/examples/2fa/public/stylesheets/layout.css +45 -0
  46. data/examples/2fa/public/stylesheets/main.css +3 -0
  47. data/examples/2fa/views/alert.erb +5 -0
  48. data/examples/2fa/views/dashboard.erb +4 -0
  49. data/examples/2fa/views/index.erb +17 -0
  50. data/examples/2fa/views/login.erb +13 -0
  51. data/examples/2fa/views/verify.erb +8 -0
  52. data/examples/sms/.env.example +4 -0
  53. data/examples/sms/.gitignore +159 -0
  54. data/examples/sms/.ruby-gemset +1 -0
  55. data/examples/sms/.ruby-version +1 -0
  56. data/examples/sms/Gemfile +8 -0
  57. data/examples/sms/README.md +80 -0
  58. data/examples/sms/app.rb +87 -0
  59. data/examples/sms/config.ru +10 -0
  60. data/examples/sms/helper.rb +33 -0
  61. data/examples/sms/public/scripts/notification.js +46 -0
  62. data/examples/sms/public/stylesheets/forms.css +28 -0
  63. data/examples/sms/public/stylesheets/global.css +7 -0
  64. data/examples/sms/public/stylesheets/layout.css +74 -0
  65. data/examples/sms/public/stylesheets/main.css +3 -0
  66. data/examples/sms/views/alert.erb +5 -0
  67. data/examples/sms/views/index.erb +48 -0
  68. data/lib/cpaas-sdk.rb +30 -0
  69. data/lib/cpaas-sdk/api.rb +139 -0
  70. data/lib/cpaas-sdk/config.rb +9 -0
  71. data/lib/cpaas-sdk/resources.rb +4 -0
  72. data/lib/cpaas-sdk/resources/conversation.rb +268 -0
  73. data/lib/cpaas-sdk/resources/notification.rb +62 -0
  74. data/lib/cpaas-sdk/resources/notification_channel.rb +39 -0
  75. data/lib/cpaas-sdk/resources/twofactor.rb +136 -0
  76. data/lib/cpaas-sdk/util.rb +93 -0
  77. data/lib/cpaas-sdk/version.rb +3 -0
  78. data/tutorials/2FA.md +109 -0
  79. data/tutorials/2fa-flow.png +0 -0
  80. data/tutorials/GetStarted.md +86 -0
  81. data/tutorials/SMSMessaging.md +132 -0
  82. data/tutorials/index.html +86 -0
  83. data/tutorials/quickstarts.yml +15 -0
  84. metadata +238 -0
@@ -0,0 +1,6 @@
1
+ EMAIL=user@test.com
2
+ PASSWORD=123456
3
+ CLIENT_ID=
4
+ CLIENT_SECRET=
5
+ BASE_URL=
6
+ PHONE_NUMBER=
@@ -0,0 +1,159 @@
1
+ # Ignore the default SQLite database.
2
+ /db/*.sqlite3
3
+ /db/*.sqlite3-journal
4
+
5
+ # Ignore all logfiles and tempfiles.
6
+ /log/*
7
+ /tmp/*
8
+ !/log/.keep
9
+ !/tmp/.keep
10
+
11
+ # Ignore uploaded files in development
12
+ /storage/*
13
+ !/storage/.keep
14
+
15
+ .byebug_history
16
+
17
+ # Ignore master key for decrypting credentials and more.
18
+ /config/master.key
19
+
20
+ ## App-Specific
21
+
22
+ # Ignore the generated sample apps folder.
23
+ /public/sample_apps
24
+
25
+ *.pdf
26
+
27
+ # Ignore the generated csv folder
28
+ /public/csv
29
+
30
+ ## Capistrano
31
+
32
+ .env.staging
33
+ .env.production
34
+ .env.china
35
+ .env.developer
36
+
37
+ ## Rails
38
+
39
+ *.rbc
40
+ *.sassc
41
+ .sass-cache
42
+ capybara-*.html
43
+ .rspec
44
+ /log
45
+ /tmp
46
+ /db/*.sqlite3
47
+ /db/*.sqlite3-journal
48
+ /public/system
49
+ /public/assets
50
+ /public/uploads
51
+ /public/docs
52
+ /coverage/
53
+ /spec/tmp
54
+ rerun.txt
55
+ pickle-email-*.html
56
+ dump.rdb
57
+
58
+ ## Environment normalisation:
59
+ /.bundle
60
+ /vendor/bundle
61
+
62
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
63
+ .rvmrc
64
+
65
+ # if using bower-rails ignore default bower_components path bower.json files
66
+ /vendor/assets/bower_components
67
+ *.bowerrc
68
+ bower.json
69
+
70
+ # Ignore pow environment settings
71
+ .powenv
72
+
73
+ ## Documentation cache and generated files:
74
+ /.yardoc/
75
+ /_yardoc/
76
+ /doc/
77
+ /rdoc/
78
+
79
+ # Developer-specific files - These have a corresponding *.example file as a template to quickly copy over
80
+ config/database.yml
81
+ .env
82
+
83
+ ## General
84
+
85
+ # Git
86
+ **.orig
87
+
88
+ # OS X
89
+ .DS_Store
90
+ .DS_Store?
91
+ .AppleDouble
92
+ .LSOverride
93
+
94
+ # Icon must end with two \r
95
+ Icon
96
+
97
+
98
+ # Thumbnails
99
+ ._*
100
+
101
+ # Files that might appear on external disk
102
+ .Spotlight-V100
103
+ .Trashes
104
+
105
+ # Directories potentially created on remote AFP share
106
+ .AppleDB
107
+ .AppleDesktop
108
+ Network Trash Folder
109
+ Temporary Items
110
+ .apdisk
111
+
112
+ # Windows image file caches
113
+ Thumbs.db
114
+ ehthumbs.db
115
+
116
+ # Folder config file
117
+ Desktop.ini
118
+
119
+ # Recycle Bin used on file shares
120
+ $RECYCLE.BIN/
121
+
122
+ # Windows Installer files
123
+ *.cab
124
+ *.msi
125
+ *.msm
126
+ *.msp
127
+
128
+ # Windows shortcuts
129
+ *.lnk
130
+
131
+ # Compiled source
132
+ *.com
133
+ *.class
134
+ *.dll
135
+ *.exe
136
+ *.o
137
+ *.so
138
+
139
+ # Packages
140
+ # it's better to unpack these files and commit the raw source
141
+ # git has its own built in compression methods
142
+ *.7z
143
+ *.dmg
144
+ *.gz
145
+ *.iso
146
+ *.jar
147
+ *.rar
148
+ *.tar
149
+ *.zip
150
+
151
+ # Logs and databases
152
+ *.log
153
+ *.sql
154
+ *.sql-e
155
+ *.sqlite
156
+
157
+ # Files generated by atom
158
+ *.tags
159
+ *.tags_swap
@@ -0,0 +1 @@
1
+ kandy-sdk-example-2fa
@@ -0,0 +1 @@
1
+ ruby-2.5.0
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'httparty'
5
+ gem 'dotenv'
6
+ gem 'rerun'
7
+ gem 'pry'
8
+ gem 'cpaas-sdk', path: './../../'
@@ -0,0 +1,34 @@
1
+ # Two Factor Authentication Starter App
2
+
3
+ This is an elementary login authentication use case of two-factor authentication via SMS. The main focus of this application is to understand and implement the 2FA flow, so least amount of stress is given to the authentication/login mechanism.
4
+
5
+ ## Installation
6
+ 1. Copy `.env.example` and rename to `.env` and add the appropriate values. Check `Configuration` section for more details.
7
+ 2. To install dependencies, run:
8
+ ```bash
9
+ bundle install
10
+ ```
11
+ 3. To start the server, run:
12
+ ```bash
13
+ bundle exec rackup -p 6000
14
+ ```
15
+
16
+ ## Configuration
17
+ There are a few environment variables (check `.env` file) to make the application simpler and help us focus on the key aspects a two-factor authentication system via SMS. Some of the variables are pre-filled and some are left blank which are left on the user to place appropriate values. All the variables are mandatory.
18
+
19
+ ENV KEY | Description
20
+ ------------- | -------------
21
+ CLIENT_ID | Private project key
22
+ CLIENT_SECRET | Private project secret
23
+ BASE_URL | URL of the CPaaS server to use
24
+ PHONE_NUMBER | Phone number that would receive the verification code
25
+ EMAIL | Email used in the login screen of the application
26
+ PASSWORD | Password to be entered against the EMAIL provided
27
+
28
+ ## Usage
29
+ The application comprises of three simple pages, login, code verification, dashboard/portal
30
+ > + On opening the application in the browser, the login screen is presented. The user needs to enter the `Email` / `Password` that are specified in the `.env` file and click on the `Login` button.
31
+ > + Once the credentials are verified, a verification code is sent out to the phone number and redirected to the code verification page. This phone number corresponds to the one entered in the `.env` file as `PHONE_NUMBER`.
32
+ > + The user now needs to enter the verification code received in the mentioned phone number and click `Verify` button.
33
+ > + The application verifies the entered code. If the code validates, the user is redirected to the dashboard section; else the user will be promoted with an error alert `Code invalid or expired` and is required to re-enter the verification code.
34
+ > + As the user is authenticated, the dashboard opens up. The user can logout from the dashboard and login screen would be presented.
@@ -0,0 +1,134 @@
1
+ require 'sinatra'
2
+ require 'json'
3
+ require 'pry'
4
+ require 'cpaas-sdk'
5
+
6
+ require './helper'
7
+
8
+
9
+ class App < Sinatra::Application
10
+ enable :sessions
11
+
12
+ def initialize
13
+ super
14
+
15
+ # Initialize
16
+ Cpaas.configure do |config|
17
+ config.client_id = ENV['CLIENT_ID']
18
+ config.client_secret = ENV['CLIENT_SECRET']
19
+ config.base_url = ENV['BASE_URL']
20
+ end
21
+ end
22
+
23
+ get '/' do
24
+ redirect '/login'
25
+ end
26
+
27
+ get '/login' do
28
+ # If user is logged in and trying to access login page, redirect to dashboard.
29
+ return redirect '/dashboard' if is_logged_in? session
30
+
31
+ set_default_state(session)
32
+
33
+ erb :login, layout: :index
34
+ end
35
+
36
+ post '/login' do
37
+ if valid_credentials? params
38
+ # If login credentials are valid, send_code method is used to request 2FA code
39
+ # to the phone number as destination_address.
40
+ #
41
+ # If a valid response is received, the code_id present in the response is set in the session.
42
+ # This code_id is eventually used when the 2FA code (received in the phone number) needs to be verified.
43
+ # Once the code_id is set, the user is redirected to the code verification page
44
+ # where the user is prompted to enter the code received in the phone number.
45
+ #
46
+ # If an error is raised by send_code, it is caught in the catch block and the user is
47
+ # redirected to the login page with the received error message as an alert.
48
+
49
+ response = Cpaas::Twofactor.send_code({
50
+ destination_address: ENV['PHONE_NUMBER'],
51
+ message: 'Your verification code: {code}'
52
+ })
53
+
54
+ if response[:exception_id]
55
+ # Here something went wrong either with the server or proper parameters were not passed.
56
+ # Received error message is echoed back to the UI as error alert.
57
+ return erb :login, layout: :index, locals: { alert: { message: error_message(response), type: 'error' } }
58
+ end
59
+
60
+ session[:code_id] = response[:code_id]
61
+ set_credentials_verified(session)
62
+
63
+ redirect '/verify'
64
+ else
65
+ # If login credentials do not match with credentials present in .env, login page is re-rendered with error alert
66
+ erb :login, layout: :index, locals: { alert: { message: 'Invalid username or password', type: 'error' } }
67
+ end
68
+ end
69
+
70
+ get '/verify' do
71
+ # If logged in and trying to access login page, redirect to dashboard.
72
+ return redirect '/dashboard' if is_logged_in? session
73
+ # If login credentials are not verified but tries to access the code verification page, user is redirected.
74
+ return redirect '/logout' if !is_credentials_verified? session
75
+
76
+ # If the login credentials are verified, user is shown code verification page.
77
+ erb :verify, layout: :index, locals: { alert: { message: "Verification code has been sent to #{ENV['PHONE_NUMBER']}", type: 'success' } }
78
+ end
79
+
80
+ post '/verify' do
81
+ # The 2FA code entered in the UI is passed to the verify_code along with codeId,
82
+ # which was saved from the response of send_code method.
83
+ #
84
+ # There are two valid response for verify_code method.
85
+ #
86
+ # Type 1 - The 2FA code is successfully verified.
87
+ # {
88
+ # verified: true,
89
+ # message: 'Verified'
90
+ # }
91
+ #
92
+ # Type 2 - The 2FA code pass is either incorrect or the code has expired
93
+ # (The expiry of the code can be changed by passing expiry param in the send_code. Ref - Documentation)
94
+ # {
95
+ # verified: false,
96
+ # message: 'Code expired or invalid'
97
+ # }
98
+
99
+ response = Cpaas::Twofactor.verify_code({
100
+ code_id: session[:code_id],
101
+ verification_code: params['code']
102
+ })
103
+
104
+ if response[:exception_id]
105
+ # Here something went wrong either with the server or proper parameters were not passed.
106
+ # Received error message is echoed back to the UI as error alert.
107
+ return erb :verify, layout: :index, locals: { alert: { message: error_message(response), type: 'error' } }
108
+ end
109
+
110
+ if response[:verified]
111
+ login session
112
+ # The code is verified and redirected to dashboard/portal/protected area of app.
113
+ return redirect '/dashboard'
114
+ else
115
+ # The code is invalid and error message received from server is shown as error alert.
116
+ return erb :verify, layout: :index, locals: { alert: { message: response[:message], type: 'error' } }
117
+ end
118
+ end
119
+
120
+ get '/dashboard' do
121
+ # If not logged in, redirected to logout.
122
+ return redirect '/logout' if !is_logged_in? session
123
+
124
+ # Login criteria is fulfilled, renders dashboard/portal/protected area of app
125
+ erb :dashboard, layout: :index
126
+ end
127
+
128
+ get '/logout' do
129
+ # Logged in session is cleared
130
+ logout session
131
+
132
+ redirect '/login'
133
+ end
134
+ end
@@ -0,0 +1,10 @@
1
+ require 'dotenv'
2
+ require 'rubygems'
3
+ require 'bundler'
4
+
5
+ require './app'
6
+
7
+ Bundler.require
8
+ Dotenv.load
9
+
10
+ run App
@@ -0,0 +1,37 @@
1
+ def valid_credentials?(params)
2
+ ENV['EMAIL'] == params['email'] && ENV['PASSWORD'] == params['password']
3
+ end
4
+
5
+ def error_message(error)
6
+ "#{error[:name]}: #{error[:message]} (#{error[:exception_id]})"
7
+ end
8
+
9
+ def set_credentials_verified(session)
10
+ session[:credentials_verified] = true
11
+ session[:code_verified] = false
12
+ end
13
+
14
+ def is_credentials_verified?(session)
15
+ session[:credentials_verified] && !session[:code_verified]
16
+ end
17
+
18
+ def is_logged_in?(session)
19
+ session[:credentials_verified] && session[:code_verified]
20
+ end
21
+
22
+ def logout(session)
23
+ session[:credentials_verified] = true
24
+ session[:code_verified] = false
25
+ session[:code_id] = nil
26
+ end
27
+
28
+ def set_default_state(session)
29
+ session[:credentials_verified] = false
30
+ session[:code_verified] = false
31
+ end
32
+
33
+
34
+ def login(session)
35
+ session[:credentials_verified] = true
36
+ session[:code_verified] = true
37
+ end
@@ -0,0 +1,28 @@
1
+ .input-group {
2
+ display: flex;
3
+ flex-direction: column;
4
+ }
5
+
6
+ input[type=text],
7
+ input[type=password] {
8
+ border-radius: 4px;
9
+ border: 1px solid #ccc;
10
+ box-sizing: border-box;
11
+ display: inline-block;
12
+ font-size: 14px;
13
+ margin: 8px 0;
14
+ padding: 12px 20px;
15
+ width: 100%;
16
+ }
17
+
18
+ button {
19
+ background-color: #4CAF50;
20
+ border-radius: 5px;
21
+ border: none;
22
+ color: white;
23
+ cursor: pointer;
24
+ font-size: 14px;
25
+ margin: 8px 0;
26
+ padding: 14px 20px;
27
+ width: 100%;
28
+ }
@@ -0,0 +1,7 @@
1
+ body {
2
+ font-family: Arial, Helvetica, sans-serif;
3
+ height: 100%;
4
+ margin: 0;
5
+ padding: 0;
6
+ width: 100%;
7
+ }
@@ -0,0 +1,45 @@
1
+ .box {
2
+ background-color: #f2f2f2;
3
+ border-radius: 5px;
4
+ border: 1px black solid;
5
+ height: 400px;
6
+ padding: 20px;
7
+ width: 300px;
8
+ display: flex;
9
+ flex-direction: column;
10
+ justify-content: center;
11
+ }
12
+
13
+ .centered-box {
14
+ margin: calc((50vh - 200px) / 2) auto;
15
+ }
16
+
17
+ .text-center {
18
+ text-align: center;
19
+ }
20
+
21
+ .alert {
22
+ align-items: center;
23
+ border-radius: 5px;
24
+ border: 1px solid transparent;
25
+ display: flex;
26
+ height: 30px;
27
+ justify-content: center;
28
+ left: 10%;
29
+ padding: 10px 20px;
30
+ position: absolute;
31
+ top: 10px;
32
+ width: 80%;
33
+ }
34
+
35
+ .alert-error {
36
+ color: #721c24;
37
+ background-color: #f8d7da;
38
+ border-color: #f5c6cb;
39
+ }
40
+
41
+ .alert-success {
42
+ color: #155724;
43
+ background-color: #d4edda;
44
+ border-color: #c3e6cb;
45
+ }