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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +4 -0
- data/LICENSE.md +1 -0
- data/README.md +25 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/cpaas-sdk.gemspec +32 -0
- data/docs/Cpaas.html +446 -0
- data/docs/Cpaas/Conversation.html +1742 -0
- data/docs/Cpaas/Notification.html +301 -0
- data/docs/Cpaas/TwoFactor.html +908 -0
- data/docs/_index.html +146 -0
- data/docs/_index.md +21 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +496 -0
- data/docs/file.README.html +102 -0
- data/docs/file._index.html +94 -0
- data/docs/file_list.html +56 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +94 -0
- data/docs/js/app.js +303 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +251 -0
- data/docs/mv_index.html +102 -0
- data/docs/top-level-namespace.html +663 -0
- data/examples/2fa/.env.example +6 -0
- data/examples/2fa/.gitignore +159 -0
- data/examples/2fa/.ruby-gemset +1 -0
- data/examples/2fa/.ruby-version +1 -0
- data/examples/2fa/Gemfile +8 -0
- data/examples/2fa/README.md +34 -0
- data/examples/2fa/app.rb +134 -0
- data/examples/2fa/config.ru +10 -0
- data/examples/2fa/helper.rb +37 -0
- data/examples/2fa/public/stylesheets/forms.css +28 -0
- data/examples/2fa/public/stylesheets/global.css +7 -0
- data/examples/2fa/public/stylesheets/layout.css +45 -0
- data/examples/2fa/public/stylesheets/main.css +3 -0
- data/examples/2fa/views/alert.erb +5 -0
- data/examples/2fa/views/dashboard.erb +4 -0
- data/examples/2fa/views/index.erb +17 -0
- data/examples/2fa/views/login.erb +13 -0
- data/examples/2fa/views/verify.erb +8 -0
- data/examples/sms/.env.example +4 -0
- data/examples/sms/.gitignore +159 -0
- data/examples/sms/.ruby-gemset +1 -0
- data/examples/sms/.ruby-version +1 -0
- data/examples/sms/Gemfile +8 -0
- data/examples/sms/README.md +80 -0
- data/examples/sms/app.rb +87 -0
- data/examples/sms/config.ru +10 -0
- data/examples/sms/helper.rb +33 -0
- data/examples/sms/public/scripts/notification.js +46 -0
- data/examples/sms/public/stylesheets/forms.css +28 -0
- data/examples/sms/public/stylesheets/global.css +7 -0
- data/examples/sms/public/stylesheets/layout.css +74 -0
- data/examples/sms/public/stylesheets/main.css +3 -0
- data/examples/sms/views/alert.erb +5 -0
- data/examples/sms/views/index.erb +48 -0
- data/lib/cpaas-sdk.rb +30 -0
- data/lib/cpaas-sdk/api.rb +139 -0
- data/lib/cpaas-sdk/config.rb +9 -0
- data/lib/cpaas-sdk/resources.rb +4 -0
- data/lib/cpaas-sdk/resources/conversation.rb +268 -0
- data/lib/cpaas-sdk/resources/notification.rb +62 -0
- data/lib/cpaas-sdk/resources/notification_channel.rb +39 -0
- data/lib/cpaas-sdk/resources/twofactor.rb +136 -0
- data/lib/cpaas-sdk/util.rb +93 -0
- data/lib/cpaas-sdk/version.rb +3 -0
- data/tutorials/2FA.md +109 -0
- data/tutorials/2fa-flow.png +0 -0
- data/tutorials/GetStarted.md +86 -0
- data/tutorials/SMSMessaging.md +132 -0
- data/tutorials/index.html +86 -0
- data/tutorials/quickstarts.yml +15 -0
- metadata +238 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
7
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/main.css">
|
8
|
+
<title>2FA</title>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<%= erb :alert, locals: locals %>
|
12
|
+
|
13
|
+
<div class="main">
|
14
|
+
<%= yield %>
|
15
|
+
</div>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<form action="/login" method="post" class="box centered-box">
|
2
|
+
<h2 class="text-center">Login</h2>
|
3
|
+
<div class="input-group">
|
4
|
+
<label for="email">Email</label>
|
5
|
+
<input type="text" id="email" name="email" />
|
6
|
+
</div>
|
7
|
+
<div class="input-group">
|
8
|
+
<label for="password">Password</label>
|
9
|
+
<input type="password" id="password" name="password" />
|
10
|
+
</div>
|
11
|
+
<button type="submit">Login</button>
|
12
|
+
</form>
|
13
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<form action="/verify" method="post" class="box centered-box">
|
2
|
+
<h2 class="text-center">Verify</h2>
|
3
|
+
<div class="input-group">
|
4
|
+
<label for="code">Verification code</label>
|
5
|
+
<input type="text" id="code" maxlength="6" name="code" />
|
6
|
+
<button type="submit">Verify</button>
|
7
|
+
</div>
|
8
|
+
</form>
|
@@ -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-sms
|
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.5.0
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# SMS Starter Example
|
2
|
+
|
3
|
+
This is a simple sms application where a user can send an sms, subscribe sms notification and receive real-time sms events (inbound, outbound etc notification).
|
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 purchased in CPaaS portal (sender phone number)
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
The application has a single simple page with 3 section:
|
28
|
+
|
29
|
+
### Section 1 - Send SMS
|
30
|
+
---
|
31
|
+
There are two fields in the form
|
32
|
+
|
33
|
+
1. Phone number - The phone number where the SMS is to be sent.
|
34
|
+
2. Message - A text message for the SMS
|
35
|
+
|
36
|
+
When clicked on `Send` button, an SMS is sent out where the `sender` phone number is the one add in `.env` file (PHONE_NUMBER) and `destination` is the one entered in the form.
|
37
|
+
|
38
|
+
### Section 2 - SMS notification subscription
|
39
|
+
---
|
40
|
+
This represents the subscription to SMS notification and can be found on the top right section. Here a Webhook host URL is to be added.
|
41
|
+
|
42
|
+
As incoming notifications are to be received by the local server, there is a requirement of a web server to be running and that web server to have a public IP address. So to use this it is recommended to install and use [ngrok](https://ngrok.com/).
|
43
|
+
|
44
|
+
#### How to use ngrok
|
45
|
+
Once `ngrok` is installed, run the following command
|
46
|
+
```bash
|
47
|
+
ngrok http 3001
|
48
|
+
```
|
49
|
+
3001 is the `PORT` that is defined in the `.env` file, so it has to be entered appropriately.
|
50
|
+
Once `ngrok` starts forwarding the `localhost`, you would find a similar kind of message in your screen.
|
51
|
+
|
52
|
+
```bash
|
53
|
+
ngrok by @inconshreveable (Ctrl+C to quit)
|
54
|
+
|
55
|
+
Session Status online
|
56
|
+
Session Expires 7 hours, 58 minutes
|
57
|
+
Update update available (version 2.3.34, Ctrl-U to update)
|
58
|
+
Version 2.3.28
|
59
|
+
Region United States (us)
|
60
|
+
Web Interface http://127.0.0.1:4040
|
61
|
+
Forwarding http://29de1e3e.ngrok.io -> http://localhost:3001
|
62
|
+
Forwarding https://29de1e3e.ngrok.io -> http://localhost:3001
|
63
|
+
|
64
|
+
Connections ttl opn rt1 rt5 p50 p90
|
65
|
+
0 0 0.00 0.00 0.00 0.00
|
66
|
+
```
|
67
|
+
After this the usage part of `ngrok` is done and we got out public domain, let's shift out attention to the notification subscription.
|
68
|
+
|
69
|
+
Copy the `forwarding` domain, for our case it is `https://29de1e3e.ngrok.io` from above and paste it to in the `Webhook host URL` input field in out `SMS starter app`.
|
70
|
+
Click `Subscribe` and a notification channel would be created with the above domain against the phone number that is described in the `.env` file (PHONE_NUMBER) and all the sms notifications would start coming in.
|
71
|
+
|
72
|
+
> Note: While entering the ngrok domain and subscribing, make sure that there is not forward slash at the end of the domain.
|
73
|
+
|
74
|
+
> **Correct** `https://29de1e3e.ngrok.io`
|
75
|
+
|
76
|
+
> **Incorrect** `https://29de1e3e.ngrok.io/`
|
77
|
+
|
78
|
+
### Section 3 - SMS Notification
|
79
|
+
This is the bottom half of the right section of the application. As in `section 2` we subscribed for all the SMS notification against the phone number described in the `.env` file (PHONE_NUMBER), whenever we send out an sms using the `Send SMS` section or get an sms to the phone number described in the `.env` file (PHONE_NUMBER), we would receive a notification and that notification would be printed out under the `SMS Notification` header
|
80
|
+
|
data/examples/sms/app.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'json'
|
3
|
+
require 'pry'
|
4
|
+
require 'cpaas-sdk'
|
5
|
+
|
6
|
+
require './helper'
|
7
|
+
|
8
|
+
class App < Sinatra::Application
|
9
|
+
enable :sessions
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super
|
13
|
+
|
14
|
+
# Initialize
|
15
|
+
Cpaas.configure do |config|
|
16
|
+
config.client_id = ENV['CLIENT_ID']
|
17
|
+
config.client_secret = ENV['CLIENT_SECRET']
|
18
|
+
config.base_url = ENV['BASE_URL']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/' do
|
23
|
+
type = params['success'] ? 'success' : 'error'
|
24
|
+
message = params[type]
|
25
|
+
|
26
|
+
erb :index, locals: { alert: { message: message, type: type } }
|
27
|
+
end
|
28
|
+
|
29
|
+
post '/send' do
|
30
|
+
#
|
31
|
+
# The method create_message would send an sms when the 'type' attribute is 'SMS'
|
32
|
+
#
|
33
|
+
puts ENV['PHONE_NUMBER']
|
34
|
+
response = Cpaas::Conversation.create_message({
|
35
|
+
type: Cpaas::Conversation.types[:SMS],
|
36
|
+
destination_address: params['number'],
|
37
|
+
message: params['message'],
|
38
|
+
sender_address: ENV['PHONE_NUMBER']
|
39
|
+
})
|
40
|
+
|
41
|
+
puts response
|
42
|
+
|
43
|
+
return redirect "/?error=#{error_message(response)}" if response[:exception_id]
|
44
|
+
|
45
|
+
redirect '/?success=Success'
|
46
|
+
end
|
47
|
+
|
48
|
+
post '/subscribe' do
|
49
|
+
#
|
50
|
+
# The subscribe method would enable a notification subscription for a purchased number (destination) and the
|
51
|
+
# webhook_url is the public POST endpoint where notifications would be received. For this exable the
|
52
|
+
# '/webhook' endpoint is enabled for the incoming notification.
|
53
|
+
#
|
54
|
+
|
55
|
+
response = Cpaas::Conversation.subscribe({
|
56
|
+
type: Cpaas::Conversation.types[:SMS],
|
57
|
+
destination_address: ENV['PHONE_NUMBER'],
|
58
|
+
webhook_url: "#{params['webhook']}/webhook"
|
59
|
+
})
|
60
|
+
|
61
|
+
puts response
|
62
|
+
|
63
|
+
return redirect "/?error=#{error_message(response)}" if response[:exception_id]
|
64
|
+
|
65
|
+
redirect '/?success=Created subscription'
|
66
|
+
end
|
67
|
+
|
68
|
+
post '/webhook' do
|
69
|
+
body = JSON.parse request.body.read
|
70
|
+
|
71
|
+
#
|
72
|
+
# The Cpaas::Notification.parse will parse the received notification and will return a
|
73
|
+
# simplified version of th notification to consume
|
74
|
+
#
|
75
|
+
|
76
|
+
notification = Cpaas::Notification.parse(body)
|
77
|
+
|
78
|
+
add_notification(notification) # Helper method, check helper.rb
|
79
|
+
|
80
|
+
status 200
|
81
|
+
end
|
82
|
+
|
83
|
+
get '/notifications' do
|
84
|
+
content_type :json
|
85
|
+
notifications.to_json # Helper method, check helper.rb
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
FILE_NAME = 'notifications.json'
|
2
|
+
PATH = "#{Dir.pwd}/tmp/#{FILE_NAME}"
|
3
|
+
|
4
|
+
def error_message(error)
|
5
|
+
"#{error[:name]}: #{error[:message]} (#{error[:exception_id]})"
|
6
|
+
end
|
7
|
+
|
8
|
+
def notifications
|
9
|
+
return [] if !File.file?(PATH)
|
10
|
+
|
11
|
+
all_notifications = JSON.parse(read_file)
|
12
|
+
all_notifications[ENV['PHONE_NUMBER']]
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_notification(notification)
|
16
|
+
all_notifications = JSON.parse(read_file)
|
17
|
+
|
18
|
+
all_notifications[ENV['PHONE_NUMBER']] = [] if all_notifications[ENV['PHONE_NUMBER']].nil?
|
19
|
+
all_notifications[ENV['PHONE_NUMBER']].unshift(notification)
|
20
|
+
|
21
|
+
write_file(all_notifications.to_json)
|
22
|
+
end
|
23
|
+
|
24
|
+
def read_file
|
25
|
+
File.file?(PATH) ? File.read(PATH) : "{}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def write_file(content)
|
29
|
+
notification_file = File.file?(PATH) ? File.open(PATH, 'w') : File.new(PATH, 'w')
|
30
|
+
|
31
|
+
notification_file.puts(content)
|
32
|
+
notification_file.close
|
33
|
+
end
|