api_pack 1.0.1 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf4c6bafb046c3e5e2973fffa4d6ef460e97c54c49fc2a53ee97d765068763e0
4
- data.tar.gz: 88203c2eaad28463a1280d6d86987b9dd2f8a8d2e46359669a3a381bb90fd3a2
3
+ metadata.gz: 90690a0d83cc8cc7f5ceea8bac821b5e37a4041c8f86422dcc46e0441ba6e274
4
+ data.tar.gz: 6a4c83180bd090e1b8e64eec029cbb3074a53b66c37a92de6ab0abba1032704f
5
5
  SHA512:
6
- metadata.gz: e030fc6456c257babab2f92a1bc026e4df1c8782d7cd1b54279de0352e89404d8e5e0f8fbad82e1811f92905d8ccbf59d361b02fcb4e43b9c6dea6e9ad09fcf8
7
- data.tar.gz: 81e97e117806d75a3bffc3c78f341f3fba67fc59d69e7e80510d6d161c3ed6d81eec0286cdfb109e43219bf1ebd49921b4f04321c3e6efa103482b5ce41e3872
6
+ metadata.gz: 223b02240830989e6f7c16d0e0cea2ae124af88a71ef4c75cf302085803bee46975fe2f7485161cc83aa0824ea80617c4df44e5b7896d65d579c27272cc3f99b
7
+ data.tar.gz: 32fe39dadf86fe81880657b42e113a80bc23a58da82e962515738fef898856b8b2e2e7e5bf4088cb58a9919a83ab352d7cd4d281e581d3887daae75b86279136
data/.gitignore CHANGED
@@ -8,6 +8,7 @@
8
8
  /tmp/
9
9
  Gemfile.lock
10
10
  .DS_store
11
+ api_pack-*
11
12
 
12
13
  # rspec failure tracking
13
14
  .rspec_status
