From 28d6aa2dda36975d9721b33303a1865a278e367c Mon Sep 17 00:00:00 2001 From: Jasder <2053003901@@qq.com> Date: Tue, 13 Oct 2020 19:49:52 +0800 Subject: [PATCH] ADD drone user oauth --- README.md | 30 +++++++++++++ .../ci/cloud_accounts_controller.rb | 8 +++- .../concerns/ci/cloud_account_manageable.rb | 43 ++++++++++++++----- app/models/user.rb | 1 + config/routes.rb | 6 +++ 5 files changed, 76 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7bc1dbcce..62bfa67c9 100644 --- a/README.md +++ b/README.md @@ -2633,6 +2633,36 @@ https://localhost:3000/api/jasder/forgeplus/cloud_accounts.json | jq ``` --- +#### devops用户认证授权 +``` +GET /api/users/ci/oauth_grant +``` +*示例* +``` +curl -X GET \ +-d "password=123456" +http://localhost:3000/api/users/ci/oauth_grant.json | jq +``` +*请求参数说明:* + +|参数名|必选|类型|说明| +|-|-|-|-| +|password |是|string |用户密码 | + +*返回参数说明:* + +|参数名|类型|说明| +|-|-|-| +|status |int|0:成功, -1: 失败| + +``` +{ + "status": 0, + "message": "success" +} +``` +--- + #### 激活项目 ``` POST /api/:owner/:repo/activate diff --git a/app/controllers/ci/cloud_accounts_controller.rb b/app/controllers/ci/cloud_accounts_controller.rb index 01f4800b0..a005075a9 100644 --- a/app/controllers/ci/cloud_accounts_controller.rb +++ b/app/controllers/ci/cloud_accounts_controller.rb @@ -5,7 +5,7 @@ class Ci::CloudAccountsController < Ci::BaseController before_action :load_project, only: %i[create activate] before_action :authorize_owner_project!, only: %i[create activate] before_action :load_repo, only: %i[activate] - before_action :find_cloud_account, only: %i[show] + before_action :find_cloud_account, only: %i[show oauth_grant] before_action :validate_params!, only: %i[create bind] before_action only: %i[create bind] do connect_to_ci_database(master_db: true) @@ -83,6 +83,12 @@ class Ci::CloudAccountsController < Ci::BaseController render_error(ex.message) end + def oauth_grant + return render_error('你输入的密码不正确.') unless current_user.check_password?(params[:password].to_s) + + result = gitea_oauth_grant!(current_user.login, password, @cloud_account.drone_url, current_user.oauths.last&.client_id) + result === true ? render_ok : render_error('授权失败.') + end private def validate_params! diff --git a/app/controllers/concerns/ci/cloud_account_manageable.rb b/app/controllers/concerns/ci/cloud_account_manageable.rb index eae546c02..e92cd77bf 100644 --- a/app/controllers/concerns/ci/cloud_account_manageable.rb +++ b/app/controllers/concerns/ci/cloud_account_manageable.rb @@ -50,10 +50,7 @@ module Ci::CloudAccountManageable logger.info "######### redirect_url: #{redirect_url}" return nil unless result.present? - - gitea_oauth_grant!(current_user.gitea_uid, oauth.gitea_oauth_id) - return cloud_account - # result && !result.blank? ? cloud_account : nil + result && !result.blank? ? cloud_account : nil end def unbind_account! @@ -92,15 +89,39 @@ module Ci::CloudAccountManageable Ci::CloudAccount.exists?(ip_num: ip_num) ? [true, "#{devops_params[:ip_num]}服务器已被使用."] : [false, nil] end - def gitea_oauth_grant!(gitea_uid, application_id) - connection = Gitea::Database.set_connection.connection + def gitea_oauth_grant!(username, password, drone_url, client_id) + state = SecureRandom.hex(8) - unix_time = Time.now.to_i - # TODO - # 目前直接操作db,可以建立对应的model进行操作 - sql = "INSERT INTO oauth2_grant ( user_id, application_id, counter, created_unix, updated_unix ) VALUES ( #{gitea_uid}, #{application_id}, 0, #{unix_time}, #{unix_time} );" + # redirect_uri eg: + # https://localhost:3000/login/oauth/authorize?client_id=94976481-ad0e-4ed4-9247-7eef106007a2&redirect_uri=http%3A%2F%2F121.69.81.11%3A80%2Flogin&response_type=code&state=9cab990b9cfb1805 + redirect_uri = CGI.escape("#{drone_url}/login&response_type=code&state=#{state}") + grant_url = "#{Gitea.gitea_config[:domain]}/login/oauth/authorize?client_id=#{client_id}&redirect_uri=#{redirect_uri}" + logger.info "[gitea] grant_url: #{grant_url}" - connection.execute(sql) + conn = Faraday.new(url: grant_url) do |req| + req.request :url_encoded + req.adapter Faraday.default_adapter + req.basic_auth(username, password) + end + + response = conn.get + logger.info "[gitea] response headers: #{response.headers}" + + drone_oauth_user!(response.headers.to_h['location'], state) + end + + def drone_oauth_user!(url, state) + logger.info "[drone] drone_oauth_user url: #{url}" + conn = Faraday.new(url: url) do |req| + req.request :url_encoded + req.adapter Faraday.default_adapter + req.headers["cookie"] = "_session_=#{SecureRandom.hex(32)}; _oauth_state_=#{state}" + end + + response = conn.get + logger.info "[drone] response headers: #{response.headers}" + + response.headers['location'].include?('error') ? false : true end private diff --git a/app/models/user.rb b/app/models/user.rb index 9df853b4e..93c8d3357 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -100,6 +100,7 @@ class User < ApplicationRecord # 教学案例 # has_many :libraries, dependent: :destroy has_many :project_trends, dependent: :destroy + has_many :oauths , dependent: :destroy # Groups and active users scope :active, lambda { where(status: STATUS_ACTIVE) } diff --git a/config/routes.rb b/config/routes.rb index 9b94ebeb3..ee1e505a3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -173,6 +173,12 @@ Rails.application.routes.draw do to: 'cloud_accounts#unbind', as: :unbind_cloud_acclount ) + + get( + 'oauth_grant', + to: 'cloud_accounts#oauth_grant', + as: :ci_oauth_grant + ) end end end