Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions app/controllers/api/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,26 @@
class Api::ApplicationController < ApplicationController
before_action :login_required
skip_before_action :verify_authenticity_token

private

def current_user
session[:user_id] = User.find_by(email: param_email).id if session[:user_id].blank? && valid_token_request?
super
end

def valid_token_request?
return false unless param_email.present? && param_token.present?

token = OneTimeToken.valid.find_by(token: param_token)
return token.try(:user).try(:email) == param_email
end

def param_email
request.headers["x-nasulog-auth-user"] || params["auth_user"]
end

def param_token
request.headers["x-nasulog-auth-token"] || params["auth_token"]
end
end
4 changes: 4 additions & 0 deletions app/controllers/api/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ class Api::UsersController < Api::ApplicationController
def show
end

def auth_token
render nothing: true, status: 401 and return if current_user.blank?
@token = current_user.create_one_time_token
end

private

Expand Down
35 changes: 35 additions & 0 deletions app/models/one_time_token.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# == Schema Information
#
# Table name: one_time_tokens
#
# id :integer not null, primary key
# user_id :integer not null
# token :string(128)
# expires_at :datetime not null
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_one_time_tokens_on_token (token)
# index_one_time_tokens_on_user_id (user_id)
#

class OneTimeToken < ApplicationRecord
belongs_to :user
before_validation :set_token, :set_expires_at

scope :valid, -> {
where('expires_at > ?', Time.current)
}

private

def set_token
self.token ||= SecureRandom.hex(64)
end

def set_expires_at
self.expires_at ||= (Time.current + 5.minutes)
end
end
6 changes: 6 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
class User < ApplicationRecord
has_many :read_poems, dependent: :destroy
has_many :poems, dependent: :destroy
has_one :one_time_token, dependent: :destroy

def my_poem?(poem)
self == poem.user
Expand All @@ -23,6 +24,11 @@ def my_read_poem?(read_poem)
self == read_poem.user
end

def create_one_time_token
OneTimeToken.delete_all(user_id:id)
one_time_token = OneTimeToken.create(user_id: id)
end

def self.form_omniauth(auth)
User.create(
google_uid: auth[:uid],
Expand Down
5 changes: 5 additions & 0 deletions app/views/api/users/auth_token.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
json.auth_token do
json.user @token.user.email
json.token @token.token
json.expires_at @token.expires_at.to_i
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
scope module: :user do
resources 'poems', only: [:index], defaults: { format: :json }
end
get :auth_token, defaults: { format: :json }
end
end
end
12 changes: 12 additions & 0 deletions db/migrate/20160411044136_create_one_time_tokens.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreateOneTimeTokens < ActiveRecord::Migration[5.0]
def change
create_table :one_time_tokens do |t|
t.references :user, null:false
t.string :token, limit: 128
t.datetime :expires_at, null: false
t.timestamps null: false
end

add_index :one_time_tokens, :token
end
end
12 changes: 11 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,17 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20160123054054) do
ActiveRecord::Schema.define(version: 20160411044136) do

create_table "one_time_tokens", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t|
t.integer "user_id", null: false
t.string "token", limit: 128
t.datetime "expires_at", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["token"], name: "index_one_time_tokens_on_token", using: :btree
t.index ["user_id"], name: "index_one_time_tokens_on_user_id", using: :btree
end

create_table "poems", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t|
t.integer "user_id"
Expand Down
33 changes: 33 additions & 0 deletions spec/requests/api/users_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'rails_helper'

RSpec.describe "Api::Users", type: :request do
let(:current_user) { nil }

before(:each) do
allow_any_instance_of(Api::ApplicationController).to receive(:current_user).and_return current_user
allow_any_instance_of(Api::ApplicationController).to receive(:login_required).and_return true
end

describe 'GET /api/user/auth_token' do
subject { get auth_token_api_user_path }

context '非ログイン' do
it "トークンの取得はできない" do
subject
expect(response).to have_http_status(401)
end
end

context 'ログイン済み' do
let (:current_user) { create(:user) }

it "トークンが取得可能" do
subject
expect(response).to have_http_status(200)
end

#TODO 取得したトークンでログインできるか、も見たい・・・
end
end

end