data/README.md CHANGED
@@ -1,18 +1,30 @@
1
- [![Build Status](https://travis-ci.org/Jllima/api_pack.svg?branch=master)](https://travis-ci.org/Jllima/api_pack)
1
+ [![Gem Version](https://badge.fury.io/rb/api_pack.svg)](https://badge.fury.io/rb/api_pack)
2
+ [![Build Status](https://www.travis-ci.com/Jllima/api_pack.svg?branch=master)](https://www.travis-ci.com/Jllima/api_pack)
2
3
  [![Coverage Status](https://coveralls.io/repos/github/Jllima/api_pack/badge.svg?branch=master)](https://coveralls.io/github/Jllima/api_pack?branch=master)
3
4
 
4
5
  # ApiPack
5
6
 
6
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/api_pack`. To experiment with that code, run `bin/console` for an interactive prompt.
7
+ ApiPack is a set of helpers to Api rails
7
8
 
8
- TODO: Delete this and the text above, and describe your gem
9
+ **This project provides the following helpers**
10
+
11
+ - Json Web Token helpers
12
+ - Json Api especifications
13
+ - Errors Serializers
14
+ - Pagination links Serializers
15
+ - Serializer Adapter (BETA)
16
+
17
+ ## Compatibility
18
+ ```
19
+ ruby >= 2.4
20
+ ```
9
21
 
10
22
  ## Installation
11
23
 
12
24
  Add this line to your application's Gemfile:
13
25
 
14
26
  ```ruby
15
- gem 'api_pack'
27
+ gem 'api_pack', '~> 1.1.4'
16
28
  ```
17
29
 
18
30
  And then execute:
@@ -25,13 +37,174 @@ Or install it yourself as:
25
37
 
26
38
  ## Usage
27
39
 
28
- TODO: Write usage instructions here
40
+ ### JsonWebToken methods
41
+ - First create file api_pack.rb in initializers in put this code
42
+ ```ruby
43
+ Rails.application.config.to_prepare do
44
+ ApiPack.hmac_secret = 'your_secret_key'
45
+ end
46
+ ```
47
+ - ApiPack::JsonWebToken.encode({ user_id: user.id }) \
48
+ returns a valid token with an expiration time of one day by default
49
+ - To change o expiration call method with parameter exp:
50
+ ```ruby
51
+ ApiPack::JsonWebToken.encode({ user_id: user.id, exp: 123 })
52
+ ```
53
+
54
+ Usage in a service authenticate user
55
+
56
+ ApiPack use gem JWT
57
+
58
+ ```ruby
59
+ class AuthenticateUser
60
+ def initialize(email, password)
61
+ @email = email
62
+ @password = password
63
+ end
64
+
65
+ def call
66
+ # return token valid
67
+ ApiPack::JsonWebToken.encode({ user_id: user.id }) if user
68
+ end
69
+
70
+ private
71
+
72
+ attr_accessor :email, :password
73
+
74
+ def user
75
+ user = User.find_by(email: email)
76
+ return user if user&.authenticate(password)
77
+
78
+ # raise AuthenticationError if authenticate fail
79
+ raise(ApiPack::Errors::Auth::AuthenticationError, 'Invalid credentials')
80
+ end
81
+ end
82
+ ```
83
+
84
+ - ApiPack::JsonWebToken.decode(http_auth_header)
85
+
86
+ Usage in a service authorize api request
87
+
88
+ ```ruby
89
+ class AuthorizeApiRequest
90
+ def initialize(headers: {})
91
+ @headers = headers
92
+ end
93
+
94
+ def call
95
+ { user: user }
96
+ end
97
+
98
+ private
99
+
100
+ attr_accessor :headers
101
+
102
+ def user
103
+ @user ||= User.find(decoded_auth_token['user_id']) if decoded_auth_token
104
+ rescue ActiveRecord::RecordNotFound => e
105
+ # raise InvalidToken if user not found
106
+ raise ApiPack::Errors::Auth::InvalidToken, ("Invalid token #{e.message}")
107
+ end
108
+
109
+ def decoded_auth_token
110
+ # decode a token valid
111
+ @decoded_auth_token ||= ApiPack::JsonWebToken.decode(http_auth_header)
112
+ end
113
+
114
+ def http_auth_header
115
+ return headers['Authorization'].split(' ').last if headers['Authorization'].present?
116
+
117
+ raise(ApiPack::Errors::Auth::MissingToken, 'Missing token')
118
+ end
119
+ end
120
+ ```
121
+
122
+ ### Errors Serializers
123
+
124
+ - Errors handled \
125
+ ActiveRecord::RecordNotFound \
126
+ ActionController::ParameterMissing \
127
+ ActiveRecord::RecordInvalid
128
+
129
+ - ApiPack::Errors::HandleError.new(e).call
130
+
131
+ create an ExceptionHandler concern and deal with api errors in json api format
132
+
133
+ ```ruby
134
+ module ExceptionHandler
135
+ extend ActiveSupport::Concern
136
+
137
+ included do
138
+ rescue_from StandardError do |e|
139
+ result = ApiPack::Errors::HandleError.new(e).call
140
+ render json: result[:body], status: result[:status]
141
+ end
142
+ end
143
+ end
144
+ ```
145
+
146
+ ### Serializer Parser Adapter (BETA)
147
+
148
+ This Parser aims to provide adapters for using serializers like FastJsonApi
149
+
150
+ Default is FastJsonApi
151
+
152
+ By convection the serializers should be in
153
+
154
+ serializers/name_serializer/class_serializer
155
+
156
+ Ex: serializers/fast_jsonapi/user_serializer.rb
157
+
158
+ USAGE:
159
+ - Create initializer serilializer_parser.rb and put this code
160
+
161
+
162
+ ```ruby
163
+ ApiPack::Serializer::Parser.adapter = :fast_json_api
164
+ ```
165
+
166
+ - include ApiPack::ApiHelper in aplication_controler.rb
167
+
168
+ ```ruby
169
+ class ApplicationController < ActionController::API
170
+ include ApiPack::ApiHelper
171
+ end
172
+ ```
173
+ - use method serializer_hash to return an hash
174
+
175
+ ```ruby
176
+ def index
177
+ users = User.all
178
+
179
+ render json: serializer_hash(users, :user)
180
+ end
181
+ ```
182
+ ## Pagination Links
183
+ - pagination_meta_generator \
184
+ Return an hash with pagination links
185
+ - Apipack has default per page like 10
186
+ - To change o defaut_per_page create an initializer api_pack and put this code
187
+
188
+ ```ruby
189
+ ApiPack.defaut_per_page = 12
190
+ ```
191
+
192
+ ```ruby
193
+ def index
194
+ # current_page mtehod default is 1
195
+ # per_page method default is 10
196
+ users = User.page(current_page).per_page(per_page)
197
+
198
+ options = pagination_meta_generator(request, users.total_pages)
199
+
200
+ render json: serializer_hash(users, :user, opt: options)
201
+ end
202
+ ```
29
203
 
30
- ## Development
204
+ ## This example project uses gem api_apck
31
205
 
32
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
206
+ https://github.com/Jllima/api_pack_rails
33
207
 
34
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
35
208
 
36
209
  ## Contributing
37
210
 
data/lib/api_pack.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'jwt'
2
2
  require 'fast_jsonapi'
3
3
  require 'api_pack/version'
4
+ require 'api_pack/api_helper'
4
5
  require 'api_pack/json_web_token'
5
6
  require 'api_pack/pagination_meta_generator'
6
7
  require 'api_pack/errors/auth'
@@ -9,25 +10,29 @@ require 'api_pack/errors/handle_error'
9
10
  require 'api_pack/errors/api_errors_serializer'
10
11
  require 'api_pack/errors/validation_error_serializer'
11
12
  require 'api_pack/errors/validation_errors_serializer'
12
- require 'api_pack/constants'
13
- require 'api_pack/support/api_helper'
13
+ require 'api_pack/support/helper'
14
14
  require 'api_pack/serializer/parser'
15
15
 
16
16
  module ApiPack
17
17
  module_function
18
18
 
19
- PER_PAGE = 10
20
- # 24 hours from now
21
- DEFAULT_EXP = (Time.now + 1 * 86_400).to_i
22
-
23
- attr_writer :default_per_page, :exp
19
+ DEFAULT_PAGE = 1
20
+ DEFAULT_PER_PAGE = 5
21
+
22
+ def default_per_page=(value)
23
+ @default_per_page = value
24
+ end
24
25
 
25
26
  def default_per_page
26
- @default_per_page ||= PER_PAGE
27
+ @default_per_page ||= DEFAULT_PER_PAGE
28
+ end
29
+
30
+ def hmac_secret=(value)
31
+ @hmac_secret = value
27
32
  end
28
33
 
29
- def exp
30
- @exp ||= DEFAULT_EXP
34
+ def hmac_secret
35
+ @hmac_secret
31
36
  end
32
37
 
33
38
  def serializer_adapter=(adapter)
@@ -0,0 +1,23 @@
1
+ module ApiPack
2
+ module ApiHelper
3
+ def pagination_meta_generator(request, total_pages)
4
+ ApiPack::PaginationMetaGenerator.new(request: request, total_pages: total_pages).call
5
+ end
6
+
7
+ def current_page
8
+ return params[:page].to_i if defined?(params[:page]) && !params[:page].nil?
9
+
10
+ ApiPack::DEFAULT_PAGE
11
+ end
12
+
13
+ def per_page
14
+ return params[:per_page].to_i if defined?(params[:per_page]) && !params[:per_page].nil?
15
+
16
+ ApiPack.default_per_page
17
+ end
18
+
19
+ def serializer_hash(resource, class_name, opt: {})
20
+ ApiPack::Serializer::Parser.serializer_hash(resource, class_name, opt: opt)
21
+ end
22
+ end
23
+ end
@@ -4,6 +4,7 @@ module ApiPack
4
4
  class AuthenticationError < StandardError; end
5
5
  class InvalidToken < StandardError; end
6
6
  class MissingToken < StandardError; end
7
+ class MissingHmacSecret < StandardError; end
7
8
  end
8
9
  end
9
10
  end
@@ -24,8 +24,8 @@ module ApiPack
24
24
  },
25
25
  'ApiPack::Errors::Auth::InvalidToken' => {
26
26
  method: :error_message_body,
27
- title: 'Invalid Token',
28
- status: :unprocessable_entity
27
+ title: 'Access Denied - Invalid Token',
28
+ status: :forbidden
29
29
  },
30
30
  'ApiPack::Errors::Auth::MissingToken' => {
31
31
  method: :error_message_body,
@@ -1,13 +1,18 @@
1
1
  module ApiPack
2
2
  class JsonWebToken
3
- def self.encode(payload, exp: ApiPack.exp)
3
+ # exp: 24 hours from now
4
+ def self.encode(payload, exp: (Time.now + 1 * 86_400).to_i)
5
+ raise ApiPack::Errors::Auth::MissingHmacSecret if ApiPack.hmac_secret.nil?
6
+
4
7
  payload[:exp] = exp.to_i
5
8
 
6
- JWT.encode(payload, ApiPack::HMAC_SECRET)
9
+ JWT.encode(payload, ApiPack.hmac_secret)
10
+ rescue ApiPack::Errors::Auth::MissingHmacSecret
11
+ raise ApiPack::Errors::Auth::MissingHmacSecret, 'ApiPach.hmac_secret is missing'
7
12
  end
8
13
 
9
14
  def self.decode(token)
10
- JWT.decode(token, ApiPack::HMAC_SECRET).first
15
+ JWT.decode(token, ApiPack.hmac_secret).first
11
16
  rescue JWT::DecodeError => e
12
17
  raise ApiPack::Errors::Auth::InvalidToken, e.message
13
18
  end
@@ -1,8 +1,8 @@
1
- require 'api_pack/support/api_helper'
1
+ require 'api_pack/support/helper'
2
2
 
3
3
  module ApiPack
4
4
  class PaginationMetaGenerator
5
- include Support::ApiHelper
5
+ include Support::Helper
6
6
 
7
7
  def initialize(request:, total_pages:)
8
8
  @url = "#{request.base_url}#{request.path}"
@@ -1,5 +1,5 @@
1
1
  module Support
2
- module ApiHelper
2
+ module Helper
3
3
  def to_query_api(params)
4
4
  query = params.collect do |key, value|
5
5
  "#{key}=#{value}"
@@ -1,3 +1,3 @@
1
1
  module ApiPack
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.2.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_pack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jorge
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-20 00:00:00.000000000 Z
11
+ date: 2021-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,7 +60,7 @@ files:
60
60
  - bin/console
61
61
  - bin/setup
62
62
  - lib/api_pack.rb
63
- - lib/api_pack/constants.rb
63
+ - lib/api_pack/api_helper.rb
64
64
  - lib/api_pack/errors/api_errors_serializer.rb
65
65
  - lib/api_pack/errors/auth.rb
66
66
  - lib/api_pack/errors/error_map.rb
@@ -71,13 +71,13 @@ files:
71
71
  - lib/api_pack/pagination_meta_generator.rb
72
72
  - lib/api_pack/serializer/adapter/fast_json_api.rb
73
73
  - lib/api_pack/serializer/parser.rb
74
- - lib/api_pack/support/api_helper.rb
74
+ - lib/api_pack/support/helper.rb
75
75
  - lib/api_pack/version.rb
76
76
  homepage: https://github.com/Jllima/api_pack
77
77
  licenses:
78
78
  - MIT
79
79
  metadata: {}
80
- post_install_message:
80
+ post_install_message:
81
81
  rdoc_options: []
82
82
  require_paths:
83
83
  - lib
@@ -92,8 +92,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  requirements: []
95
- rubygems_version: 3.0.8
96
- signing_key:
95
+ rubygems_version: 3.0.9
96
+ signing_key:
97
97
  specification_version: 4
98
98
  summary: Api requirements
99
99
  test_files: []
@@ -1,3 +0,0 @@
1
- module ApiPack
2
- HMAC_SECRET = '2e484b352b985259601a5f2f2c1712b31d63136bf22d9213303a5b501942723827508038484b9da1ead77a7788799c55e05785f2f148e53d943e6dedf635a291'.freeze
3
- end