GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#237)
by Moritz
01:06
created

WatchDogServer.events()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 3
rs 10
1
require 'digest/sha1'
2
3
require 'sinatra'
4
require 'mongo'
5
require 'sinatra/contrib'
6
require 'json'
7
require 'net/smtp'
8
require 'logger'
9
require 'geocoder'
10
require 'yaml'
11
12
class WatchDogServer < Sinatra::Base
13
  include Mongo
14
15
  def mongo
16
    @serverconfig ||= YAML.load_file('config.yaml')[settings.environment.to_s]
17
    MongoClient.new(@serverconfig['mongo_host'], 27017)
18
  end
19
20
  # Setup database connection
21
  before  do
22
    mongo
23
    @db = mongo.db(@serverconfig['mongo_db'])
24
    unless @serverconfig['mongo_username'].nil? or @serverconfig['mongo_username'].empty? 
25
      @db.authenticate(@serverconfig['mongo_username'],
26
                       @serverconfig['mongo_password'])
27
    end
28
  end
29
30
  after do
31
    @db.connection.close
32
    @db = nil
33
  end
34
35
  # Do not support static files
36
  set :static, false
37
38
  # Enable request logging
39
  enable :logging
40
41
  logger = Logger.new('logfile.log')
42
43
  # Enable post payloads up to 4MB
44
  Rack::Utils.key_space_limit = 4914304
45
  logger.info("key_space_limit=#{Rack::Utils.key_space_limit}")
46
47
  Geocoder.configure(:timeout => 3, :lookup => :google)
48
49
  get '/' do
50
    'Woof Woof'
51
  end
52
53
  # Get info about stored user
54
  get '/client' do
55
    client_version = "1.7.0"
56
57
    status 200
58
    body client_version.to_json
59
  end
60
61
  # Get info about stored user
62
  get '/user/:id' do
63
    get_entity_info('get_user_by_id', params[:'id'])
64
  end
65
66
  # Get info about stored project
67
  get '/project/:id' do
68
    get_entity_info('get_project_by_id', params[:'id'])
69
  end
70
71
  
72
  # Return info about stored entity
73
  def get_entity_info(info_function, id) 
74
    stored_entity = self.send(info_function, id)
75
    
76
    if stored_entity.nil?
77
      halt 404, "Entity does not exist"
78
    else
79
      status 200
80
      body stored_entity['id'].to_json
81
    end
82
  end
83
84
  # Create a new user and return unique SHA1
85
  post '/user' do
86
    user = create_json_object(request)
87
	
88
	if user['programmingExperience'].nil? or user['programmingExperience'].empty?
89
	  halt 404, "Missing programming experience in user registration"
90
	end
91
	
92
    sha = create_40_char_SHA
93
    logger.info user
94
95
    user['id'] = sha
96
97
    begin
98
      user['country'] = request.location.country
99
    rescue
100
      user['country'] = 'NA' 
101
      logger.warn user
102
    end
103
    begin
104
      user['city'] = request.location.city
105
    rescue
106
      user['city'] = 'NA' 
107
    end
108
    begin
109
      user['postCode'] = request.location.postal_code
110
    rescue 
111
      user['postCode'] = 'NA' 
112
    end
113
114
    add_ip_timestamp(user, request)
115
116
    users.save(user)
117
    stored_user = get_user_by_id(sha)
118
119
    unless user['email'].nil? or user['email'].empty?
120
      send_registration_email(USER_REGISTERED, user['email'], sha, nil)
121
    end
122
123
    status 201
124
    body stored_user['id']
125
  end
126
127
  # Create a new project and return unique SHA1
128
  post '/project' do
129
    project = create_json_object(request)
130
    logger.info project
131
132
    associated_user = get_user_by_id(project['userId'])
133
    if associated_user.nil?
134
      halt 404, "The user who registers the project does not exist on the server. Create a new user first."
135
    end
136
137
    sha = create_40_char_SHA()
138
139
    project['id'] = sha
140
141
    add_ip_timestamp(project, request)
142
143
    projects.save(project)
144
145
    unless associated_user['email'].nil? or associated_user['email'].empty?
146
      send_registration_email(PROJECT_REGISTERED, associated_user['email'], sha, project['name'])
147
    end
148
149
    status 201
150
    body sha
151
  end
152
153
  # Create new intervals
154
  post '/user/:uid/:pid/intervals' do
155
    ivals = create_json_object(request)
156
157
    unless ivals.kind_of?(Array)
158
      halt 400, 'Wrong request, body is not a JSON array'
159
    end
160
161
    if ivals.size > 100000
162
      halt 413, 'Request too long (> 100000 intervals)'
163
    end
164
165
    negative_intervals = ivals.find{|x| (x['te'].to_i - x['ts'].to_i) < 0}
166
167
    unless negative_intervals.nil?
168
      halt 400, 'Request contains negative intervals'
169
    end
170
171
    user_id = params[:uid]
172
    user = get_user_by_id(user_id)
173
174
    if user.nil?
175
      halt 404, "User does not exist"
176
    end
177
178
    project_id = params[:pid]
179
    project = get_project_by_id(project_id)
180
181
    if project.nil?
