goserv-user 0.0.1.alpha.1
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/Rakefile +11 -0
- data/app.rb +72 -0
- data/config/database.yml +23 -0
- data/config.ru +10 -0
- data/db/migrate/20170326180724_initial_migration.rb +17 -0
- data/db/schema.rb +32 -0
- data/lib/goserv-user/prehandlers.rb +18 -0
- data/lib/goserv-user/schema/signin.rb +30 -0
- data/lib/goserv-user/schema.rb +1 -0
- data/lib/goserv-user/users/errors.rb +11 -0
- data/lib/goserv-user/users/models.rb +29 -0
- data/lib/goserv-user/users.rb +40 -0
- data/lib/goserv-user/version.rb +3 -0
- data/lib/goserv-user.rb +10 -0
- metadata +212 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fcc05121b5a6f18010a6dafb98b030e740e451e4
|
4
|
+
data.tar.gz: f6571cea15ffa9d5d94721fd1c1c3090e8d61a03
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 66454eb3633f2527efa161cb0c6efc0a610e06c03757fdb5f9d9bd990099eb91106f62ec83c40d40dbb08088fda49c7e59f44a4073396e677c6aab32245e850e
|
7
|
+
data.tar.gz: f874a0a60c4d00554eb6e83f4c62987c770c3e88f0e54ad59248e79ebe50780d508be9adcb622a95770aab2c0d51e58c327e6444da13b00e66dadfd119d4bd83
|
data/Rakefile
ADDED
data/app.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/activerecord'
|
3
|
+
require 'json'
|
4
|
+
require 'goserv-user'
|
5
|
+
require 'goserv-util'
|
6
|
+
|
7
|
+
# GoServApp: Main controller for the API
|
8
|
+
class GoServApp < Sinatra::Base
|
9
|
+
include GoUtil::Log
|
10
|
+
|
11
|
+
register Sinatra::ActiveRecordExtension
|
12
|
+
|
13
|
+
before '/*' do
|
14
|
+
log.begin_request(request)
|
15
|
+
end
|
16
|
+
|
17
|
+
post '/login' do
|
18
|
+
body = Prehandlers::Login.prehandle(request)
|
19
|
+
user = Users.authenticate(body)
|
20
|
+
JSON.pretty_generate(
|
21
|
+
code: 'SUCCESS',
|
22
|
+
token: user.token
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
post '/signup' do
|
27
|
+
body = Prehandlers::Signup.prehandle(request)
|
28
|
+
Users.create_user(body)
|
29
|
+
JSON.pretty_generate(code: 'SUCCESS')
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.register_error(*codes, err_status:, err_code:, err_reasons: [])
|
33
|
+
error(*codes) do
|
34
|
+
err = env['sinatra.error']
|
35
|
+
log.request_error err, err_status
|
36
|
+
status err_status
|
37
|
+
|
38
|
+
err_reasons = err.full_messages if err.respond_to? :full_messages
|
39
|
+
|
40
|
+
JSON.pretty_generate code: err_code, errors: err_reasons
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
register_error(
|
45
|
+
err_status: '500 Internal Server Error',
|
46
|
+
err_code: 'INTERNAL_ERROR'
|
47
|
+
)
|
48
|
+
|
49
|
+
register_error(
|
50
|
+
GoUser::AuthError,
|
51
|
+
err_status: '401 Bad Request',
|
52
|
+
err_code: 'AUTH_ERROR'
|
53
|
+
)
|
54
|
+
|
55
|
+
register_error(
|
56
|
+
GoUtil::Request::SchemaValidationError,
|
57
|
+
err_status: '400 Bad Request',
|
58
|
+
err_code: 'SCHEMA_VALIDATION'
|
59
|
+
)
|
60
|
+
|
61
|
+
register_error(
|
62
|
+
JSON::ParserError,
|
63
|
+
err_status: '400 Bad Request',
|
64
|
+
err_code: 'JSON_PARSING'
|
65
|
+
)
|
66
|
+
|
67
|
+
register_error(
|
68
|
+
GoUser::UserValidationError,
|
69
|
+
err_status: '409 Conflict',
|
70
|
+
err_code: 'USER_INVALID'
|
71
|
+
)
|
72
|
+
end
|
data/config/database.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
development:
|
2
|
+
adapter: postgresql
|
3
|
+
host: ''
|
4
|
+
database: goserv_dev
|
5
|
+
pool: 5
|
6
|
+
timeout: 5000
|
7
|
+
username: goserv
|
8
|
+
|
9
|
+
production:
|
10
|
+
adapter: postgresql
|
11
|
+
host: ''
|
12
|
+
encoding: utf-8
|
13
|
+
database: goserv
|
14
|
+
pool: 5
|
15
|
+
username: goserv
|
16
|
+
|
17
|
+
test: &test
|
18
|
+
adapter: postgresql
|
19
|
+
host: ''
|
20
|
+
database: goserv_test
|
21
|
+
pool: 5
|
22
|
+
timeout: 5000
|
23
|
+
username: goserv
|
data/config.ru
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class InitialMigration < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :users do |tab|
|
4
|
+
tab.string :username
|
5
|
+
tab.string :password_digest
|
6
|
+
tab.string :email
|
7
|
+
tab.string :status
|
8
|
+
tab.string :token
|
9
|
+
tab.string :password_reset
|
10
|
+
tab.datetime :token_created_at
|
11
|
+
tab.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :users, :username, unique: true
|
15
|
+
add_index :users, :token, unique: true
|
16
|
+
end
|
17
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
6
|
+
# database schema. If you need to create the application database on another
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
10
|
+
#
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(version: 20170326180724) do
|
14
|
+
|
15
|
+
# These are extensions that must be enabled in order to support this database
|
16
|
+
enable_extension "plpgsql"
|
17
|
+
|
18
|
+
create_table "users", force: :cascade do |t|
|
19
|
+
t.string "username"
|
20
|
+
t.string "password_digest"
|
21
|
+
t.string "email"
|
22
|
+
t.string "status"
|
23
|
+
t.string "token"
|
24
|
+
t.string "password_reset"
|
25
|
+
t.datetime "token_created_at"
|
26
|
+
t.datetime "created_at", null: false
|
27
|
+
t.datetime "updated_at", null: false
|
28
|
+
t.index ["token"], name: "index_users_on_token", unique: true, using: :btree
|
29
|
+
t.index ["username"], name: "index_users_on_username", unique: true, using: :btree
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'goserv-util'
|
2
|
+
require_relative 'schema'
|
3
|
+
|
4
|
+
module Prehandlers
|
5
|
+
# user creation request prehandling.
|
6
|
+
class Signup
|
7
|
+
include GoUtil::Request::Prehandler
|
8
|
+
has_json_body
|
9
|
+
self.schema = Schema.signin
|
10
|
+
end
|
11
|
+
|
12
|
+
# user login request prehandling
|
13
|
+
class LoginHandler
|
14
|
+
include GoUtil::Request::Prehandler
|
15
|
+
has_json_body
|
16
|
+
self.schema = Schema.login
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Schema
|
2
|
+
def self.signin
|
3
|
+
{
|
4
|
+
type: 'object',
|
5
|
+
required: %w(username password email),
|
6
|
+
properties: {
|
7
|
+
username: {
|
8
|
+
type: 'string',
|
9
|
+
maxLength: 16,
|
10
|
+
minLength: 3
|
11
|
+
},
|
12
|
+
password: {
|
13
|
+
type: 'string',
|
14
|
+
maxLength: 16,
|
15
|
+
minLength: 8
|
16
|
+
},
|
17
|
+
email: {
|
18
|
+
type: 'string',
|
19
|
+
pattern: '/\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i'
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.login
|
26
|
+
{
|
27
|
+
type: 'object'
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'schema/signin'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'sinatra/activerecord'
|
2
|
+
|
3
|
+
module GoUser
|
4
|
+
# User model
|
5
|
+
class User < ActiveRecord::Base
|
6
|
+
has_secure_password
|
7
|
+
has_secure_token
|
8
|
+
has_secure_token :password_reset
|
9
|
+
|
10
|
+
before_save :default_values
|
11
|
+
|
12
|
+
validates :username, presence: true, uniqueness: true
|
13
|
+
validates :email, presence: true, uniqueness: true
|
14
|
+
validates :password, presence: true
|
15
|
+
|
16
|
+
def refresh_auth_token
|
17
|
+
update!(
|
18
|
+
token_created_at: DateTime.now,
|
19
|
+
token: self.class.generate_unique_secure_token
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def default_values
|
26
|
+
self.status ||= 'P'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'goserv-util'
|
2
|
+
require_relative 'users/models'
|
3
|
+
require_relative 'users/errors'
|
4
|
+
|
5
|
+
# user creation / authentication logic.
|
6
|
+
module GoUser
|
7
|
+
HOUR = 60 * 60
|
8
|
+
DAY = HOUR * 24
|
9
|
+
WEEK = DAY * 7
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def create_user(username:, password:, email:)
|
13
|
+
user = User.create(
|
14
|
+
username: username,
|
15
|
+
password: password,
|
16
|
+
email: email
|
17
|
+
)
|
18
|
+
raise(UserValidationError.new(user), 'create failed') unless user.valid?
|
19
|
+
user
|
20
|
+
end
|
21
|
+
|
22
|
+
def authenticate_token(token)
|
23
|
+
users = User.where(token: token)
|
24
|
+
raise(AuthError.new, 'Token not found') if users.empty?
|
25
|
+
user = users.first
|
26
|
+
t = user.token_created_at
|
27
|
+
raise(AuthError.new, 'Token expired') if t.nil? || t > DateTime.now + DAY
|
28
|
+
user
|
29
|
+
end
|
30
|
+
|
31
|
+
def authenticate(username, password)
|
32
|
+
users = User.where(username: username)
|
33
|
+
raise(AuthError.new, 'Username not found') if users.empty?
|
34
|
+
user = users.first
|
35
|
+
correct = user.authenticate(password)
|
36
|
+
raise(AuthError.new, 'Authentication failed') unless correct
|
37
|
+
user
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/goserv-user.rb
ADDED
metadata
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: goserv-user
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.alpha.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben C Lewis
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: database_cleaner
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: passenger
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 5.0.25
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 5.0.25
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sinatra
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.4.5
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.4.5
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activerecord
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '5.0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '5.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pg
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.20'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.20'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: bcrypt
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sinatra-activerecord
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: goserv-util
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.0.0.alpha
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.0.0.alpha
|
167
|
+
description: Provides an API to create and authenticate goserv users
|
168
|
+
email:
|
169
|
+
- benjamin.connah.lewis@gmail.com
|
170
|
+
executables: []
|
171
|
+
extensions: []
|
172
|
+
extra_rdoc_files: []
|
173
|
+
files:
|
174
|
+
- Rakefile
|
175
|
+
- app.rb
|
176
|
+
- config.ru
|
177
|
+
- config/database.yml
|
178
|
+
- db/migrate/20170326180724_initial_migration.rb
|
179
|
+
- db/schema.rb
|
180
|
+
- lib/goserv-user.rb
|
181
|
+
- lib/goserv-user/prehandlers.rb
|
182
|
+
- lib/goserv-user/schema.rb
|
183
|
+
- lib/goserv-user/schema/signin.rb
|
184
|
+
- lib/goserv-user/users.rb
|
185
|
+
- lib/goserv-user/users/errors.rb
|
186
|
+
- lib/goserv-user/users/models.rb
|
187
|
+
- lib/goserv-user/version.rb
|
188
|
+
homepage: https://github.com/goserv/user
|
189
|
+
licenses:
|
190
|
+
- MIT
|
191
|
+
metadata: {}
|
192
|
+
post_install_message:
|
193
|
+
rdoc_options: []
|
194
|
+
require_paths:
|
195
|
+
- lib
|
196
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
202
|
+
requirements:
|
203
|
+
- - ">"
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: 1.3.1
|
206
|
+
requirements: []
|
207
|
+
rubyforge_project:
|
208
|
+
rubygems_version: 2.5.1
|
209
|
+
signing_key:
|
210
|
+
specification_version: 4
|
211
|
+
summary: User service for goserv
|
212
|
+
test_files: []
|