-
Notifications
You must be signed in to change notification settings - Fork 161
Expand file tree
/
Copy pathsetting_endpoint.rb
More file actions
164 lines (132 loc) · 4.22 KB
/
setting_endpoint.rb
File metadata and controls
164 lines (132 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
require 'travis/api/app'
class Travis::Api::App
class SettingsEndpoint < Endpoint
include ActiveSupport::Callbacks
extend ActiveSupport::Concern
define_callbacks :after_save
set_callback :after_save, :after, :save_audit
set(:prefix) { "/settings/" << name[/[^:]+$/].underscore }
class << self
# This method checks if class based on a given name exists or creates
# a new SettingsEndpoint subclass, which will be then used as an endpoint
def subclass(name)
class_name = name.to_s.camelize
if Travis::Api::App::Endpoint.const_defined?(class_name)
Travis::Api::App::Endpoint.const_get(class_name)
else
klass = create_settings_class(name)
Travis::Api::App::Endpoint.const_set(class_name, klass)
klass
end
end
def create_settings_class(name)
Class.new(self) do
define_method(:name) { name }
before { authenticate_by_mode! }
define_routes!
end
end
def define_routes!
get("/", scope: :private) do index end
get("/:id", scope: :private) do show end
post("/", scope: :private) do create end
patch("/:id", scope: :private) do update end
delete("/:id", scope: :private) do destroy end
end
end
# Rails style methods for easy overriding
def index
respond_with(collection, type: name, version: :v2)
end
def show
respond_with(record, type: singular_name, version: :v2)
end
def update
disallow_migrating!(repo)
record.update(JSON.parse(request.body.read)[singular_name])
if record.valid?
@changes = {
env_vars: {
created: "name: #{record.name}, is_public: #{record.public}, branch: #{record.branch || 'all'} "
}
} if is_env_var?
repo_settings.save
run_callbacks :after_save if is_env_var?
respond_with(record, type: singular_name, version: :v2)
else
status 422
respond_with(record, type: :validation_error, version: :v2)
end
end
def create
disallow_migrating!(repo)
record = collection.create(JSON.parse(request.body.read)[singular_name])
if record.valid?
@changes = {
env_vars: {
created: "name: #{record.name}, is_public: #{record.public}, branch: #{record.branch || 'all'}"
}
} if is_env_var?
repo_settings.save
run_callbacks :after_save if is_env_var?
respond_with(record, type: singular_name, version: :v2)
else
status 422
respond_with(record, type: :validation_error, version: :v2)
end
end
def destroy
disallow_migrating!(repo)
record = collection.destroy(params[:id]) || record_not_found
@changes = {
env_vars: {
destroyed: "name: #{record.name}, is_public: #{record.public}, branch: #{record.branch || 'all'} "
}
} if is_env_var?
repo_settings.save
run_callbacks :after_save if is_env_var?
respond_with(record, type: singular_name, version: :v2)
end
def singular_name
name.to_s.singularize
end
def collection
@collection ||= repo_settings.send(name)
end
def repo
@repo = Repository.find(params[:repository_id])
end
# This method can't be called "settings" because it clashes with
# Sinatra's method
def repo_settings
@settings ||= begin
service(:find_repo_settings, id: params['repository_id'].to_i).run
end || halt(404, error: "Couldn't find repository")
end
def record
collection.find(params[:id]) || record_not_found
end
def record_not_found
halt(404, { error: "Could not find a requested setting" })
end
def changes
@changes
end
def is_env_var?
singular_name == 'env_var'
end
private
def save_audit
change_source = access_token.app_id == 2 ? 'admin-v2' : 'travis-api'
Travis::API::V3::Models::Audit.create!(
owner: current_user,
change_source: change_source,
source: @repo,
source_changes: {
settings: self.changes
}
)
@changes = {}
end
end
end