182
      halt 404, "Project does not exist"
183
    end
184
185
    ivals.each do |i|
186
      begin
187
        i['userId'] = user_id
188
        i['projectId'] = project_id
189
        add_ip_timestamp(i, request)
190
        intervals.save(i)
191
      rescue IndexError => e
192
        log.error "IndexError occurred. Interval: #{i}"
193
        log.error e.backtrace
194
      rescue StandardError => e
195
        log.error "Unexpected error: #{e.message}"
196
        log.error e.backtrace
197
      end
198
    end
199
200
    status 201
201
    body ivals.size.to_s
202
  end
203
204
  # Create new events
205
  post '/user/:uid/:pid/events' do
206
    evs = create_json_object(request)
207
208
    unless evs.kind_of?(Array)
209
      halt 400, 'Wrong request, body is not a JSON array'
210
    end
211
212
    if evs.size > 100000
213
      halt 413, 'Request too long (> 100000 events)'
214
    end
215
216
    user_id = params[:uid]
217
    user = get_user_by_id(user_id)
218
219
    if user.nil?
220
      halt 404, "User does not exist"
221
    end
222
223
    project_id = params[:pid]
224
    project = get_project_by_id(project_id)
225
226
    if project.nil?
227
      halt 404, "Project does not exist"
228
    end
229
230
    evs.each do |i|
231
      begin
232
        i['userId'] = user_id
233
        i['projectId'] = project_id
234
        add_ip_timestamp(i, request)
235
        events.save(i)
236
      rescue IndexError => e
237
        log.error "IndexError occurred. Event: #{i}"
238
        log.error e.backtrace
239
      rescue StandardError => e
240
        log.error "Unexpected error: #{e.message}"
241
        log.error e.backtrace
242
      end
243
    end
244
245
    status 201
246
    body evs.size.to_s
247
  end
248
249
  private
250
251
  def users
252
    @db.collection('users')
253
  end
254
255
  def projects
256
    @db.collection('projects')
257
  end
258
259
  def intervals
260
    @db.collection('intervals')
261
  end
262
263
  def events
264
    @db.collection('events')
265
  end
266
267
  def get_user_by_id(id)
268
    users.find_one({'id' => id})
269
  end
270
271
  def get_project_by_id(id)
272
    projects.find_one({'id' => id})
273
  end
274
275
  # creates a json object from a http request
276
  def create_json_object(request)
277
     begin
278
      object = JSON.parse(request.body.read)
279
    rescue StandardError => e
280
      logger.error e
281
      halt 400, "Wrong JSON object #{request.body.read}"
282
    end
283
    return object
284
  end
285
286
  def add_ip_timestamp(object, request)
287
    object['ip'] = request.ip
288
    object['regDate'] = Time.now
289
  end
290
291
  # creates a 40 character long SHA hash
292
  def create_40_char_SHA()
293
    rnd = (0...100).map { ('a'..'z').to_a[rand(26)] }.join
294
    return Digest::SHA1.hexdigest rnd
295
  end
296
297
  # sends a registration mail
298
  def send_registration_email(mailtext, email, id, projectname)
299
    text = sprintf(mailtext, Time.now.rfc2822, id, projectname, id)
300
301
    Net::SMTP.start('localhost', 25, 'testroots.org') do |smtp|
302
      begin
303
        smtp.send_message(text, '[email protected]', email)
304
      rescue StandardError => e
305
        logger.error "Failed to send email to #{email}: #{e.message}"
306
        logger.error e.backtrace.join("\n")
307
      end
308
    end
309
   rescue Errno::ECONNREFUSED => e
310
        logger.error "NET::SMTP.start failure"
311
        logger.error e.backtrace.join("\n")
312
  end
313
314
315
  USER_REGISTERED = <<-END_EMAIL
316
Subject: Your new WatchDog user id
317
Date: %s
318
319
Dear WatchDog user,
320
321
You recently registered with WatchDog.
322
323
Your user id is: %s
324
325
You can use this id to link other WatchDog installations to your user.
326
327
Thank you for contributing to science -- with WatchDog!
328
329
Moritz, Georgios, Annibale, Igor and Andy
330
--
331
The TestRoots team
332
http://www.testroots.org - http://www.tudelft.nl
333
  END_EMAIL
334
335
336
  PROJECT_REGISTERED = <<-END_EMAIL
337
Subject: Your new WatchDog project id
338
Date: %s
339
340
Dear WatchDog user,
341
342
You recently registered a new project with WatchDog.
343
344
Your new project id is: %s
345
Your project name is: %s
346
347
You can use this id for other workspaces where you work on the same project.
348
If your colleagues work on the same project, please ask them to create new
349
project ids, but with the same project name.
350
351
You will be able to access your custom-generated project report under:
352
http://www.testroots.org/reports/project/%s.html
353
354
Please give us a time frame of 24 hours to create your report.
355
356
Thank you for contributing to science -- with WatchDog!
357
358
Moritz, Georgios, Annibale, Igor and Andy
359
--
360
The TestRoots team
361
http://www.testroots.org - http://www.tudelft.nl
362
  END_EMAIL
363
364
end
365