diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 845f889..f8f1ed9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,66 +1,78 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception helper_method :current_user, :warden def index redirect_to clients_path if current_user end def unauthenticated + flash[:error] = warden.message redirect_to root_path end # POST /login def login if params[:admin] == 'admin' warden.authenticate(:admin) current_user end redirect_to admin_path end + # POST /vima + def vima + begin + warden.authenticate!(:vima) + rescue + return unauthenticated + end + current_user + redirect_to clients_path + end + def logout warden.logout reset_current_user redirect_to root_path end protected def warden request.env['warden'] end def current_user @current_user ||= warden.user end def reset_current_user @current_user = nil end def fetch_logs days_ago = params.fetch(:days_back, 7).to_i rescue 7 if @client @logs = Log.includes(:job).joins(job: :client).where(Client: { ClientId: @client.id }) else @logs = Log.includes(:job).joins(job: { client: { host: :users } }). where(users: { id: current_user.id }) end @logs = @logs.where('Time > ?', days_ago.days.ago). order(Time: :desc, LogId: :desc).page(params[:page]) end private def require_logged_in return if current_user flash[:alert] = 'You need to log in first' redirect_to root_path end end diff --git a/app/views/application/index.html.erb b/app/views/application/index.html.erb index 06b971b..f3a51a6 100644 --- a/app/views/application/index.html.erb +++ b/app/views/application/index.html.erb @@ -1,2 +1,5 @@ <%= link_to 'admin', login_path(admin: 'admin'), method: :post, role: :button, class: 'btn btn-primary' %> + +<%= link_to 'vima', vima_path(vima: 'vima'), method: :post, role: :button, + class: 'btn btn-primary' %> diff --git a/config/initializers/00_settings.rb b/config/initializers/00_settings.rb index 1c45762..f158398 100644 --- a/config/initializers/00_settings.rb +++ b/config/initializers/00_settings.rb @@ -1 +1,3 @@ Baas.settings local_db: "local_#{Rails.env}".to_sym + +Archiving.settings vima_oauth_enabled: true diff --git a/config/routes.rb b/config/routes.rb index 38eef99..1988513 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,67 +1,68 @@ Rails.application.routes.draw do root 'application#index' post 'login' => 'application#login' + match 'vima', to: 'application#vima', :via => [:get, :post] get 'logout' => 'application#logout' resources :clients, only: [:index, :show] do member do get :jobs get :logs get :stats post :stats end collection do post :index end end resources :hosts, only: [:new, :create, :show, :edit, :update, :destroy] do member do post :submit_config get :restore post :run_restore delete :revoke end resources :jobs, only: [:new, :create, :show, :edit, :update, :destroy] do member do patch :toggle_enable post :backup_now end end resources :filesets, only: [:show, :new, :create, :destroy] resources :schedules, only: [:show, :new, :edit, :create, :update, :destroy] end namespace :admin do match '/', to: 'base#index', via: [:get, :post] resources :settings, only: [:index, :new, :create, :edit, :update] do member do delete :reset end end resources :clients, only: [:index, :show] do member do get :jobs get :logs get :stats post :stats get :configuration end end resources :hosts, only: [:show] do collection do get :unverified end member do post :verify end end end end diff --git a/lib/peter/strategies/vima.rb b/lib/peter/strategies/vima.rb index 127c4a8..a0c3324 100644 --- a/lib/peter/strategies/vima.rb +++ b/lib/peter/strategies/vima.rb @@ -1,7 +1,82 @@ +## -*- encoding : utf-8 -*- +require 'oauth2' + Warden::Strategies.add(:vima) do + Key = Rails.application.secrets.oauth2_vima_client_id + Secret = Rails.application.secrets.oauth2_vima_secret + def valid? + params['vima'] || params['error'] || params['code'] + end + + def client + OAuth2::Client.new( + Key, + Secret, + site: 'https://vima.grnet.gr', + token_url: "/o/token", + authorize_url: "/o/authorize", + :ssl => {:ca_path => "/etc/ssl/certs"} + ) + end + + def redirect_uri + uri = URI.parse(request.url) + uri.scheme = 'https' unless Rails.env.development? + uri.path = '/vima' + uri.query = nil + uri.to_s + end + + def redirect_to_vima + redirect! client.auth_code.authorize_url(:redirect_uri => redirect_uri, scope: 'read') end def authenticate! + if !Baas::settings[:vima_oauth_enabled] + return fail!("ViMa is temporarily disabled") + end + + if params['error'] + Rails.logger.warn("WARDEN: ERROR #{params['error']}") + return fail!("ViMa log in failed: #{params['error']}") + end + + return redirect_to_vima if params['vima'] + + access_token = client.auth_code.get_token( + params['code'], + { :redirect_uri => redirect_uri }, + { :mode => :query, :param_name => "access_token", :header_format => "" }) + + user_data = access_token.get('https://vima.grnet.gr/instances/list?tag=vima:service:archiving', + { mode: :query, param_name: 'access_token' }). + parsed.deep_symbolize_keys + + user = User.find_or_initialize_by(username: user_data[:user][:username], + email: user_data[:user][:email]) + if user.new_record? + user.enabled = true + user.vima! + end + + if user_data[:response][:errors] != false + Rails.logger.warn("ViMa: errors on instances/list response for user #{user_data[:user][:username]}") + end + + if !user.enabled? + return fail!('Service not available') + end + + assign_vms(user, user_data[:response][:instances]) + + success!(user) + end + + def assign_vms(user, vms) + session[:vms] = vms + Host.where(fqdn: vms).each do |host| + host.users << user unless host.users.include?(user) + end end end