From 0d97d7d4f0ac5c19a3b0cd4136bb205f8a076730 Mon Sep 17 00:00:00 2001 From: "vilet.yy" Date: Thu, 1 Apr 2021 18:01:51 +0800 Subject: [PATCH] add: educoder third party --- app/controllers/oauth/base_controller.rb | 22 ++++++++++++ app/controllers/oauth/educoder_controller.rb | 28 +++++++++++++++ app/controllers/settings_controller.rb | 10 +++++- app/libs/educoder_oauth.rb | 18 ++++++++++ app/libs/educoder_oauth/service.rb | 37 ++++++++++++++++++++ app/views/settings/show.json.jbuilder | 1 + config/configuration.yml.example | 4 +++ config/initializers/educoder_oauth_init.rb | 15 ++++++++ config/routes.rb | 1 + 9 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 app/libs/educoder_oauth.rb create mode 100644 app/libs/educoder_oauth/service.rb create mode 100644 config/initializers/educoder_oauth_init.rb diff --git a/app/controllers/oauth/base_controller.rb b/app/controllers/oauth/base_controller.rb index 3fe349bb5..6956c9ce9 100644 --- a/app/controllers/oauth/base_controller.rb +++ b/app/controllers/oauth/base_controller.rb @@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base include RenderHelper include LoginHelper include ControllerRescueHandler + include LoggerHelper # include LaboratoryHelper skip_before_action :verify_authenticity_token @@ -11,6 +12,18 @@ class Oauth::BaseController < ActionController::Base end 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 # session[:user_id] @@ -48,4 +61,13 @@ class Oauth::BaseController < ActionController::Base Rails.logger.info("[wechat] set session unionid: #{unionid}") session[:unionid] = unionid 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 diff --git a/app/controllers/oauth/educoder_controller.rb b/app/controllers/oauth/educoder_controller.rb index 8ed537d6c..cc9ad8966 100644 --- a/app/controllers/oauth/educoder_controller.rb +++ b/app/controllers/oauth/educoder_controller.rb @@ -32,4 +32,32 @@ class Oauth::EducoderController < Oauth::BaseController render_error(ex.message) 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 diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index b6662f661..eab27636c 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -4,7 +4,7 @@ class SettingsController < ApplicationController get_add_menu get_common_menu get_personal_menu - + get_third_party end private @@ -40,6 +40,14 @@ class SettingsController < ApplicationController 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) key.to_s === "url" ? append_http(reset_site_url(value)) : reset_site_url(value) end diff --git a/app/libs/educoder_oauth.rb b/app/libs/educoder_oauth.rb new file mode 100644 index 000000000..3fa06dcde --- /dev/null +++ b/app/libs/educoder_oauth.rb @@ -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 \ No newline at end of file diff --git a/app/libs/educoder_oauth/service.rb b/app/libs/educoder_oauth/service.rb new file mode 100644 index 000000000..29f5f1ebb --- /dev/null +++ b/app/libs/educoder_oauth/service.rb @@ -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 \ No newline at end of file diff --git a/app/views/settings/show.json.jbuilder b/app/views/settings/show.json.jbuilder index 330966aa1..ea42f20b4 100644 --- a/app/views/settings/show.json.jbuilder +++ b/app/views/settings/show.json.jbuilder @@ -56,4 +56,5 @@ json.setting do end json.common @common + json.third_party @third_party end diff --git a/config/configuration.yml.example b/config/configuration.yml.example index 823d8547e..1bb25ec39 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -43,6 +43,10 @@ default: &default cate_id: '-1' callback_url: 'callback_url' signature_key: 'test12345678' + educoder: + client_id: 'e9ce4d5ba1698d6f7d01d8ee2959776c7a6d743ebe94da2341e288fd2fbf60aa' + client_secret: '6ff84dd75eddd859c5bd0e7a791b58bc5ad1ba4fbb30bc9db37cb0baf9f33012' + base_url: 'https://test-data.educoder.net' gitea: access_key_id: 'root' diff --git a/config/initializers/educoder_oauth_init.rb b/config/initializers/educoder_oauth_init.rb new file mode 100644 index 000000000..1ef46bc95 --- /dev/null +++ b/config/initializers/educoder_oauth_init.rb @@ -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'] diff --git a/config/routes.rb b/config/routes.rb index daef12bb4..fec562ace 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -312,6 +312,7 @@ Rails.application.routes.draw do get '/auth/qq/callback', to: 'oauth/qq#create' get '/auth/wechat/callback', to: 'oauth/wechat#create' + get '/auth/educoder/callback', to: 'oauth/educoder#create' resource :bind_user, only: [:create] resources :hot_keywords, only: [:index]