131 lines
4.0 KiB
Ruby
131 lines
4.0 KiB
Ruby
class Rs::OauthController < ApplicationController
|
|
before_action :require_user_signed_in
|
|
|
|
def new
|
|
username, org = params[:useraddress].split("@")
|
|
@user = User.where(cn: username.downcase, ou: org).first
|
|
@scopes = parse_scopes params[:scope]
|
|
@redirect_uri = params[:redirect_uri]
|
|
@client_id = params[:client_id]
|
|
@state = params[:state]
|
|
@root_access_requested = (@scopes & [":r",":rw"]).any?
|
|
|
|
@denial_url = url_with_state("#{@redirect_uri}#error=access_denied", @state)
|
|
|
|
@expire_at_dates = [["Never", nil],
|
|
["In 1 month", 1.month.from_now],
|
|
["In 1 day", 1.day.from_now]]
|
|
|
|
http_status :bad_request and return unless @redirect_uri.present?
|
|
|
|
unless current_user == @user
|
|
sign_out :user
|
|
|
|
redirect_to new_rs_oauth_url(@user.address,
|
|
scope: params[:scope],
|
|
redirect_uri: params[:redirect_uri],
|
|
client_id: params[:client_id],
|
|
state: params[:state])
|
|
return
|
|
end
|
|
|
|
unless @client_id.present?
|
|
redirect_to url_with_state("#{@redirect_uri}#error=invalid_request", @state) and return
|
|
end
|
|
|
|
if @scopes.empty?
|
|
redirect_to url_with_state("#{@redirect_uri}#error=invalid_scope", @state) and return
|
|
end
|
|
|
|
unless hostname_of(@client_id) == hostname_of(@redirect_uri)
|
|
redirect_to url_with_state("#{@redirect_uri}#error=invalid_client", @state) and return
|
|
end
|
|
|
|
@client_id.gsub!(/http(s)?:\/\//, "")
|
|
|
|
# TODO
|
|
# if auth = current_user.remote_storage_authorizations.valid.where(permissions: @scopes, client_id: @client_id).first
|
|
# redirect_to url_with_state("#{@redirect_uri}#access_token=#{auth.token}", @state), allow_other_host: true
|
|
# end
|
|
end
|
|
|
|
def create
|
|
unless current_user.id.to_s == params[:user_id]
|
|
Rails.logger.info("NO MATCH: #{params[:user_id]}, #{current_user.id}")
|
|
http_status :forbidden and return
|
|
end
|
|
|
|
permissions = parse_scopes params[:scope]
|
|
redirect_uri = params[:redirect_uri].presence
|
|
client_id = params[:client_id].presence
|
|
state = params[:state].presence
|
|
expire_at = params[:expire_at].presence
|
|
|
|
http_status :bad_request and return unless redirect_uri.present?
|
|
|
|
if permissions.empty?
|
|
redirect_to url_with_state("#{redirect_uri}#error=invalid_scope", state), allow_other_host: true and return
|
|
end
|
|
|
|
unless client_id.present?
|
|
redirect_to url_with_state("#{redirect_uri}#error=invalid_request", state), allow_other_host: true and return
|
|
end
|
|
|
|
unless hostname_of(client_id) == hostname_of(redirect_uri)
|
|
redirect_to url_with_state("#{redirect_uri}#error=invalid_client", state), allow_other_host: true and return
|
|
end
|
|
|
|
client_id.gsub!(/http(s)?:\/\//, "")
|
|
|
|
auth = current_user.remote_storage_authorizations.create!(
|
|
permissions: permissions,
|
|
client_id: client_id,
|
|
redirect_uri: redirect_uri,
|
|
app_name: client_id, #TODO use user-defined name
|
|
expire_at: expire_at
|
|
)
|
|
|
|
redirect_to url_with_state("#{redirect_uri}#access_token=#{auth.token}", state), allow_other_host: true
|
|
end
|
|
|
|
# GET /rs/oauth/token/:id/launch_app
|
|
def launch_app
|
|
auth = current_user.remote_storage_authorizations.find(params[:id])
|
|
|
|
redirect_to app_auth_url(auth)
|
|
end
|
|
|
|
private
|
|
|
|
def app_auth_url(auth)
|
|
url = "#{auth.url}#remotestorage=#{current_user.address}"
|
|
url += "&access_token=#{auth.token}"
|
|
url
|
|
end
|
|
|
|
def hostname_of(uri)
|
|
uri.gsub(/http(s)?:\/\//, "").split(":")[0].split("/")[0]
|
|
end
|
|
|
|
def parse_scopes(scope_string)
|
|
return [] if scope_string.blank?
|
|
|
|
scopes = scope_string.
|
|
gsub(/\[|\]/, "").
|
|
gsub(/\,/, " ").
|
|
gsub(/\/:/, ":").
|
|
split(/\s/).map(&:strip).
|
|
reject(&:empty?)
|
|
|
|
scopes = [":r"] if scopes.include?("*:r")
|
|
scopes = [":rw"] if scopes.include?("*:rw")
|
|
|
|
scopes
|
|
end
|
|
|
|
def url_with_state(url, state)
|
|
state ? "#{url}&state=#{CGI.escape(state)}" : url
|
|
end
|
|
|
|
end
|