diff options
-rw-r--r-- | app/api/api.rb | 16 | ||||
-rw-r--r-- | app/api/api_tweets.rb | 8 | ||||
-rw-r--r-- | app/api/api_users.rb | 2 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 27 | ||||
-rw-r--r-- | app/models/account.rb | 13 | ||||
-rw-r--r-- | app/models/user.rb | 4 | ||||
-rw-r--r-- | app/views/internal/tweets/_tweet.json.jbuilder | 2 | ||||
-rw-r--r-- | app/views/internal/tweets/responses.json.jbuilder | 2 |
8 files changed, 45 insertions, 29 deletions
diff --git a/app/api/api.rb b/app/api/api.rb index 6e15151..836ef99 100644 --- a/app/api/api.rb +++ b/app/api/api.rb @@ -39,10 +39,18 @@ class Api < Grape::API end end - def permitted_to_see?(user_or_tweet) - user_or_tweet.is_a?(User) ? - !user_or_tweet.protected? || current_user.try(:permitted_to_see?, user_or_tweet) : - !user_or_tweet.user.protected? || current_user.try(:permitted_to_see?, user_or_tweet.user) + def authorized?(object) + case object + when User + !object.protected? || + logged_in? && + (object.id == current_user.id || + current_user.account.following?(object)) + when Tweet + authorized?(object.user) + else + raise ArgumentError, "object must be User or Tweet" + end end end diff --git a/app/api/api_tweets.rb b/app/api/api_tweets.rb index 8e5d5ca..87b054a 100644 --- a/app/api/api_tweets.rb +++ b/app/api/api_tweets.rb @@ -45,14 +45,14 @@ class ApiTweets < Grape::API def user @_user ||= begin user = User.find(id: params[:user_id], screen_name: params[:screen_name]) - raise Aclog::Exceptions::UserProtected unless permitted_to_see?(user) + raise Aclog::Exceptions::UserProtected unless authorized?(user) user end end def source_user user = User.find(id: params[:source_user_id], screen_name: params[:source_screen_name]) - raise Aclog::Exceptions::UserProtected unless permitted_to_see?(user) + raise Aclog::Exceptions::UserProtected unless authorized?(user) user end @@ -72,7 +72,7 @@ class ApiTweets < Grape::API end get "show", rabl: "tweet" do @tweet = Tweet.find(params[:id]) - raise Aclog::Exceptions::UserProtected unless permitted_to_see?(@tweet) + raise Aclog::Exceptions::UserProtected unless authorized?(@tweet) end desc "Returns Tweets, specified by comma-separated IDs.", example_params: { ids: "43341783446466560,340640143058825216" } @@ -81,7 +81,7 @@ class ApiTweets < Grape::API end get "lookup", rabl: "tweets" do @tweets = Tweet.where(id: params[:ids].split(",").map(&:to_i)) - @tweets = @tweets.select {|tweet| permitted_to_see?(tweet) } + @tweets = @tweets.select {|tweet| authorized?(tweet) } end desc "Returns the best Tweets of a user, specified by username or user ID.", example_params: { user_id: 15926668, count: 2, page: 3, recent: "1m" } diff --git a/app/api/api_users.rb b/app/api/api_users.rb index 0ca7705..4e65f5e 100644 --- a/app/api/api_users.rb +++ b/app/api/api_users.rb @@ -11,7 +11,7 @@ class ApiUsers < Grape::API def user @_user ||= begin user = User.find(id: params[:id] || params[:user_id], screen_name: params[:screen_name]) - raise Aclog::Exceptions::UserProtected unless permitted_to_see?(user) + raise Aclog::Exceptions::UserProtected unless authorized?(user) user end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fe1f1a9..9cc2785 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception helper_method :logged_in?, :current_user - helper_method :authorized_to_show_user? + helper_method :authorized? def routing_error raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}" @@ -24,24 +24,23 @@ class ApplicationController < ActionController::Base end end - def authorized_to_show_user?(user) - !user.protected? || - (logged_in? && current_user.permitted_to_see?(user)) - end - - def authorize!(object) + def authorized?(object) case object when User - unless authorized_to_show_user?(object) - raise(Aclog::Exceptions::UserProtected, object) - end + !object.protected? || + logged_in? && + (object.id == current_user.id || + current_user.account.following?(object)) when Tweet - authorize! object.user - when NilClass - raise Aclog::Exceptions::NotFound + authorized?(object.user) else - raise ArgumentError, "parameter `object` must be a User or a Tweet" + raise ArgumentError, "object must be User or Tweet" end + end + + def authorize!(object) + authorized?(object) || + raise(Aclog::Exceptions::UserProtected, object) object end diff --git a/app/models/account.rb b/app/models/account.rb index 7e96852..8d6ea47 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -32,6 +32,19 @@ class Account < ActiveRecord::Base revoked! end + def authorized?(object) + case object + when User + !object.protected? || + object.id == self.user_id || + following?(object) + when Tweet + authorized?(object.user) + else + raise ArgumentError, "object must be User or Tweet" + end + end + # Returns whether following the target user or not. # @param [User, Integer] target_id Target user. # @return [Boolean] whether following the target or not. diff --git a/app/models/user.rb b/app/models/user.rb index 6a51bb6..587745e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -71,10 +71,6 @@ class User < ActiveRecord::Base !!account && account.active? end - def permitted_to_see?(user) - !user.protected? || user.id == self.id || (self.registered? && account.following?(user)) - end - def stats Rails.cache.fetch("users/#{self.id}/stats", expires_in: Settings.cache.stats) do plucked = self.tweets.select("COUNT(*) AS count, SUM(reactions_count) AS sum").first.attributes diff --git a/app/views/internal/tweets/_tweet.json.jbuilder b/app/views/internal/tweets/_tweet.json.jbuilder index 21f4d96..ac63359 100644 --- a/app/views/internal/tweets/_tweet.json.jbuilder +++ b/app/views/internal/tweets/_tweet.json.jbuilder @@ -1,4 +1,4 @@ -if authorized_to_show_user?(tweet.user) +if authorized?(tweet.user) json.id_str tweet.id.to_s json.user do diff --git a/app/views/internal/tweets/responses.json.jbuilder b/app/views/internal/tweets/responses.json.jbuilder index 62de683..de4fe12 100644 --- a/app/views/internal/tweets/responses.json.jbuilder +++ b/app/views/internal/tweets/responses.json.jbuilder @@ -1,6 +1,6 @@ apply = ->(property, users) do json.__send__(property, @tweet.__send__(users)) do |u| - if authorized_to_show_user?(u) + if authorized?(u) json.name u.name json.screen_name u.screen_name json.profile_image_url u.profile_image_url |