From 6f05ea63cd0a4b8afe87b90ae39081de7688f393 Mon Sep 17 00:00:00 2001 From: p31729568 Date: Sat, 12 Oct 2019 10:00:38 +0800 Subject: [PATCH] thiry party login --- app/controllers/bind_users_controller.rb | 22 ++++++++ app/models/open_user.rb | 4 ++ app/models/user.rb | 3 ++ app/services/application_service.rb | 2 + app/services/create_bind_user_service.rb | 51 +++++++++++++++++++ .../create_or_find_wechat_account_service.rb | 8 ++- config/routes.rb | 1 + 7 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 app/controllers/bind_users_controller.rb create mode 100644 app/services/create_bind_user_service.rb diff --git a/app/controllers/bind_users_controller.rb b/app/controllers/bind_users_controller.rb new file mode 100644 index 000000000..530aa9b73 --- /dev/null +++ b/app/controllers/bind_users_controller.rb @@ -0,0 +1,22 @@ +class BindUsersController < ApplicationController + before_action :require_login + + def create + user = CreateBindUserService.call(current_user, create_params) + successful_authentication(user) if user.id != current_user.id + + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + def new_user + current_user + end + + private + + def create_params + params.permit(:login, :password, :type, :not_bind) + end +end \ No newline at end of file diff --git a/app/models/open_user.rb b/app/models/open_user.rb index cedf02edb..91228b976 100644 --- a/app/models/open_user.rb +++ b/app/models/open_user.rb @@ -2,4 +2,8 @@ class OpenUser < ApplicationRecord belongs_to :user validates :uid, presence: true, uniqueness: { scope: :type } + + def can_bind_cache_key + "open_user:#{type}:#{uid}:can_bind" + end end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 92005d142..11ffe084c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,6 +31,9 @@ class User < ApplicationRecord LOGIN_CHARS = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z).freeze has_one :user_extension, dependent: :destroy + has_many :open_users, dependent: :destroy + has_one :wechat_open_user, class_name: 'OpenUsers::Wechat' + has_one :qq_open_user, class_name: 'OpenUsers::QQ' accepts_nested_attributes_for :user_extension, update_only: true has_many :memos, foreign_key: 'author_id' diff --git a/app/services/application_service.rb b/app/services/application_service.rb index 8b3819017..1be6896eb 100644 --- a/app/services/application_service.rb +++ b/app/services/application_service.rb @@ -1,6 +1,8 @@ class ApplicationService include Callable + Error = Class.new(StandardError) + private def strip(str) diff --git a/app/services/create_bind_user_service.rb b/app/services/create_bind_user_service.rb new file mode 100644 index 000000000..29818c493 --- /dev/null +++ b/app/services/create_bind_user_service.rb @@ -0,0 +1,51 @@ +class CreateBindUserService < ApplicationService + attr_reader :user, :params + + def initialize(user, params) + @user = user + @params = params + end + + def call + raise Error, '系统错误' if open_user.blank? + raise Error, '系统错误' unless can_bind_user? + + if params[:not_bind].to_s == 'true' + clear_can_bind_user_flag + return user + end + + bind_user = User.try_to_login(params[:login], params[:password]) + raise Error, '用户名或者密码错误' if bind_user.blank? + + ActiveRecord::Base.transaction do + open_user.user_id = bind_user.id + open_user.save! + + user.destroy! + end + + clear_can_bind_user_flag + + bind_user + end + + private + + def open_user + @_open_user ||= begin + case params[:type].to_s + when 'wechat' then user.wechat_open_user + when 'qq' then user.qq_open_user + end + end + end + + def can_bind_user? + Rails.cache.read(open_user.can_bind_cache_key).present? + end + + def clear_can_bind_user_flag + Rails.cache.delete(open_user.can_bind_cache_key) + end +end \ No newline at end of file diff --git a/app/services/oauth/create_or_find_wechat_account_service.rb b/app/services/oauth/create_or_find_wechat_account_service.rb index b59d6a68d..c9402a91f 100644 --- a/app/services/oauth/create_or_find_wechat_account_service.rb +++ b/app/services/oauth/create_or_find_wechat_account_service.rb @@ -18,21 +18,25 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService open_user = OpenUsers::Wechat.find_by(uid: result['unionid']) return open_user.user if open_user.present? + new_user = false if user.blank? || !user.logged? + new_user = true # 新用户 login = User.generate_login('w') @user = User.new(login: login, nickname: result['nickname']) end ActiveRecord::Base.transaction do - if user.new_record? + if new_user user.save! gender = result['sex'].to_i == 1 ? 0 : 1 user.create_user_extension!(gender: gender) end - OpenUsers::Wechat.create!(user: user, uid: result['unionid']) + new_open_user= OpenUsers::Wechat.create!(user: user, uid: result['unionid']) + + Rails.cache.write(new_open_user.can_bind_cache_key, 1, expires_in: 1.hours) if new_user # 方便后面进行账号绑定 end user diff --git a/config/routes.rb b/config/routes.rb index 056fb324c..c83fddffa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -827,6 +827,7 @@ Rails.application.routes.draw do end resource :template, only: [:show] resource :setting, only: [:show] + resource :bind_user, only: [:create] end namespace :admins do