summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
authorazul <azul@riseup.net>2014-04-17 10:12:05 +0200
committerazul <azul@riseup.net>2014-04-17 10:12:05 +0200
commit3513ad74f950b113af1ba1e3d06bc6a55c48fde5 (patch)
treedb49ebd4428053d5c8d720275b77594a531a1ad1 /app/controllers
parentcb6442c344d6bdaf52c3878b2de2fcf4d85f2648 (diff)
parent3d3688647fab7049e5b531c45b85c1e46a1d528f (diff)
Merge pull request #146 from azul/refactor/engines
Refactor/engines
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/.gitkeep0
-rw-r--r--app/controllers/account_settings_controller.rb0
-rw-r--r--app/controllers/controller_extension/authentication.rb75
-rw-r--r--app/controllers/controller_extension/token_authentication.rb27
-rw-r--r--app/controllers/keys_controller.rb18
-rw-r--r--app/controllers/sessions_controller.rb28
-rw-r--r--app/controllers/users_base_controller.rb18
-rw-r--r--app/controllers/users_controller.rb69
-rw-r--r--app/controllers/v1/certs_controller.rb50
-rw-r--r--app/controllers/v1/messages_controller.rb25
-rw-r--r--app/controllers/v1/sessions_controller.rb45
-rw-r--r--app/controllers/v1/users_controller.rb32
-rw-r--r--app/controllers/webfinger_controller.rb19
13 files changed, 406 insertions, 0 deletions
diff --git a/app/controllers/.gitkeep b/app/controllers/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/controllers/.gitkeep
diff --git a/app/controllers/account_settings_controller.rb b/app/controllers/account_settings_controller.rb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/controllers/account_settings_controller.rb
diff --git a/app/controllers/controller_extension/authentication.rb b/app/controllers/controller_extension/authentication.rb
new file mode 100644
index 0000000..03d3989
--- /dev/null
+++ b/app/controllers/controller_extension/authentication.rb
@@ -0,0 +1,75 @@
+module ControllerExtension::Authentication
+ extend ActiveSupport::Concern
+
+ private
+
+ included do
+ helper_method :current_user, :logged_in?, :admin?
+ end
+
+ def current_user
+ @current_user ||= token_authenticate || warden.user
+ end
+
+ def logged_in?
+ !!current_user
+ end
+
+ def require_login
+ access_denied unless logged_in?
+ end
+
+ # some actions only make sense if you are not logged in yet.
+ # (login, signup). If a user tries to perform these they will
+ # be redirected to their dashboard.
+ def redirect_if_logged_in
+ 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 && current_user.is_admin?
+ end
+
+ def require_admin
+ access_denied unless admin?
+ end
+
+ def authentication_errors
+ return unless attempted_login?
+ errors = get_warden_errors
+ errors.inject({}) do |translated,err|
+ translated[err.first] = I18n.t(err.last)
+ translated
+ end
+ end
+
+ def get_warden_errors
+ if strategy = warden.winning_strategy
+ message = strategy.message
+ # in case we get back the default message to fail!
+ message.respond_to?(:inject) ? message : { base: message }
+ else
+ { login: :all_strategies_failed }
+ end
+ end
+
+ def attempted_login?
+ request.env['warden.options'] &&
+ request.env['warden.options'][:attempted_path]
+ end
+end
diff --git a/app/controllers/controller_extension/token_authentication.rb b/app/controllers/controller_extension/token_authentication.rb
new file mode 100644
index 0000000..6e0a6ce
--- /dev/null
+++ b/app/controllers/controller_extension/token_authentication.rb
@@ -0,0 +1,27 @@
+module ControllerExtension::TokenAuthentication
+ extend ActiveSupport::Concern
+
+ def token
+ @token ||= authenticate_with_http_token do |token_id, options|
+ Token.find(token_id)
+ end
+ end
+
+ def token_authenticate
+ @token_authenticated ||= token.authenticate if token
+ end
+
+ def require_token
+ access_denied unless token_authenticate
+ end
+
+ def logout
+ super
+ clear_token
+ end
+
+ def clear_token
+ token.destroy if token
+ end
+end
+
diff --git a/app/controllers/keys_controller.rb b/app/controllers/keys_controller.rb
new file mode 100644
index 0000000..fb28901
--- /dev/null
+++ b/app/controllers/keys_controller.rb
@@ -0,0 +1,18 @@
+class KeysController < ApplicationController
+
+ #
+ # Render the user's key as plain text, without a layout.
+ #
+ # We will show blank page if user doesn't have key (which shouldn't generally occur)
+ # and a 404 error if user doesn't exist
+ #
+ def show
+ user = User.find_by_login(params[:login])
+ if user
+ render text: user.public_key, content_type: 'text/text'
+ else
+ raise ActionController::RoutingError.new('Not Found')
+ end
+ end
+
+end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
new file mode 100644
index 0000000..8919a4d
--- /dev/null
+++ b/app/controllers/sessions_controller.rb
@@ -0,0 +1,28 @@
+class SessionsController < ApplicationController
+
+ before_filter :redirect_if_logged_in, :only => [:new]
+
+ def new
+ @session = Session.new
+ if authentication_errors
+ @errors = authentication_errors
+ render :status => 422
+ end
+ end
+
+ def destroy
+ logout
+ redirect_to home_url
+ 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.
+ #
+ #Warden::Manager.after_authentication do |user, auth, opts|
+ # response = Rack::Response.new
+ # response.redirect "/users/#{user.id}"
+ # throw :warden, response.finish
+ #end
+
+end
diff --git a/app/controllers/users_base_controller.rb b/app/controllers/users_base_controller.rb
new file mode 100644
index 0000000..9becf0d
--- /dev/null
+++ b/app/controllers/users_base_controller.rb
@@ -0,0 +1,18 @@
+#
+# common base class for all user related controllers
+#
+
+class UsersBaseController < ApplicationController
+
+ protected
+
+ def fetch_user
+ @user = User.find(params[:user_id] || params[:id])
+ if !@user && admin?
+ redirect_to users_url, :alert => t(:no_such_thing, :thing => 'user')
+ elsif !admin? && @user != current_user
+ access_denied
+ end
+ end
+
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
new file mode 100644
index 0000000..c8e09b6
--- /dev/null
+++ b/app/controllers/users_controller.rb
@@ -0,0 +1,69 @@
+#
+# This is an HTML-only controller. For the JSON-only controller, see v1/users_controller.rb
+#
+
+class UsersController < UsersBaseController
+
+ before_filter :require_login, :except => [:new]
+ before_filter :redirect_if_logged_in, :only => [:new]
+ before_filter :require_admin, :only => [:index, :deactivate, :enable]
+ before_filter :fetch_user, :only => [:show, :edit, :update, :destroy, :deactivate, :enable]
+
+ respond_to :html
+
+ def index
+ if params[:query]
+ if @user = User.find_by_login(params[:query])
+ redirect_to @user
+ return
+ else
+ @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ)
+ end
+ else
+ @users = User.by_created_at.descending
+ end
+ @users = @users.limit(100)
+ end
+
+ def new
+ @user = User.new
+ end
+
+ def show
+ end
+
+ def edit
+ end
+
+ ## added so updating service level works, but not sure we will actually want this. also not sure that this is place to prevent user from updating own effective service level, but here as placeholder:
+ def update
+ @user.update_attributes(params[:user]) unless (!admin? and params[:user][:effective_service_level])
+ respond_with @user
+ end
+
+ def deactivate
+ @user.enabled = false
+ @user.save
+ respond_with @user
+ end
+
+ def enable
+ @user.enabled = true
+ @user.save
+ respond_with @user
+ end
+
+ def destroy
+ @user.account.destroy
+ flash[:notice] = I18n.t(:account_destroyed)
+ # admins can destroy other users
+ if @user != current_user
+ redirect_to users_url
+ else
+ # let's remove the invalid session
+ logout
+ redirect_to bye_url
+ end
+ end
+
+end
diff --git a/app/controllers/v1/certs_controller.rb b/app/controllers/v1/certs_controller.rb
new file mode 100644
index 0000000..64cfa7f
--- /dev/null
+++ b/app/controllers/v1/certs_controller.rb
@@ -0,0 +1,50 @@
+class V1::CertsController < ApplicationController
+
+ before_filter :require_login, :unless => :anonymous_certs_allowed?
+
+ # GET /cert
+ def show
+ @cert = ClientCertificate.new(:prefix => certificate_prefix)
+ render text: @cert.to_s, content_type: 'text/plain'
+ end
+
+ protected
+
+ def anonymous_certs_allowed?
+ APP_CONFIG[:allow_anonymous_certs]
+ end
+ #
+ # this is some temporary logic until we store the service level in the user db.
+ #
+ # better logic might look like this:
+ #
+ # if logged_in?
+ # service_level = user.service_level
+ # elsif allow_anonymous?
+ # service_level = service_levels[:anonymous]
+ # else
+ # service_level = nil
+ # end
+ #
+ # if service_level.bandwidth == 'limited' && allow_limited?
+ # prefix = limited
+ # elsif allow_unlimited?
+ # prefix = unlimited
+ # else
+ # prefix = nil
+ # end
+ #
+ def certificate_prefix
+ if logged_in?
+ if APP_CONFIG[:allow_unlimited_certs]
+ APP_CONFIG[:unlimited_cert_prefix]
+ elsif APP_CONFIG[:allow_limited_certs]
+ APP_CONFIG[:limited_cert_prefix]
+ end
+ elsif !APP_CONFIG[:allow_limited_certs]
+ APP_CONFIG[:unlimited_cert_prefix]
+ else
+ APP_CONFIG[:limited_cert_prefix]
+ end
+ end
+end
diff --git a/app/controllers/v1/messages_controller.rb b/app/controllers/v1/messages_controller.rb
new file mode 100644
index 0000000..f71d0f1
--- /dev/null
+++ b/app/controllers/v1/messages_controller.rb
@@ -0,0 +1,25 @@
+module V1
+ class MessagesController < ApplicationController
+
+ skip_before_filter :verify_authenticity_token
+ before_filter :require_token
+
+ respond_to :json
+
+ def index
+ render json: (current_user ? current_user.messages : [] )
+ end
+
+ def update
+ message = Message.find(params[:id])
+ if (message and current_user)
+ message.mark_as_read_by(current_user)
+ message.save
+ render json: true
+ else
+ render json: false
+ end
+ end
+
+ end
+end
diff --git a/app/controllers/v1/sessions_controller.rb b/app/controllers/v1/sessions_controller.rb
new file mode 100644
index 0000000..eae3a1e
--- /dev/null
+++ b/app/controllers/v1/sessions_controller.rb
@@ -0,0 +1,45 @@
+module V1
+ class SessionsController < ApplicationController
+
+ skip_before_filter :verify_authenticity_token
+ before_filter :require_token, only: :destroy
+
+ def new
+ @session = Session.new
+ if authentication_errors
+ @errors = authentication_errors
+ render :status => 422
+ end
+ end
+
+ def create
+ logout if logged_in?
+ if params['A']
+ authenticate!
+ else
+ @user = User.find_by_login(params['login'])
+ render :json => {salt: @user.salt}
+ end
+ end
+
+ def update
+ authenticate!
+ @token = Token.create(:user_id => current_user.id)
+ session[:token] = @token.id
+ render :json => login_response
+ end
+
+ def destroy
+ logout
+ head :no_content
+ end
+
+ protected
+
+ def login_response
+ handshake = session.delete(:handshake) || {}
+ handshake.to_hash.merge(:id => current_user.id, :token => @token.id)
+ end
+
+ end
+end
diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb
new file mode 100644
index 0000000..8897d01
--- /dev/null
+++ b/app/controllers/v1/users_controller.rb
@@ -0,0 +1,32 @@
+module V1
+ class UsersController < UsersBaseController
+
+ skip_before_filter :verify_authenticity_token
+ before_filter :fetch_user, :only => [:update]
+ before_filter :require_admin, :only => [:index]
+ before_filter :require_token, :only => [:update]
+
+ respond_to :json
+
+ # used for autocomplete for admins in the web ui
+ def index
+ if params[:query]
+ @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ)
+ respond_with @users.map(&:login).sort
+ else
+ render :json => {'error' => 'query required', 'status' => :unprocessable_entity}
+ end
+ end
+
+ def create
+ @user = Account.create(params[:user])
+ respond_with @user # return ID instead?
+ end
+
+ def update
+ @user.account.update params[:user]
+ respond_with @user
+ end
+
+ end
+end
diff --git a/app/controllers/webfinger_controller.rb b/app/controllers/webfinger_controller.rb
new file mode 100644
index 0000000..8872802
--- /dev/null
+++ b/app/controllers/webfinger_controller.rb
@@ -0,0 +1,19 @@
+class WebfingerController < ApplicationController
+
+ respond_to :xml, :json
+ layout false
+
+ def host_meta
+ @host_meta = Webfinger::HostMetaPresenter.new(request)
+ respond_with @host_meta
+ end
+
+ def search
+ username = params[:q].split('@')[0].to_s.downcase
+ user = User.find_by_login(username)
+ raise RECORD_NOT_FOUND, 'User not found' unless user.present?
+ @presenter = Webfinger::UserPresenter.new(user, request)
+ respond_with @presenter
+ end
+
+end