v3: implement enable/disable
This commit is contained in:
parent
47b6590aad
commit
de5908dd43
|
@ -8,5 +8,9 @@ module Travis::API::V3
|
|||
def self.for_request(*)
|
||||
new
|
||||
end
|
||||
|
||||
def admin_for(repository)
|
||||
raise LoginRequired
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,12 +2,13 @@ require 'travis/api/v3/access_control/generic'
|
|||
|
||||
module Travis::API::V3
|
||||
class AccessControl::Application < AccessControl::Generic
|
||||
attr_reader :application_name, :config, :user
|
||||
attr_reader :application_name, :config, :user, :user_control
|
||||
|
||||
def initialize(application_name, user: nil)
|
||||
@application_name = application_name
|
||||
@config = Travis.config.applications[application_name]
|
||||
@user = user
|
||||
@user_control = user ? AccessControl::User.new(user) : AccessControl::Generic.new
|
||||
raise ArgumentError, 'unknown application %p' % application_name unless config
|
||||
raise ArgumentError, 'cannot use %p without a user' % application_name if config.requires_user and not user
|
||||
end
|
||||
|
@ -19,5 +20,12 @@ module Travis::API::V3
|
|||
def full_access?
|
||||
config.full_access
|
||||
end
|
||||
|
||||
def admin_for(repository)
|
||||
return user_control.admin_for(repository) unless full_access?
|
||||
admin = repository.users.where('permissions.admin = true'.freeze).order('users.synced_at DESC'.freeze).first
|
||||
raise AdminAccessRequired, "no admin found for #{repository.slug}" unless admin
|
||||
admin
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,10 @@ module Travis::API::V3
|
|||
full_access? or dispatch(object)
|
||||
end
|
||||
|
||||
def admin_for(repository)
|
||||
raise AdminAccessRequired, repository: repository
|
||||
end
|
||||
|
||||
def user
|
||||
end
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@ module Travis::API::V3
|
|||
true
|
||||
end
|
||||
|
||||
def admin_for(repository)
|
||||
permission?(:admin, repository) ? user : super
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def repository_writable?(repository)
|
||||
|
|
109
lib/travis/api/v3/extensions/encrypted_column.rb
Normal file
109
lib/travis/api/v3/extensions/encrypted_column.rb
Normal file
|
@ -0,0 +1,109 @@
|
|||
require 'securerandom'
|
||||
require 'base64'
|
||||
|
||||
module Travis::API::V3
|
||||
module Extensions
|
||||
class EncryptedColumn
|
||||
attr_reader :disable, :options
|
||||
alias disabled? disable
|
||||
|
||||
def initialize(options = {})
|
||||
@options = options || {}
|
||||
@disable = self.options[:disable]
|
||||
@key = self.options[:key]
|
||||
end
|
||||
|
||||
def enabled?
|
||||
!disabled?
|
||||
end
|
||||
|
||||
def load(data)
|
||||
return nil unless data
|
||||
|
||||
data = data.to_s
|
||||
|
||||
decrypt?(data) ? decrypt(data) : data
|
||||
end
|
||||
|
||||
def dump(data)
|
||||
encrypt?(data) ? encrypt(data.to_s) : data
|
||||
end
|
||||
|
||||
def key
|
||||
@key || config.key
|
||||
end
|
||||
|
||||
def iv
|
||||
SecureRandom.hex(8)
|
||||
end
|
||||
|
||||
def prefix
|
||||
'--ENCR--'
|
||||
end
|
||||
|
||||
def decrypt?(data)
|
||||
data.present? && (!use_prefix? || prefix_used?(data))
|
||||
end
|
||||
|
||||
def encrypt?(data)
|
||||
data.present? && enabled?
|
||||
end
|
||||
|
||||
def prefix_used?(data)
|
||||
data[0..7] == prefix
|
||||
end
|
||||
|
||||
def decrypt(data)
|
||||
data = data[8..-1] if prefix_used?(data)
|
||||
|
||||
data = decode data
|
||||
|
||||
iv = data[-16..-1]
|
||||
data = data[0..-17]
|
||||
|
||||
aes = create_aes :decrypt, key.to_s, iv
|
||||
|
||||
result = aes.update(data) + aes.final
|
||||
end
|
||||
|
||||
def encrypt(data)
|
||||
iv = self.iv
|
||||
|
||||
aes = create_aes :encrypt, key.to_s, iv
|
||||
|
||||
encrypted = aes.update(data) + aes.final
|
||||
|
||||
encrypted = "#{encrypted}#{iv}"
|
||||
encrypted = encode encrypted
|
||||
encrypted = "#{prefix}#{encrypted}" if use_prefix?
|
||||
encrypted
|
||||
end
|
||||
|
||||
def use_prefix?
|
||||
options.has_key?(:use_prefix) ? options[:use_prefix] : Travis::Features.feature_inactive?(:db_encryption_prefix)
|
||||
end
|
||||
|
||||
def create_aes(mode = :encrypt, key, iv)
|
||||
aes = OpenSSL::Cipher::AES.new(256, :CBC)
|
||||
|
||||
aes.send(mode)
|
||||
aes.key = key
|
||||
aes.iv = iv
|
||||
|
||||
aes
|
||||
end
|
||||
|
||||
def config
|
||||
Travis.config.encryption
|
||||
end
|
||||
|
||||
def decode(str)
|
||||
Base64.strict_decode64 str
|
||||
end
|
||||
|
||||
def encode(str)
|
||||
Base64.strict_encode64 str
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
43
lib/travis/api/v3/github.rb
Normal file
43
lib/travis/api/v3/github.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
require 'gh'
|
||||
|
||||
|
||||
module Travis::API::V3
|
||||
class GitHub
|
||||
DEFAULT_OPTIONS = {
|
||||
client_id: Travis.config.oauth2.try(:client_id),
|
||||
client_secret: Travis.config.oauth2.try(:client_secret),
|
||||
user_agent: "Travis-API/3 Travis-CI/0.0.1 GH/#{GH::VERSION}",
|
||||
origin: Travis.config.host,
|
||||
api_url: Travis.config.github.api_url,
|
||||
ssl: Travis.config.ssl.merge(Travis.config.github.ssl || {}).to_hash.compact
|
||||
}
|
||||
private_constant :DEFAULT_OPTIONS
|
||||
|
||||
attr_reader :gh, :user
|
||||
|
||||
def initialize(user = nil, token = nil)
|
||||
if user.respond_to? :github_oauth_token
|
||||
raise ServerError, 'no GitHub token for user' if user.github_oauth_token.blank?
|
||||
token = user.github_oauth_token
|
||||
end
|
||||
|
||||
@user = user
|
||||
@gh = GH.with(token: token, **DEFAULT_OPTIONS)
|
||||
end
|
||||
|
||||
def set_hook(repository, flag)
|
||||
config = { domain: Travis.config.service_hook_url || '' }
|
||||
|
||||
if user
|
||||
config[:user] = user.login
|
||||
config[:token] = user.token
|
||||
end
|
||||
|
||||
gh.post("repos/#{repository.slug}/hooks",
|
||||
name: 'travis'.freeze,
|
||||
events: [:push, :pull_request, :issue_comment, :public, :member],
|
||||
active: flag,
|
||||
config: config)
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/v3/models/token.rb
Normal file
14
lib/travis/api/v3/models/token.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis::API::V3
|
||||
class Models::Token < Model
|
||||
belongs_to :user
|
||||
validate :token, presence: true
|
||||
serialize :token, Extensions::EncryptedColumn.new(disable: true)
|
||||
before_validation :generate_token, on: :create
|
||||
|
||||
protected
|
||||
|
||||
def generate_token
|
||||
self.token = SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,9 +1,14 @@
|
|||
module Travis::API::V3
|
||||
class Models::User < Model
|
||||
has_many :memberships, dependent: :destroy
|
||||
has_many :organizations, through: :memberships
|
||||
has_many :permissions, dependent: :destroy
|
||||
has_many :repositories, through: :permissions
|
||||
has_many :emails, dependent: :destroy
|
||||
has_many :tokens, dependent: :destroy
|
||||
has_many :repositories, through: :permissions
|
||||
has_many :organizations, through: :memberships
|
||||
|
||||
def token
|
||||
tokens.first_or_create.token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,12 +13,17 @@ module Travis::API::V3
|
|||
@access_control = access_control
|
||||
@params = params
|
||||
@queries = {}
|
||||
@github = {}
|
||||
end
|
||||
|
||||
def query(type = self.class.result_type)
|
||||
@queries[type] ||= Queries[type].new(params, self.class.result_type)
|
||||
end
|
||||
|
||||
def github(user = nil)
|
||||
@github[user] ||= GitHub.new(user)
|
||||
end
|
||||
|
||||
def find(type = self.class.result_type, *args)
|
||||
not_found(true, type) unless object = query(type).find(*args)
|
||||
not_found(false, type) unless access_control.visible? object
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
module Travis::API::V3
|
||||
class Services::Repository::Disable < Service
|
||||
def run!(activate = false)
|
||||
not_implemented
|
||||
raise LoginRequired unless access_control.logged_in? or access_control.full_access?
|
||||
raise NotFound unless repository = find(:repository)
|
||||
|
||||
admin = access_control.admin_for(repository)
|
||||
github(admin).set_hook(repository, activate)
|
||||
repository.update_attributes(active: active)
|
||||
|
||||
repository
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user