| @@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base | |||||
| include RenderHelper | include RenderHelper | ||||
| include LoginHelper | include LoginHelper | ||||
| include ControllerRescueHandler | include ControllerRescueHandler | ||||
| include LoggerHelper | |||||
| # include LaboratoryHelper | # include LaboratoryHelper | ||||
| skip_before_action :verify_authenticity_token | skip_before_action :verify_authenticity_token | ||||
| @@ -11,6 +12,18 @@ class Oauth::BaseController < ActionController::Base | |||||
| end | end | ||||
| private | private | ||||
| def tip_exception(status = -1, message) | |||||
| raise Educoder::TipException.new(status, message) | |||||
| end | |||||
| def tip_show_exception(status = -2, message) | |||||
| raise Educoder::TipException.new(status, message) | |||||
| end | |||||
| def tip_show(exception) | |||||
| uid_logger("Tip show status is #{exception.status}, message is #{exception.message}") | |||||
| render json: exception.tip_json | |||||
| end | |||||
| def session_user_id | def session_user_id | ||||
| # session[:user_id] | # session[:user_id] | ||||
| @@ -48,4 +61,13 @@ class Oauth::BaseController < ActionController::Base | |||||
| Rails.logger.info("[wechat] set session unionid: #{unionid}") | Rails.logger.info("[wechat] set session unionid: #{unionid}") | ||||
| session[:unionid] = unionid | session[:unionid] = unionid | ||||
| end | end | ||||
| def session_edulogin | |||||
| session[:edulogin] | |||||
| end | |||||
| def set_session_edulogin(login) | |||||
| Rails.logger.info("[educoder] set sesstion edulogin: #{login}") | |||||
| session[:edulogin] = login | |||||
| end | |||||
| end | end | ||||
| @@ -32,4 +32,32 @@ class Oauth::EducoderController < Oauth::BaseController | |||||
| render_error(ex.message) | render_error(ex.message) | ||||
| end | end | ||||
| end | end | ||||
| # 需要educoder那边设置回调地址 | |||||
| def create | |||||
| begin | |||||
| code = params['code'].to_s.strip | |||||
| tip_exception("code不能为空") if code.blank? | |||||
| new_user = false | |||||
| result = EducoderOauth::Service.access_token(code, [request.protocol, request.host_with_port, '/api/auth/educoder/callback'].join('')) | |||||
| result = EducoderOauth::Service.user_info(result[:access_token]) | |||||
| # 存在该用户 | |||||
| open_user = OpenUsers::Educoder.find_by(uid: result['login']) | |||||
| if open_user.present? && open_user.user.present? | |||||
| successful_authentication(open_user.user) | |||||
| else | |||||
| if current_user.blank? || !current_user.logged? | |||||
| new_user = true | |||||
| set_session_edulogin(result['login']) | |||||
| else | |||||
| OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result) | |||||
| end | |||||
| end | |||||
| render_ok(new_user: new_user) | |||||
| rescue Exception => ex | |||||
| render_error(ex.message) | |||||
| end | |||||
| end | |||||
| end | end | ||||
| @@ -4,7 +4,7 @@ class SettingsController < ApplicationController | |||||
| get_add_menu | get_add_menu | ||||
| get_common_menu | get_common_menu | ||||
| get_personal_menu | get_personal_menu | ||||
| get_third_party | |||||
| end | end | ||||
| private | private | ||||
| @@ -40,6 +40,14 @@ class SettingsController < ApplicationController | |||||
| end | end | ||||
| end | end | ||||
| def get_third_party | |||||
| @third_party = [] | |||||
| @third_party << { | |||||
| name: 'educoder', | |||||
| url: EducoderOauth.oauth_url([request.protocol, request.host_with_port, '/api/auth/educoder/callback'].join('')) | |||||
| } | |||||
| end | |||||
| def get_site_url(key, value) | def get_site_url(key, value) | ||||
| key.to_s === "url" ? append_http(reset_site_url(value)) : reset_site_url(value) | key.to_s === "url" ? append_http(reset_site_url(value)) : reset_site_url(value) | ||||
| end | end | ||||
| @@ -0,0 +1,18 @@ | |||||
| module EducoderOauth | |||||
| class << self | |||||
| attr_accessor :client_id, :client_secret, :base_url | |||||
| def logger | |||||
| @_logger ||= STDOUT | |||||
| end | |||||
| def logger=(l) | |||||
| @_logger = l | |||||
| end | |||||
| def oauth_url(redirect_uri) | |||||
| "#{base_url}/oauth2?call_url=/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code" | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,37 @@ | |||||
| require 'oauth2' | |||||
| module EducoderOauth::Service | |||||
| module_function | |||||
| def request(method, url, params) | |||||
| begin | |||||
| Rails.logger.info("[EducoderOauth] [#{method.to_s.upcase}] #{url} || #{params}") | |||||
| client = Faraday.new(url: EducoderOauth.base_url) | |||||
| response = client.public_send(method, url, params) | |||||
| result = JSON.parse(response.body) | |||||
| Rails.logger.info("[EducoderOauth] [#{response.status}] #{result}") | |||||
| result | |||||
| rescue Exception => e | |||||
| raise Educoder::TipException.new(e.message) | |||||
| end | |||||
| end | |||||
| def access_token(code, redirect_uri) | |||||
| begin | |||||
| Rails.logger.info("[EducoderOauth] [code] #{code} ") | |||||
| Rails.logger.info("[EducoderOauth] [redirect_uri] #{redirect_uri} ") | |||||
| client = OAuth2::Client.new(EducoderOauth.client_id, EducoderOauth.client_secret, site: EducoderOauth.base_url) | |||||
| result = client.auth_code.get_token(code, redirect_uri: redirect_uri).to_hash | |||||
| return result | |||||
| rescue Exception => e | |||||
| raise Educoder::TipException.new(e.message) | |||||
| end | |||||
| end | |||||
| def user_info(access_token) | |||||
| request(:get, '/api/users/info.json', {access_token: access_token}) | |||||
| end | |||||
| end | |||||
| @@ -56,4 +56,5 @@ json.setting do | |||||
| end | end | ||||
| json.common @common | json.common @common | ||||
| json.third_party @third_party | |||||
| end | end | ||||
| @@ -43,6 +43,10 @@ default: &default | |||||
| cate_id: '-1' | cate_id: '-1' | ||||
| callback_url: 'callback_url' | callback_url: 'callback_url' | ||||
| signature_key: 'test12345678' | signature_key: 'test12345678' | ||||
| educoder: | |||||
| client_id: 'e9ce4d5ba1698d6f7d01d8ee2959776c7a6d743ebe94da2341e288fd2fbf60aa' | |||||
| client_secret: '6ff84dd75eddd859c5bd0e7a791b58bc5ad1ba4fbb30bc9db37cb0baf9f33012' | |||||
| base_url: 'https://test-data.educoder.net' | |||||
| gitea: | gitea: | ||||
| access_key_id: 'root' | access_key_id: 'root' | ||||
| @@ -0,0 +1,15 @@ | |||||
| oauth_config = {} | |||||
| begin | |||||
| config = Rails.application.config_for(:configuration) | |||||
| oauth_config = config.dig('oauth', 'educoder') | |||||
| raise 'oauth educoder config missing' if oauth_config.blank? | |||||
| rescue => ex | |||||
| raise ex if Rails.env.production? | |||||
| puts %Q{\033[33m [warning] wechat oauth config or configuration.yml missing, | |||||
| please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} | |||||
| end | |||||
| EducoderOauth.client_id = oauth_config['client_id'] | |||||
| EducoderOauth.client_secret = oauth_config['client_secret'] | |||||
| EducoderOauth.base_url = oauth_config['base_url'] | |||||
| @@ -312,6 +312,7 @@ Rails.application.routes.draw do | |||||
| get '/auth/qq/callback', to: 'oauth/qq#create' | get '/auth/qq/callback', to: 'oauth/qq#create' | ||||
| get '/auth/wechat/callback', to: 'oauth/wechat#create' | get '/auth/wechat/callback', to: 'oauth/wechat#create' | ||||
| get '/auth/educoder/callback', to: 'oauth/educoder#create' | |||||
| resource :bind_user, only: [:create] | resource :bind_user, only: [:create] | ||||
| resources :hot_keywords, only: [:index] | resources :hot_keywords, only: [:index] | ||||