summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorazul <azul@leap.se>2014-07-17 12:16:07 +0200
committerazul <azul@leap.se>2014-07-17 12:16:07 +0200
commitade74d8a9091ae607586d7b287a0579a2ee7af8e (patch)
tree74273b8ba7e35d0fb3c96aa79e63c93086d15146 /app
parent952bc18e8333ca5c3e6e16f8059f84a1414d5f6f (diff)
parente86cccb4b89540f3bd403110d051b2723be781b9 (diff)
Merge pull request #176 from azul/feature/api-authenticated-configs
API: Authenticated access to config settings
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api_controller.rb11
-rw-r--r--app/controllers/controller_extension/authentication.rb17
-rw-r--r--app/controllers/controller_extension/errors.rb34
-rw-r--r--app/controllers/controller_extension/fetch_user.rb (renamed from app/controllers/users_base_controller.rb)8
-rw-r--r--app/controllers/controller_extension/json_file.rb23
-rw-r--r--app/controllers/controller_extension/token_authentication.rb4
-rw-r--r--app/controllers/sessions_controller.rb7
-rw-r--r--app/controllers/static_config_controller.rb35
-rw-r--r--app/controllers/users_controller.rb3
-rw-r--r--app/controllers/v1/certs_controller.rb2
-rw-r--r--app/controllers/v1/configs_controller.rb34
-rw-r--r--app/controllers/v1/messages_controller.rb7
-rw-r--r--app/controllers/v1/services_controller.rb4
-rw-r--r--app/controllers/v1/sessions_controller.rb5
-rw-r--r--app/controllers/v1/smtp_certs_controller.rb2
-rw-r--r--app/controllers/v1/users_controller.rb9
16 files changed, 152 insertions, 53 deletions
diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb
new file mode 100644
index 0000000..0aa9507
--- /dev/null
+++ b/app/controllers/api_controller.rb
@@ -0,0 +1,11 @@
+class ApiController < ApplicationController
+
+ skip_before_filter :verify_authenticity_token
+ respond_to :json
+
+ def require_login
+ require_token
+ end
+
+end
+
diff --git a/app/controllers/controller_extension/authentication.rb b/app/controllers/controller_extension/authentication.rb
index 1f73f38..e2b24f0 100644
--- a/app/controllers/controller_extension/authentication.rb
+++ b/app/controllers/controller_extension/authentication.rb
@@ -16,7 +16,7 @@ module ControllerExtension::Authentication
end
def require_login
- access_denied unless logged_in?
+ login_required unless logged_in?
end
# some actions only make sense if you are not logged in yet.
@@ -26,21 +26,6 @@ module ControllerExtension::Authentication
redirect_to home_url if logged_in?
end
- def access_denied
- respond_to do |format|
- format.html do
- if logged_in?
- redirect_to home_url, :alert => t(:not_authorized)
- else
- redirect_to login_url, :alert => t(:not_authorized_login)
- end
- end
- format.json do
- render :json => {'error' => t(:not_authorized)}, status: :unprocessable_entity
- end
- end
- end
-
def admin?
current_user.is_admin?
end
diff --git a/app/controllers/controller_extension/errors.rb b/app/controllers/controller_extension/errors.rb
new file mode 100644
index 0000000..8f8edde
--- /dev/null
+++ b/app/controllers/controller_extension/errors.rb
@@ -0,0 +1,34 @@
+module ControllerExtension::Errors
+ extend ActiveSupport::Concern
+
+ protected
+
+ def access_denied
+ respond_to_error :not_authorized, :forbidden, home_url
+ end
+
+ def login_required
+ # Warden will intercept the 401 response and call
+ # SessionController#unauthenticated instead.
+ respond_to_error :not_authorized_login, :unauthorized, login_url
+ end
+
+ def not_found
+ respond_to_error :not_found, :not_found, home_url
+ end
+
+
+ def respond_to_error(message, status=nil, redirect=nil)
+ error = message
+ message = t(message) if message.is_a?(Symbol)
+ respond_to do |format|
+ format.html do
+ redirect_to redirect, alert: message
+ end
+ format.json do
+ status ||= :unprocessable_entity
+ render json: {error: error, message: message}, status: status
+ end
+ end
+ end
+end
diff --git a/app/controllers/users_base_controller.rb b/app/controllers/controller_extension/fetch_user.rb
index 9becf0d..695d723 100644
--- a/app/controllers/users_base_controller.rb
+++ b/app/controllers/controller_extension/fetch_user.rb
@@ -1,8 +1,10 @@
#
-# common base class for all user related controllers
+# fetch the user taking into account permissions.
+# While normal users can only change settings for themselves
+# admins can change things for all users.
#
-
-class UsersBaseController < ApplicationController
+module ControllerExtension::FetchUser
+ extend ActiveSupport::Concern
protected
diff --git a/app/controllers/controller_extension/json_file.rb b/app/controllers/controller_extension/json_file.rb
new file mode 100644
index 0000000..6be919a
--- /dev/null
+++ b/app/controllers/controller_extension/json_file.rb
@@ -0,0 +1,23 @@
+module ControllerExtension::JsonFile
+ extend ActiveSupport::Concern
+ include ControllerExtension::Errors
+
+ protected
+
+ def send_file
+ if stale?(:last_modified => @file.mtime)
+ response.content_type = 'application/json'
+ render :text => @file.read
+ end
+ end
+
+ def fetch_file
+ if File.exists?(@filename)
+ @file = File.new(@filename)
+ else
+ not_found
+ end
+ end
+
+end
+
diff --git a/app/controllers/controller_extension/token_authentication.rb b/app/controllers/controller_extension/token_authentication.rb
index b0ed624..4ad1977 100644
--- a/app/controllers/controller_extension/token_authentication.rb
+++ b/app/controllers/controller_extension/token_authentication.rb
@@ -1,6 +1,8 @@
module ControllerExtension::TokenAuthentication
extend ActiveSupport::Concern
+ protected
+
def token
@token ||= authenticate_with_http_token do |token, options|
Token.find_by_token(token)
@@ -12,7 +14,7 @@ module ControllerExtension::TokenAuthentication
end
def require_token
- access_denied unless token_authenticate
+ login_required unless token_authenticate
end
def logout
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 8919a4d..66eba40 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -16,6 +16,13 @@ class SessionsController < ApplicationController
end
#
+ # Warden will catch all 401s and run this instead:
+ #
+ def unauthenticated
+ login_required
+ end
+
+ #
# this is a bad hack, but user_url(user) is not available
# also, this doesn't work because the redirect happens as a PUT. no idea why.
#
diff --git a/app/controllers/static_config_controller.rb b/app/controllers/static_config_controller.rb
index c669316..c78e006 100644
--- a/app/controllers/static_config_controller.rb
+++ b/app/controllers/static_config_controller.rb
@@ -2,23 +2,28 @@
# This controller is responsible for returning some static config files, such as /provider.json
#
class StaticConfigController < ActionController::Base
+ include ControllerExtension::JsonFile
- PROVIDER_JSON = File.join(Rails.root, 'config', 'provider', 'provider.json')
+ before_filter :set_minimum_client_version
+ before_filter :set_filename
+ before_filter :fetch_file
+
+ PROVIDER_JSON = Rails.root.join('config', 'provider', 'provider.json')
- #
- # return the provider.json, ensuring that the header X-Minimum-Client-Version is sent
- # regardless if a 200 or 304 (not modified) response is sent.
- #
def provider
- response.headers["X-Minimum-Client-Version"] = APP_CONFIG[:minimum_client_version].to_s
- if File.exists?(PROVIDER_JSON)
- if stale?(:last_modified => File.mtime(PROVIDER_JSON))
- response.content_type = 'application/json'
- render :text => File.read(PROVIDER_JSON)
- end
- else
- render :text => 'not found', :status => 404
- end
+ send_file
end
-end \ No newline at end of file
+ protected
+
+ # ensure that the header X-Minimum-Client-Version is sent
+ # regardless if a 200 or 304 (not modified) or 404 response is sent.
+ def set_minimum_client_version
+ response.headers["X-Minimum-Client-Version"] =
+ APP_CONFIG[:minimum_client_version].to_s
+ end
+
+ def set_filename
+ @filename = PROVIDER_JSON
+ end
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 0f822cb..dcf7607 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -2,7 +2,8 @@
# This is an HTML-only controller. For the JSON-only controller, see v1/users_controller.rb
#
-class UsersController < UsersBaseController
+class UsersController < ApplicationController
+ include ControllerExtension::FetchUser
before_filter :require_login, :except => [:new]
before_filter :redirect_if_logged_in, :only => [:new]
diff --git a/app/controllers/v1/certs_controller.rb b/app/controllers/v1/certs_controller.rb
index b6d1d0b..68d6586 100644
--- a/app/controllers/v1/certs_controller.rb
+++ b/app/controllers/v1/certs_controller.rb
@@ -1,4 +1,4 @@
-class V1::CertsController < ApplicationController
+class V1::CertsController < ApiController
before_filter :require_login, :unless => :anonymous_certs_allowed?
diff --git a/app/controllers/v1/configs_controller.rb b/app/controllers/v1/configs_controller.rb
new file mode 100644
index 0000000..accdf5a
--- /dev/null
+++ b/app/controllers/v1/configs_controller.rb
@@ -0,0 +1,34 @@
+class V1::ConfigsController < ApiController
+ include ControllerExtension::JsonFile
+
+ before_filter :require_login
+ before_filter :sanitize_filename, only: :show
+ before_filter :fetch_file, only: :show
+
+ def index
+ render json: {services: service_paths}
+ end
+
+ def show
+ send_file
+ end
+
+ SERVICES = {
+ soledad: "soledad-service.json",
+ eip: "eip-service.json",
+ smtp: "smtp-service.json"
+ }
+
+ protected
+
+ def service_paths
+ Hash[SERVICES.map{|k,v| [k,"/1/configs/#{v}"] } ]
+ end
+
+ def sanitize_filename
+ @filename = params[:id].downcase
+ @filename += '.json' unless @filename.ends_with?('.json')
+ access_denied unless SERVICES.values.include? name
+ @filename = Rails.root.join('public', '1', 'config', @filename)
+ end
+end
diff --git a/app/controllers/v1/messages_controller.rb b/app/controllers/v1/messages_controller.rb
index 85156b7..a9b93a9 100644
--- a/app/controllers/v1/messages_controller.rb
+++ b/app/controllers/v1/messages_controller.rb
@@ -1,10 +1,7 @@
module V1
- class MessagesController < ApplicationController
+ class MessagesController < ApiController
- skip_before_filter :verify_authenticity_token
- before_filter :require_token
-
- respond_to :json
+ before_filter :require_login
def index
render json: current_user.messages
diff --git a/app/controllers/v1/services_controller.rb b/app/controllers/v1/services_controller.rb
index 594940e..114870f 100644
--- a/app/controllers/v1/services_controller.rb
+++ b/app/controllers/v1/services_controller.rb
@@ -1,6 +1,4 @@
-class V1::ServicesController < ApplicationController
-
- respond_to :json
+class V1::ServicesController < ApiController
def show
respond_with current_user.effective_service_level
diff --git a/app/controllers/v1/sessions_controller.rb b/app/controllers/v1/sessions_controller.rb
index d88fcdc..a343d9b 100644
--- a/app/controllers/v1/sessions_controller.rb
+++ b/app/controllers/v1/sessions_controller.rb
@@ -1,8 +1,7 @@
module V1
- class SessionsController < ApplicationController
+ class SessionsController < ApiController
- skip_before_filter :verify_authenticity_token
- before_filter :require_token, only: :destroy
+ before_filter :require_login, only: :destroy
def new
@session = Session.new
diff --git a/app/controllers/v1/smtp_certs_controller.rb b/app/controllers/v1/smtp_certs_controller.rb
index 377a49c..fa53b26 100644
--- a/app/controllers/v1/smtp_certs_controller.rb
+++ b/app/controllers/v1/smtp_certs_controller.rb
@@ -1,4 +1,4 @@
-class V1::SmtpCertsController < ApplicationController
+class V1::SmtpCertsController < ApiController
before_filter :require_login
before_filter :require_email_account
diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb
index abaefd8..bfa04fc 100644
--- a/app/controllers/v1/users_controller.rb
+++ b/app/controllers/v1/users_controller.rb
@@ -1,10 +1,10 @@
module V1
- class UsersController < UsersBaseController
+ class UsersController < ApiController
+ include ControllerExtension::FetchUser
- skip_before_filter :verify_authenticity_token
before_filter :fetch_user, :only => [:update]
before_filter :require_admin, :only => [:index]
- before_filter :require_token, :only => [:update]
+ before_filter :require_login, :only => [:index, :update]
before_filter :require_registration_allowed, only: :create
respond_to :json
@@ -29,11 +29,12 @@ module V1
respond_with @user
end
+ protected
+
def require_registration_allowed
unless APP_CONFIG[:allow_registration]
head :forbidden
end
end
-
end
end