diff --git a/app/assets/stylesheets/oauth.scss b/app/assets/stylesheets/oauth.scss new file mode 100644 index 000000000..e862b52de --- /dev/null +++ b/app/assets/stylesheets/oauth.scss @@ -0,0 +1,78 @@ +html{margin:0px;padding: 0px;font-size: 14px;font-family: "微软雅黑","宋体";} +body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { + margin: 0; + padding: 0; +} +.IndexContent{ + height: 100vh; + width: 100%; + position: relative; + background-image: url('/images/oauth/backImg.png'); + background-repeat: no-repeat; + background-size: cover; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} +.indexLogo{ + width:80px; + margin-bottom: 35px; +} +.indexPanel{ + width: 580px; + min-height: 400px; + background-color: #fff; + box-shadow: 0px 2px 10px 5px rgba(0,0,0,0.05); + border-radius: 5px; + box-sizing: border-box; +} +.indexTitle{ + height: 75px; + line-height: 75px; + font-size: 18px; + color:#333; + text-align: center; + border-bottom: 1px solid #eee; +} +.indexInfo{ + display: flex; + flex-direction: column; + align-items: flex-start; +} +.indexInfos{ + padding:40px 60px; +} +.indexInfo > span{ + color: #333; + font-size: 16px; + margin-top: 5px; +} +.indexInfo input{ + width: 100%; + height:40px; + border-radius: 2px; + border:1px solid #eee; + margin-top: 5px; + padding:0px 0px 0px 8px; + outline: none; +} +.indexInfo .checkInfo{ + height: 15px; + color: red; +} +.indexBtn{ + text-align: center; + margin-top: 20px; +} +.indexSubmit{ + width: 50%; + height: 32px; + line-height: 32px; + background-color: #1890FF; + border:none; + color: #fff; + border-radius: 2px; + cursor: pointer; + outline: none; +} diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 23290d91c..8d51fddc8 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -13,24 +13,12 @@ class AccountsController < ApplicationController password = params[:password] platform = (params[:platform] || 'forge')&.gsub(/\s+/, "") - @user = User.new(admin: false, login: username, mail: email, type: "User") - @user.password = password - @user.platform = platform - @user.activate - ActiveRecord::Base.transaction do - interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password}) - if interactor.success? - gitea_user = interactor.result - result = Gitea::User::GenerateTokenService.new(username, password).call - @user.gitea_token = result['sha1'] - @user.gitea_uid = gitea_user['id'] - if @user.save! - UserExtension.create!(user_id: @user.id) - render_ok({user: {id: @user.id, token: @user.gitea_token}}) - end + result = autologin_register(username, email, password, platform) + if result[:message].blank? + render_ok({user: result[:user]}) else - render_error(interactor.error) + render_error(result[:message]) end end rescue Exception => e diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 159832177..cd317e50f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,7 +9,8 @@ class ApplicationController < ActionController::Base include GitHelper include LoggerHelper include LoginHelper - + include RegisterHelper + protect_from_forgery prepend: true, unless: -> { request.format.json? } before_action :check_sign diff --git a/app/controllers/concerns/register_helper.rb b/app/controllers/concerns/register_helper.rb new file mode 100644 index 000000000..a5a5652ba --- /dev/null +++ b/app/controllers/concerns/register_helper.rb @@ -0,0 +1,28 @@ +module RegisterHelper + extend ActiveSupport::Concern + + def autologin_register(username, email, password, platform= '') + result = {message: nil, user: nil} + + user = User.new(admin: false, login: username, mail: email, type: "User") + user.password = password + user.platform = platform + user.activate + + interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password}) + if interactor.success? + gitea_user = interactor.result + result = Gitea::User::GenerateTokenService.new(username, password).call + user.gitea_token = result['sha1'] + user.gitea_uid = gitea_user['id'] + if user.save! + UserExtension.create!(user_id: user.id) + result[:user] = {id: user.id, token: user.gitea_token} + end + else + result[:message] = interactor.error + end + result + end + +end diff --git a/app/controllers/oauth/educoder_controller.rb b/app/controllers/oauth/educoder_controller.rb new file mode 100644 index 000000000..17c5e5dc6 --- /dev/null +++ b/app/controllers/oauth/educoder_controller.rb @@ -0,0 +1,36 @@ +class Oauth::EducoderController < Oauth::BaseController + def bind + begin + login = params[:login] + callback_url = params[:callback_url] + oauth_token = params[:key] + raw_pay_load = params[:raw_pay_load] + + ::OauthEducoderForm.new({login: login, oauth_token: oauth_token, callback_url: callback_url, raw_pay_load: raw_pay_load}).validate! + + open_user= OpenUser::Educoder.find_by(uid: login) + + if open_user.present? && open_user.user.present? && open_user.user.email_bind? + # 存在说明绑定了,验证信息是否齐全, + if current_user != open_user.user + logout_user + successful_authentication(open_user.user) + end + + redirect_to callback_url + else + # 未存在需要进行绑定 + if current_user.blank? || !current_user.logged? + # forge平台未登录 + redirect_to oauth_register_path(user_id: login, callback_url: callback_url) + else + # forge平台已登录 + OpenUsers::Educoder.create!(user: current_user, uid: login) + redirect_to callback_url + end + end + rescue WechatOauth::Error => ex + render_error(ex.message) + end + end +end diff --git a/app/controllers/oauth_controller.rb b/app/controllers/oauth_controller.rb index ff5908cd0..f9c526fac 100644 --- a/app/controllers/oauth_controller.rb +++ b/app/controllers/oauth_controller.rb @@ -1,4 +1,6 @@ class OauthController < ApplicationController + layout "oauth_register", only: [:register] + DEFAULT_PASSWORD = "a12345678" TOKEN_CALL_BACK = "/oauth/get_token_callback" USER_INFO = "/oauth/userinfo" @@ -51,4 +53,24 @@ class OauthController < ApplicationController def get_token_callback end + + def register + # redirect_to params[:callback_url] + end + + def auto_register + login = params[:login] + email = params[:email] + password = params[:login] + platform = params[:plathform] || 'forge' + + result = autologin_register(login, email, password, platform) + + if result[:message].blank? + redirect_to params[:callback_url] + else + render :action => "auto_register" + end + end + end diff --git a/app/forms/oauth_educoder_form.rb b/app/forms/oauth_educoder_form.rb new file mode 100644 index 000000000..2a6a0c385 --- /dev/null +++ b/app/forms/oauth_educoder_form.rb @@ -0,0 +1,37 @@ +class OauthEducoderForm + include ActiveModel::Model + + attr_accessor :login, :oauth_token, :callback_url, :raw_pay_load + + validates :login, presence: true + validates :oauth_token, presence: true + validates :callback_url, presence: true + validates :raw_pay_load, presence: true + + validate :check_oauth_token! + validate :check_callback_url! + + def checke_raw_pay_load! + secret = OauthEducoder.config[:access_key_secret] + + before_raw_pay_load = "#{login}#{secret}#{Time.now.to_i/60-1}" + now_raw_pay_load = "#{login}#{secret}#{Time.now.to_i/60-1}" + + if raw_pay_load != Digest::SHA1.hexdigest(now_raw_pay_load) || raw_pay_load != Digest::SHA1.hexdigest(before_raw_pay_load) + raise '你的请求无效值无效.' + end + end + + def checke_raw_pay_load! + secret = OauthEducoder.config[:access_key_secret] + raise 'oauth_token值无效.' if oauth_token != secret + end + + def check_callback_url! + request_host = URI.parse(callback_url).host + callback_url = OauthEducoder.config[:callback_url_host] + + raise 'callback_url参数无效.' if request_host != callback_url + end + +end diff --git a/app/libs/oauth_educoder.rb b/app/libs/oauth_educoder.rb new file mode 100644 index 000000000..4e700d76d --- /dev/null +++ b/app/libs/oauth_educoder.rb @@ -0,0 +1,20 @@ +module OauthEducoder + class << self + def config + educoder_config = {} + + begin + config = Rails.application.config_for(:configuration).symbolize_keys! + educoder_config = config[:oauth][:educoder].symbolize_keys! + raise 'oauth educoder config missing' if educoder_config.blank? + rescue => ex + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] educoder config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} + educoder_config = {} + end + educoder_config + end + end +end diff --git a/app/models/open_users/educoder.rb b/app/models/open_users/educoder.rb new file mode 100644 index 000000000..8993fe59f --- /dev/null +++ b/app/models/open_users/educoder.rb @@ -0,0 +1,9 @@ +class OpenUsers::EduCoder < OpenUser + def nickname + extra&.[]('nickname') + end + + def en_type + 'educoder' + end +end diff --git a/app/views/layouts/oauth_register.html.erb b/app/views/layouts/oauth_register.html.erb new file mode 100644 index 000000000..ac381eb4f --- /dev/null +++ b/app/views/layouts/oauth_register.html.erb @@ -0,0 +1,13 @@ + + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + <%= stylesheet_link_tag 'oauth', media: 'all','data-turbolinks-track': 'reload' %> + + +
+ <%= image_tag('/images/oauth/logo.png') %> + <%= yield %> +
+ + diff --git a/app/views/oauth/register.html.erb b/app/views/oauth/register.html.erb new file mode 100644 index 000000000..4b053b542 --- /dev/null +++ b/app/views/oauth/register.html.erb @@ -0,0 +1,54 @@ +
+

完善信息,进入比赛

+
+ <%= form_tag(oauth_auto_register_path, method: :post, class: 'form-inline search-form flex-1') do %> + <%= hidden_field_tag 'callback_url', params[:callback_url] %> +
+ 用户名: + <%= text_field_tag :mail, params[:login], placeholder: '请输入用户名', disabled: true, id: 'login' %> +

+
+
+ 邮箱: + <%= text_field_tag :mail, '', placeholder: '请输入绑定邮箱', maxlength: 40, id: 'email' %> +

+
+
+ 密码: + <%= password_field_tag :password, '', placeholder: '请输入账号密码', id: 'password' %> +

+
+
+ +
+ <% end %> +
+
+ diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index ef056bbef..60855f79e 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -12,5 +12,4 @@ Rails.application.config.assets.paths << Rails.root.join('vendor/assets') # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. -Rails.application.config.assets.precompile += %w( admin.js admin.css college.js college.css cooperative.js cooperative.css ) - +Rails.application.config.assets.precompile += %w( admin.js admin.css college.js college.css cooperative.js cooperative.css oauth.css ) diff --git a/config/routes.rb b/config/routes.rb index 1cfe1b2a3..00e27ed7f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,11 @@ Rails.application.routes.draw do get 'auth/qq/callback', to: 'oauth/qq#create' get 'auth/failure', to: 'oauth/base#auth_failure' get 'auth/cas/callback', to: 'oauth/cas#create' + + get 'oauth/bind', to: 'oauth/educoder#bind' + get 'oauth/register', to: 'oauth#register' + post 'oauth/auto_register', to: 'oauth#auto_register' + resources :edu_settings scope '/api' do diff --git a/public/images/oauth/backImg.png b/public/images/oauth/backImg.png new file mode 100644 index 000000000..450002fac Binary files /dev/null and b/public/images/oauth/backImg.png differ diff --git a/public/images/oauth/logo.png b/public/images/oauth/logo.png new file mode 100644 index 000000000..4d0b489bf Binary files /dev/null and b/public/images/oauth/logo.png differ