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
|
# frozen_string_literal: true
class SystemHooksService
BUILDER_DRIVEN_EVENT_DATA_AVAILABLE_FOR_CLASSES = [GroupMember].freeze
def execute_hooks_for(model, event)
data = build_event_data(model, event)
model.run_after_commit_or_now do
SystemHooksService.new.execute_hooks(data)
end
end
def execute_hooks(data, hooks_scope = :all)
SystemHook.hooks_for(hooks_scope).find_each do |hook|
hook.async_execute(data, 'system_hooks')
end
Gitlab::FileHook.execute_all_async(data)
end
private
def build_event_data(model, event)
# return entire event data from its builder class, if available.
return builder_driven_event_data(model, event) if builder_driven_event_data_available?(model)
data = {
event_name: build_event_name(model, event),
created_at: model.created_at&.xmlschema,
updated_at: model.updated_at&.xmlschema
}
case model
when Key
data.merge!(
key: model.key,
id: model.id
)
if model.user
data[:username] = model.user.username
end
when Project
data.merge!(project_data(model))
if event == :rename || event == :transfer
data[:old_path_with_namespace] = model.old_path_with_namespace
end
when User
data.merge!(user_data(model))
case event
when :rename
data[:old_username] = model.username_before_last_save
when :failed_login
data[:state] = model.state
end
when ProjectMember
data.merge!(project_member_data(model))
when Group
data.merge!(group_data(model))
if event == :rename
data.merge!(
old_path: model.path_before_last_save,
old_full_path: model.full_path_before_last_save
)
end
end
data
end
def build_event_name(model, event)
case model
when ProjectMember
return "user_add_to_team" if event == :create
return "user_remove_from_team" if event == :destroy
return "user_update_for_team" if event == :update
else
"#{model.class.name.downcase}_#{event}"
end
end
def project_data(model)
owner = model.owner
{
name: model.name,
path: model.path,
path_with_namespace: model.full_path,
project_id: model.id,
owner_name: owner.name,
owner_email: owner.respond_to?(:email) ? owner.email : "",
project_visibility: model.visibility.downcase
}
end
def project_member_data(model)
project = model.project || Project.unscoped.find(model.source_id)
{
project_name: project.name,
project_path: project.path,
project_path_with_namespace: project.full_path,
project_id: project.id,
user_username: model.user.username,
user_name: model.user.name,
user_email: model.user.email,
user_id: model.user.id,
access_level: model.human_access,
project_visibility: Project.visibility_levels.key(project.visibility_level_value).downcase
}
end
def group_data(model)
owner = model.owner
{
name: model.name,
path: model.path,
full_path: model.full_path,
group_id: model.id,
owner_name: owner.try(:name),
owner_email: owner.try(:email)
}
end
def user_data(model)
{
name: model.name,
email: model.email,
user_id: model.id,
username: model.username
}
end
def builder_driven_event_data_available?(model)
model.class.in?(BUILDER_DRIVEN_EVENT_DATA_AVAILABLE_FOR_CLASSES)
end
def builder_driven_event_data(model, event)
case model
when GroupMember
Gitlab::HookData::GroupMemberBuilder.new(model).build(event)
end
end
end
SystemHooksService.prepend_if_ee('EE::SystemHooksService')
|