## # Main controller class. Defines basic internal SSO actions. class AnoubisSsoServer::MainController < AnoubisSsoServer::ApplicationController ## # Login action for SSO server. # # API request: # GET /api//login # # Parameters: # - login (String) --- user email address (required field) # - password (String) --- user password (required field) # - locale (String) --- the output language locale (optional value) # - code (String) --- login code for redirect (optional value, default: 0) # # Request example: # curl --header "Content-Type: application/json" http://:/api//login=admin@example.com&password=password&locale=en # # Results: # # Resulting data returns as redirect to silent URL with login result. def login redirect_url = sso_silent_url redirect_url += redirect_url.index('?') ? '&' : '?' unless params[:login] redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.fields.login')), { allow_other_host: true } return end unless params[:password] redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.fields.password')), { allow_other_host: true } return end usr = user_model.where(email: params[:login]).first unless usr redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.incorrect_login')), { allow_other_host: true } return end unless usr.authenticate(params[:password]) redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.incorrect_login')), { allow_other_host: true } return end self.current_system = get_current_system unless current_system redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.system_not_defined')), { allow_other_host: true } return end code = nil if params[:code] begin code = JSON.parse(self.redis.get("#{redis_prefix}login_code:#{params[:code]}"),{ symbolize_names: true }) rescue end end session_name = SecureRandom.uuid session = { id: usr.id, uuid: usr.uuid, ttl: Time.now.utc.to_i + current_system[:ttl], timeout: current_system[:ttl] } cookies[:oauth_session] = session_name redis.set("#{redis_prefix}session:#{session_name}", session.to_json, ex: 86400) unless code redirect_to redirect_url + "code=0", { allow_other_host: true } else auth_code = SecureRandom.uuid redis.set("#{redis_prefix}auth_code:#{auth_code}", params[:code], ex: 600) redirect_to redirect_url + "code=#{auth_code}", { allow_other_host: true } end end ## # Procedure check current login status of user and redirect to URL used for call /openid/oauth2/auth. def auth redirect_url = sso_silent_url redirect_url += redirect_url.index('?') ? '&' : '?' err = check_listed_parameters %w[code] if err redirect_to redirect_url + 'error=' + ERB::Util.url_encode(err), { allow_other_host: true } return end begin session = JSON.parse(redis.get("#{redis_prefix}session:#{cookies[:oauth_session]}"), { symbolize_names: true }) rescue StandardError session = nil cookies[:oauth_session] = nil end unless session redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.session_expired')), { allow_other_host: true } return end begin auth_code = redis.get("#{redis_prefix}auth_code:#{params[:code]}") code = JSON.parse(redis.get("#{redis_prefix}login_code:#{auth_code}"), { symbolize_names: true }) rescue StandardError code = nil end unless code redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.is_not_correct', title: 'code')), { allow_other_host: true } return end self.redis.del("#{redis_prefix}auth_code:#{params[:code]}") self.redis.del("#{redis_prefix}login_code:#{auth_code}") redirect_to code[:original_url], { allow_other_host: true } end end