Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #35 from malparty/feature/user-login-api
[#17] [API] As a User, I can sign up and sign in/out with a username and password
- Loading branch information
Showing
38 changed files
with
500 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# frozen_string_literal: true | ||
|
||
module API | ||
module V1 | ||
class ApplicationController < ActionController::API | ||
# equivalent of authenticate_user! on devise, but this one will check the oauth token | ||
before_action :doorkeeper_authorize! | ||
|
||
private | ||
|
||
# helper method to access the current user from the token | ||
def current_user | ||
@current_user ||= User.find_by(id: doorkeeper_token[:resource_owner_id]) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# frozen_string_literal: true | ||
|
||
module API | ||
module V1 | ||
class TokensController < Doorkeeper::TokensController | ||
include ErrorHandlerConcern | ||
|
||
# Overridden from doorkeeper as the doorkeeper revoke action does not return response according to json-api spec | ||
def revoke | ||
# The authorization server responds with HTTP status code 200 if the client | ||
# submitted an invalid token or the token has been revoked successfully. | ||
if token.blank? | ||
render json: token_revoke_response, status: :ok | ||
# The authorization server validates [...] and whether the token | ||
# was issued to the client making the revocation request. If this | ||
# validation fails, the request is refused and the client is informed | ||
# of the error by the authorization server as described below. | ||
elsif authorized? | ||
revoke_token | ||
render json: token_revoke_response, status: :ok | ||
else | ||
render json: revocation_error_response, status: :forbidden | ||
end | ||
end | ||
|
||
private | ||
|
||
# Overridden from doorkeeper as it does not return response according to json-api spec | ||
def revocation_error_response | ||
error_description = I18n.t(:unauthorized, scope: %i[doorkeeper errors messages revoke]) | ||
{ | ||
errors: build_error(detail: error_description, code: :invalid_client) | ||
} | ||
end | ||
|
||
def token_revoke_response | ||
{ meta: I18n.t('doorkeeper.token_revoked') } | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# frozen_string_literal: true | ||
|
||
module API | ||
module V1 | ||
class UsersController < ApplicationController | ||
include API::V1::ErrorHandlerConcern | ||
|
||
skip_before_action :doorkeeper_authorize!, only: :create | ||
|
||
before_action :ensure_valid_client, only: :create | ||
|
||
def create | ||
user = User.new(create_params.except(:client_id, :client_secret)) | ||
|
||
if user.save | ||
render json: UserTokenSerializer.new(user, { params: { client_id: @client_app.id } }), | ||
status: :created | ||
else | ||
render json: ActiveModel::ErrorsSerializer.new(user.errors) | ||
end | ||
end | ||
|
||
private | ||
|
||
def create_params | ||
params.permit(:email, :password, :last_name, :first_name, :client_id, :client_secret) | ||
end | ||
|
||
def ensure_valid_client | ||
@client_app = Doorkeeper::Application.by_uid_and_secret(create_params[:client_id], | ||
create_params[:client_secret]) | ||
|
||
render_error 'Invalid client credentials', status: :forbidden, source: :client_id if @client_app.blank? | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# frozen_string_literal: true | ||
|
||
module API | ||
module V1 | ||
module ErrorHandlerConcern | ||
extend ActiveSupport::Concern | ||
|
||
private | ||
|
||
# Render Error Message in json_api format | ||
def render_error(detail, source: nil, status: :unprocessable_entity) | ||
error = build_error(detail: detail, source: source) | ||
render_errors [error], status | ||
end | ||
|
||
def render_errors(jsonapi_errors, status = :unprocessable_entity) | ||
render json: { errors: jsonapi_errors }, status: status | ||
end | ||
|
||
def build_error(detail:, source: nil, code: nil) | ||
{ | ||
source: source, | ||
detail: detail, | ||
code: code | ||
}.compact | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# frozen_string_literal: true | ||
|
||
module DeviseParameter | ||
protected | ||
|
||
def update_allowed_parameters | ||
devise_parameter_sanitizer.permit(:sign_up) do |u| | ||
u.permit(:first_name, :last_name, :email, :password, :password_confirmation) | ||
end | ||
devise_parameter_sanitizer.permit(:account_update) do |u| | ||
u.permit(:first_name, :last_name, :email, :password, :current_password) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# frozen_string_literal: true | ||
|
||
module ActiveModel | ||
class ErrorsSerializer | ||
def initialize(errors) | ||
@errors = errors | ||
end | ||
|
||
def as_json(_options = nil) | ||
{ errors: @errors.errors.map { |e| { detail: e.full_message, source: e.attribute } } } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# frozen_string_literal: true | ||
|
||
module Doorkeeper | ||
class TokenSerializer | ||
include JSONAPI::Serializer | ||
|
||
attributes :token, :token_type, :expires_in, :refresh_token | ||
|
||
attribute :created_at do |token| | ||
token.created_at.to_i | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
class UserSerializer | ||
include JSONAPI::Serializer | ||
|
||
attributes :email, :last_name, :first_name | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# frozen_string_literal: true | ||
|
||
class UserTokenSerializer < UserSerializer | ||
set_type :user | ||
|
||
attribute :access_token do |user, params| | ||
Doorkeeper::TokenSerializer.new(user.create_access_token(params[:client_id])).serializable_hash[:data] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.