diff --git a/app/controllers/answers_controller.rb b/app/controllers/answers_controller.rb index c72174d..83f4e62 100644 --- a/app/controllers/answers_controller.rb +++ b/app/controllers/answers_controller.rb @@ -1,6 +1,7 @@ class AnswersController < ApplicationController before_action :set_question before_action :set_answer, only: [:show, :update, :destroy] + include OwnershipConcern def index @answers = @question.answers.all @@ -14,11 +15,12 @@ def show def create @answer = @question.answers.new(answer_params) + @answer.user = current_user if @answer.save render json: @answer, status: :created, location: question_answer_path(@question, @answer) else - render json: @answer.errors, status: :unprocessable_entity + invalid_request(error_msg) end end @@ -26,13 +28,16 @@ def update if @answer.update(answer_params) head :no_content else - render json: @answer.errors, status: :unprocessable_entity + invalid_request(error_msg) end end def destroy - @answer.destroy - head :no_content + if @answer.try(:destroy) + head :no_content + else + invalid_request(error_msg) + end end private diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c597c78..a2ea850 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -34,6 +34,11 @@ def unauthorized_token render json: {errors: "Request was made with invalid token"}, status: 401 end + def error_msg + "The operation could not be performed."\ + " Please check your request or try again later" + end + def set_attrs_in_session(hash={}) hash.each do |key, val| diff --git a/app/controllers/concerns/ownership_concern.rb b/app/controllers/concerns/ownership_concern.rb new file mode 100644 index 0000000..537e116 --- /dev/null +++ b/app/controllers/concerns/ownership_concern.rb @@ -0,0 +1,27 @@ + +require 'forwardable' +module OwnershipConcern + extend ActiveSupport::Concern + + included do + extend Forwardable + def_delegator self, :resource_name + def self.resource_name + controller_name.singularize + end + + before_action "check_user_owns_#{resource_name}", only: [:update, :destroy] + + define_method "check_user_owns_#{resource_name}" do + resource = instance_variable_get("@#{resource_name}") + if resource + unauthorized_access && return unless resource.user == current_user + end + end + end + + def unauthorized_access + render json: {errors: "Unauthorized/Forbidden Access: #{resource_name.capitalize} does not belong to user"}, status: :forbidden + end + +end diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb index 2a7519c..e5f1d02 100644 --- a/app/controllers/questions_controller.rb +++ b/app/controllers/questions_controller.rb @@ -1,6 +1,7 @@ class QuestionsController < ApplicationController before_action :set_question, only: [:show, :update, :destroy] before_action :authenticate_user + def index questions = Question.all render json: questions, status: 200 @@ -48,11 +49,6 @@ def set_question resource_not_found && return unless @question end - def error_msg - "The operation could not be performed."\ - " Please check your request or try again later" - end - def questions_params params.permit(:id, :title, :content, :votes) end diff --git a/app/controllers/tokens_controller.rb b/app/controllers/tokens_controller.rb index 631310a..67f8d3b 100644 --- a/app/controllers/tokens_controller.rb +++ b/app/controllers/tokens_controller.rb @@ -9,7 +9,7 @@ def validate private def set_token - @token = Token.active.find_by(temp: params[:temp_token]).destroy + @token = Token.active.find_by(temp: params[:temp_token]).try(:destroy) resource_not_found unless @token end end diff --git a/app/models/concerns/andela_validator.rb b/app/models/concerns/andela_validator.rb new file mode 100644 index 0000000..957823c --- /dev/null +++ b/app/models/concerns/andela_validator.rb @@ -0,0 +1,9 @@ +module AndelaValidator + extend ActiveSupport::Concern + + ANDELA_EMAIL_REGEX = /[\w.]+@andela.co[m]?\z/ + included do + validates :email, presence: true, format: {with: ANDELA_EMAIL_REGEX, message: "Sign in with an Andela email address"} + end + +end diff --git a/app/models/social_provider.rb b/app/models/social_provider.rb index a074195..bb9c98a 100644 --- a/app/models/social_provider.rb +++ b/app/models/social_provider.rb @@ -1,4 +1,5 @@ class SocialProvider < ActiveRecord::Base + include AndelaValidator belongs_to :user validates :uuid, presence: true validates :provider, presence: true diff --git a/app/models/user.rb b/app/models/user.rb index fb5060b..4f6aa2c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,13 +1,18 @@ class User < ActiveRecord::Base + include AndelaValidator has_many :comments, as: :comment_on has_many :tags, as: :subscriber has_many :questions has_many :answers has_many :social_providers has_many :tokens + EMAIL_FORMAT= /(?[.\w]+@andela).co[m]?\z/ def self.from_omniauth(auth, user=nil) - user = where(email: auth.info.email).first_or_create do |u| + email_address = auth.info.email + grabbed = EMAIL_FORMAT.match(email_address).try(:[], :email) + grabbed = grabbed ? "#{grabbed}%" : email_address + user = where("email LIKE :email", email: grabbed).first_or_create do |u| u.name= auth.info.name u.email= auth.info.email end diff --git a/db/schema.rb b/db/schema.rb index 0f6aaf0..022b094 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -51,7 +51,7 @@ t.string "token" t.string "profile_picture" t.string "profile_url" - t.string "profile_email" + t.string "email" end add_index "social_providers", ["user_id"], name: "index_social_providers_on_user_id"