-
Notifications
You must be signed in to change notification settings - Fork 0
/
commit_request.rb
171 lines (154 loc) · 4.02 KB
/
commit_request.rb
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
165
166
167
168
169
170
171
class CommitRequest
include ActiveAttr::Model
include ActiveMessaging::MessageSender
attr_accessor :user, :command, :repository, :branch,:files, :records
attr_writer :commit_message, :files
validates_presence_of :user, :command, :repository, :branch, :commit_message
validates_numericality_of :user, :repository
validates_inclusion_of :command, in: %w( move add remove ), message: "%s is not an acceptable command"
validate :existence_of_user, :existence_of_repository, :commit_access , :correct_branch, :path_names
publishes_to :commit
#
# Performs the the action given by @options
# @move {
# command: "move",
# user: 1,
# repository: 123,
# branch: "master",
# commit_message: "A commit message",
# paths: [{
# from: "old/path",
# to: "new/path"
# }],
# records: [{
# from: "path/to/file.txt",
# to: "path/to/new_file.txt"
# }]
# }
#
# @add {
# command: "add",
# user: 1,
# repository: 123,
# branch: "master",
# commit_message: "A commit message",
# files: [{
# from: "/full/path/to/file",
# to: "path/to/dir"
# }]
# }
#
# @remove {
# user: 1,
# command: "remove",
# repository: 123,
# branch: "master",
# commit_message: "A commit message",
# records: [
# "path/to/dir1",
# "path/to/dir2",
# ]
# }
#
#
# @return String Commit message provided by frontend
#
def commit_message
if @commit_message.to_s.length.between?(6, 96)
@commit_message
else
"WebCommit: #{@command}"
end
end
#
# Ads @options to beanstalkd
# @return Boolean
# false when validation fails or @options has been pushed
# true when data has been pushed to beanstalkd
#
def save
return false unless valid?
if @command == "add"
@files.each do |file|
file["from"] = File.join(Rails.root, APP_CONFIG['tmp_upload_directory'], file["id"])
end
end
@options = {
command: @command,
user: @user,
repository: @repository,
branch: @branch,
commit_message: commit_message,
files: @files
}
@@cache[@options.to_s] ||= publish :commit, @options.merge({
callback: {
class: "CommitRequest",
method: "notify_user"
}
}).to_json
end
#
# Notify view about process
# @options Hash See @remove, @add and @move
#
def self.notify_user(options)
config = APP_CONFIG["faye"]
token = User.find(options["user"]).token
SecureFaye::Connect.new.
message({status: 200}.to_json).
token(config["token"]).
server("http://0.0.0.0:#{config["port"]}/faye").
channel("/users/#{token}").
send!
end
private
@@cache = {}
def path_names
if @command == 'add'
@files.each do |file|
if not (file[:to] =~ /[\\\0:<>"|?*"]/ ).nil?
errors[:files] << "Invalid filename"
end
end
end
end
def existence_of_user
unless User.exists?(user)
errors[:user] << "does not exist"
end
end
def existence_of_repository
unless Repository.exists?(repository)
errors[:repository] << "does not exist"
end
end
def correct_branch
unless branch == APP_CONFIG['default_branch']
errors[:correct_branch] << %q{
Permission denied, invalid branch
}
end
end
def commit_access
unless user_can_commit?
errors[:user_can_commit] << %q{
Permission denied, user is not allowed to commit to this repo
}
end
end
def current_user
@_current_user ||= User.find_by_id(user)
end
def user_can_commit?
return true if current_user and current_user.admin?
# Is the given repository part of a lab which
# responds to a given course that the user is
# examiner in OR does the user belongs to the lab
# which owns the repository?
LabHasGroup.
joins(lab_group: [:students, { given_course: :examiners }]).
where("examiners.user_id = ? OR students.user_id = ?", user, user).
where("lab_has_groups.repository_id = ?", repository).exists?
end
end