sezame-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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f6d57334987a3e68df5d3616469bec1077d1ceaf
4
+ data.tar.gz: aab37915e30af2a759b4dfba942bd5419c20b1bf
5
+ SHA512:
6
+ metadata.gz: 728dd84fe737b122e96a38f183cefaaeb46cc8f1d047a17b355117bf20404552935748a47252734ac08c4a0ceac15816922e33e86e40a6ecf0bfcc3afa08c64b
7
+ data.tar.gz: ebeba0e1e1a63edda11a5103fbec4ec8e88abf1e2cafda52ecb7acee80ad798d31a6161ebb84206c5be7ca58edff53e938f3271beed12f1e39c975491c105ad0
data/lib/sezame-sdk.rb ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sezame-sdk/client'
@@ -0,0 +1,153 @@
1
+ require 'openssl'
2
+ require_relative 'sezamejsonclient'
3
+ require_relative 'response'
4
+
5
+
6
+ module Sezame
7
+
8
+ ##
9
+ # base class for client requests.
10
+ class Client
11
+ attr_reader :http
12
+
13
+ # Expects a certificate string in pem format, the
14
+ # corresponding private key and an optional keypassword
15
+ def initialize(cert = nil, key = nil, keypassword = nil)
16
+ @http = SezameJSONClient.new
17
+ @http.connect_timeout = 10
18
+
19
+ @endpoint = 'https://hqfrontend-finprin.finprin.com/'
20
+
21
+ if cert != nil && key != nil
22
+ @http.ssl_config.client_cert = OpenSSL::X509::Certificate.new(cert)
23
+ @http.ssl_config.client_key = OpenSSL::PKey.read(key, keypassword)
24
+ end
25
+ end
26
+
27
+ # start the self-registration process by specifying
28
+ # a recovery e-mail entered during app installation
29
+ # and a name for your application
30
+ def register(email, name)
31
+ endpoint = @endpoint + 'client/register'
32
+ response = @http.post endpoint, {
33
+ :email => email,
34
+ :name => name
35
+ }
36
+ Sezame::Response::Register.new(response)
37
+ end
38
+
39
+ # helper function for building a csr
40
+ # pass the client code, obtained by the registration call
41
+ # add an e-mail address and additional x509 options
42
+ def makecsr(clientcode, email, x509 = {}, keylen = 2048)
43
+ options = {
44
+ :country => 'AT',
45
+ :state => 'Vienna',
46
+ :city => 'Vienna',
47
+ :organization => '-',
48
+ :department => '-',
49
+ :common_name => clientcode,
50
+ :email => email
51
+ }
52
+ options.merge!(x509)
53
+
54
+ key = OpenSSL::PKey::RSA.new(keylen)
55
+ csr = OpenSSL::X509::Request.new
56
+ csr.version = 0
57
+ csr.subject = OpenSSL::X509::Name.new([
58
+ ['C', options[:country], OpenSSL::ASN1::PRINTABLESTRING],
59
+ ['ST', options[:state], OpenSSL::ASN1::PRINTABLESTRING],
60
+ ['L', options[:city], OpenSSL::ASN1::PRINTABLESTRING],
61
+ ['O', options[:organization], OpenSSL::ASN1::UTF8STRING],
62
+ ['OU', options[:department], OpenSSL::ASN1::UTF8STRING],
63
+ ['CN', options[:common_name], OpenSSL::ASN1::UTF8STRING],
64
+ ['emailAddress', options[:email], OpenSSL::ASN1::UTF8STRING]
65
+ ])
66
+ csr.public_key = key.public_key
67
+ csr.sign(key, OpenSSL::Digest::SHA256.new)
68
+
69
+ {
70
+ :csr => csr.to_pem,
71
+ :key => key.to_pem
72
+ }
73
+ end
74
+
75
+ # let the csr signed by the hq server, pass the
76
+ # shared secret as optained by the register call
77
+ def sign(csr, sharedsecret)
78
+ endpoint = @endpoint + 'client/sign'
79
+ response = @http.post endpoint, {
80
+ :csr => csr,
81
+ :sharedsecret => sharedsecret
82
+ }
83
+ Sezame::Response::Sign.new(response)
84
+ end
85
+
86
+ # check the pairing status for the given username
87
+ def link_status(username)
88
+ endpoint = @endpoint + 'client/link/status'
89
+ response = @http.post endpoint, {
90
+ :username => username
91
+ }
92
+ response.content
93
+ end
94
+
95
+ # pair the given username with your application
96
+ def link(username)
97
+ endpoint = @endpoint + 'client/link'
98
+ response = @http.post endpoint, {
99
+ :username => username
100
+ }
101
+ ret = Sezame::Response::Link.new(response)
102
+ ret.username = username
103
+ ret
104
+ end
105
+
106
+ # remove the pairing for the given username
107
+ def link_delete(username)
108
+ endpoint = @endpoint + 'client/link'
109
+ response = @http.delete endpoint, {
110
+ :username => username
111
+ }
112
+ Sezame::Response::LinkDelete.new(response)
113
+ end
114
+
115
+ # submit an authentication request for the given username
116
+ # the message is displayed on the mobile app
117
+ # the timeout parameter defined the amount of seconds the requests is valid
118
+ # the type of request (auth or fraud)
119
+ # a callback url, results are posted to this url
120
+ # extra_params to be returned with the callback post
121
+ def authorize(username, message = nil, timeout = nil, type = 'auth', callback = nil, extra_params = nil)
122
+ endpoint = @endpoint + 'auth/login'
123
+ params = {
124
+ :username => username
125
+ }
126
+
127
+ params[:type] = type if type
128
+ params[:message] = message if message
129
+ params[:timeout] = timeout if timeout
130
+ params[:callback] = callback if callback
131
+ params[:params] = extra_params if extra_params
132
+
133
+ Sezame::Response::Auth.new(@http.post endpoint, params)
134
+ end
135
+
136
+ # inform the user about fraud attempts, like plaintext password logins
137
+ def fraud(username, message = nil, timeout = nil, callback = nil, extra_params = nil)
138
+ authorize(username, message, timeout, 'fraud', callback, extra_params)
139
+ end
140
+
141
+ # fetch the status of an authentication request
142
+ def status(auth_id)
143
+ endpoint = @endpoint + 'auth/status/' + auth_id
144
+ Sezame::Response::Status.new(@http.get endpoint)
145
+ end
146
+ end
147
+
148
+ # cancel the service
149
+ def cancel
150
+ endpoint = @endpoint + 'client/cancel'
151
+ Sezame::Response::Cancel.new(@http.get endpoint)
152
+ end
153
+ end
@@ -0,0 +1,151 @@
1
+ require 'rqrcode'
2
+
3
+ module Sezame
4
+
5
+ # defines a set of response classes
6
+ # to get easily response values
7
+ module Response
8
+
9
+ # generic response, expects the response as returned by the httpclient
10
+ class Generic
11
+ attr_reader :response
12
+ attr_reader :data
13
+
14
+ def initialize(response)
15
+ @response = response
16
+ @data = response.content
17
+ end
18
+
19
+ def is_empty
20
+ [201, 204, 304].include? @response.status
21
+ end
22
+
23
+ def is_ok
24
+ @response.status == 200
25
+ end
26
+
27
+ def is_notfound
28
+ @response.status == 404
29
+ end
30
+
31
+ def get_status
32
+ unless @data.has_key?('status')
33
+ return nil
34
+ end
35
+
36
+ @data['status']
37
+ end
38
+
39
+ # get the error message return by hq if any
40
+ def get_message
41
+ unless @data.has_key?('message')
42
+ return nil
43
+ end
44
+
45
+ @data['message']
46
+ end
47
+
48
+ # return an array of error messages
49
+ def get_errors
50
+ unless @data.has_key?('errors')
51
+ return []
52
+ end
53
+
54
+ @data['errors']
55
+ end
56
+ end
57
+
58
+ # represents the registration response
59
+ # returns the clientcode and the shared secret
60
+ class Register < Generic
61
+ def is_ok
62
+ super && @data.has_key?('clientcode')
63
+ end
64
+
65
+ def get_clientcode
66
+ @data['clientcode']
67
+ end
68
+
69
+ def get_sharedsecret
70
+ @data['sharedsecret']
71
+ end
72
+ end
73
+
74
+ # represents the sign response
75
+ # returns the certificate
76
+ class Sign < Generic
77
+ def is_ok
78
+ super && @data.has_key?('cert')
79
+ end
80
+
81
+ def get_cert
82
+ @data['cert']
83
+ end
84
+ end
85
+
86
+ # represents an authentication response
87
+ # returns the authentication id
88
+ class Auth < Generic
89
+ def is_ok
90
+ get_status == 'initiated'
91
+ end
92
+
93
+ def get_id
94
+ @data['id']
95
+ end
96
+ end
97
+
98
+ # auth status response
99
+ # returns the status of the authentication request
100
+ class Status < Generic
101
+ def is_authorized
102
+ get_status == 'authorized'
103
+ end
104
+
105
+ def is_denied
106
+ get_status == 'denied'
107
+ end
108
+
109
+ def is_pending
110
+ get_status == 'initiated'
111
+ end
112
+ end
113
+
114
+ # represents the pairing response
115
+ # returns a qrcode
116
+ class Link < Generic
117
+ attr_accessor :username
118
+
119
+ def is_ok
120
+ super && @data.has_key?('id')
121
+ end
122
+
123
+ def qrcode
124
+ linkdata = @data
125
+ linkdata[:username] = username
126
+ RQRCode::QRCode.new(linkdata.to_json)
127
+ end
128
+
129
+ def is_duplicate
130
+ @response.status == 409
131
+ end
132
+ end
133
+
134
+ # remove pairing response
135
+ class LinkDelete < Generic
136
+
137
+ def is_ok
138
+ super || @response.status == 204
139
+ end
140
+ end
141
+
142
+ # cancel service response
143
+ class Cancel < Generic
144
+
145
+ def is_ok
146
+ super || @response.status == 204
147
+ end
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,18 @@
1
+ require 'jsonclient'
2
+
3
+ # parse json in quirks mode, so that JSON fragments (true, false, simple strings) can be handled
4
+ class SezameJSONClient < JSONClient
5
+
6
+ def delete(uri, *args, &block)
7
+ request(:delete, uri, argument_to_hash_for_json(args), &block)
8
+ end
9
+
10
+ private
11
+
12
+ def wrap_json_response(original)
13
+ res = ::HTTP::Message.new_response(JSON.parse(original.content, :quirks_mode => true))
14
+ res.http_header = original.http_header
15
+ res.previous = original
16
+ res
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module SezameSDK
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sezame-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Finpin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rqrcode
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httpclient
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.7'
41
+ description: |
42
+ Passwordless multi-factor authentication.
43
+
44
+ Unlike password-based solutions that require you to remember just another PIN or password,
45
+ sezame is a secure and simple multi-factor authentication solution.
46
+ You only need the username and your fingerprint on your smartphone to log into any sezame-enabled site.
47
+ email:
48
+ - office@finpintech.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/sezame-sdk.rb
54
+ - lib/sezame-sdk/client.rb
55
+ - lib/sezame-sdk/response.rb
56
+ - lib/sezame-sdk/sezamejsonclient.rb
57
+ - lib/sezame-sdk/version.rb
58
+ homepage: https://www.seza.me/
59
+ licenses:
60
+ - BSD
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.2.2
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Sezame ruby SDK
82
+ test_files: []