##// END OF EJS Templates
tests: don't use "status" operand of dd in test-censor.t (issue6858)...
av6 -
r52208:c7edfccf stable
parent child Browse files
Show More
@@ -1,621 +1,621 b''
1 1 #require no-reposimplestore
2 2 #testcases revlogv1 revlogv2
3 3
4 4 #if revlogv2
5 5
6 6 $ cat >> $HGRCPATH <<EOF
7 7 > [experimental]
8 8 > revlogv2=enable-unstable-format-and-corrupt-my-data
9 9 > EOF
10 10
11 11 #endif
12 12
13 13 $ cp $HGRCPATH $HGRCPATH.orig
14 14
15 15 Create repo with unimpeachable content
16 16
17 17 $ hg init r
18 18 $ cd r
19 19 $ echo 'Initially untainted file' > target
20 20 $ echo 'Normal file here' > bystander
21 21 $ hg add target bystander
22 22 $ hg ci -m init
23 23
24 24 Clone repo so we can test pull later
25 25
26 26 $ cd ..
27 27 $ hg clone r rpull
28 28 updating to branch default
29 29 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 30 $ cd r
31 31
32 32 Introduce content which will ultimately require censorship. Name the first
33 33 censored node C1, second C2, and so on
34 34
35 35 $ echo 'Tainted file' > target
36 36 $ echo 'Passwords: hunter2' >> target
37 37 $ hg ci -m taint target
38 38 $ C1=`hg id --debug -i`
39 39
40 40 $ echo 'hunter3' >> target
41 41 $ echo 'Normal file v2' > bystander
42 42 $ hg ci -m moretaint target bystander
43 43 $ C2=`hg id --debug -i`
44 44
45 45 Add a new sanitized versions to correct our mistake. Name the first head H1,
46 46 the second head H2, and so on
47 47
48 48 $ echo 'Tainted file is now sanitized' > target
49 49 $ hg ci -m sanitized target
50 50 $ H1=`hg id --debug -i`
51 51
52 52 $ hg update -r $C2
53 53 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 54 $ echo 'Tainted file now super sanitized' > target
55 55 $ hg ci -m 'super sanitized' target
56 56 created new head
57 57 $ H2=`hg id --debug -i`
58 58
59 59 Verify target contents before censorship at each revision
60 60
61 61 $ hg cat -r $H1 target | head -n 10
62 62 Tainted file is now sanitized
63 63 $ hg cat -r $H2 target | head -n 10
64 64 Tainted file now super sanitized
65 65 $ hg cat -r $C2 target | head -n 10
66 66 Tainted file
67 67 Passwords: hunter2
68 68 hunter3
69 69 $ hg cat -r $C1 target | head -n 10
70 70 Tainted file
71 71 Passwords: hunter2
72 72 $ hg cat -r 0 target | head -n 10
73 73 Initially untainted file
74 74
75 75 Censor revision with 2 offenses
76 76
77 77 (this also tests file pattern matching: path relative to cwd case)
78 78
79 79 $ mkdir -p foo/bar/baz
80 80 $ hg --config extensions.censor= --cwd foo/bar/baz censor -r $C2 -t "remove password" ../../../target
81 81 $ hg cat -r $H1 target | head -n 10
82 82 Tainted file is now sanitized
83 83 $ hg cat -r $H2 target | head -n 10
84 84 Tainted file now super sanitized
85 85 $ hg cat -r $C2 target | head -n 10
86 86 abort: censored node: 1e0247a9a4b7
87 87 (set censor.policy to ignore errors)
88 88 $ hg cat -r $C1 target | head -n 10
89 89 Tainted file
90 90 Passwords: hunter2
91 91 $ hg cat -r 0 target | head -n 10
92 92 Initially untainted file
93 93
94 94 Censor revision with 1 offense
95 95
96 96 (this also tests file pattern matching: with 'path:' scheme)
97 97
98 98 $ hg --config extensions.censor= --cwd foo/bar/baz censor -r $C1 path:target
99 99 $ hg cat -r $H1 target | head -n 10
100 100 Tainted file is now sanitized
101 101 $ hg cat -r $H2 target | head -n 10
102 102 Tainted file now super sanitized
103 103 $ hg cat -r $C2 target | head -n 10
104 104 abort: censored node: 1e0247a9a4b7
105 105 (set censor.policy to ignore errors)
106 106 $ hg cat -r $C1 target | head -n 10
107 107 abort: censored node: 613bc869fceb
108 108 (set censor.policy to ignore errors)
109 109 $ hg cat -r 0 target | head -n 10
110 110 Initially untainted file
111 111
112 112 Can only checkout target at uncensored revisions, -X is workaround for --all
113 113
114 114 $ hg revert -r $C2 target | head -n 10
115 115 abort: censored node: 1e0247a9a4b7
116 116 (set censor.policy to ignore errors)
117 117 $ hg revert -r $C1 target | head -n 10
118 118 abort: censored node: 613bc869fceb
119 119 (set censor.policy to ignore errors)
120 120 $ hg revert -r $C1 --all
121 121 reverting bystander
122 122 reverting target
123 123 abort: censored node: 613bc869fceb
124 124 (set censor.policy to ignore errors)
125 125 [255]
126 126 $ hg revert -r $C1 --all -X target
127 127 $ cat target | head -n 10
128 128 Tainted file now super sanitized
129 129 $ hg revert -r 0 --all
130 130 reverting target
131 131 $ cat target | head -n 10
132 132 Initially untainted file
133 133 $ hg revert -r $H2 --all
134 134 reverting bystander
135 135 reverting target
136 136 $ cat target | head -n 10
137 137 Tainted file now super sanitized
138 138
139 139 Uncensored file can be viewed at any revision
140 140
141 141 $ hg cat -r $H1 bystander | head -n 10
142 142 Normal file v2
143 143 $ hg cat -r $C2 bystander | head -n 10
144 144 Normal file v2
145 145 $ hg cat -r $C1 bystander | head -n 10
146 146 Normal file here
147 147 $ hg cat -r 0 bystander | head -n 10
148 148 Normal file here
149 149
150 150 Can update to children of censored revision
151 151
152 152 $ hg update -r $H1
153 153 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 154 $ cat target | head -n 10
155 155 Tainted file is now sanitized
156 156 $ hg update -r $H2
157 157 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
158 158 $ cat target | head -n 10
159 159 Tainted file now super sanitized
160 160
161 161 Set censor policy to abort in trusted $HGRC so hg verify fails
162 162
163 163 $ cp $HGRCPATH.orig $HGRCPATH
164 164 $ cat >> $HGRCPATH <<EOF
165 165 > [censor]
166 166 > policy = abort
167 167 > EOF
168 168
169 169 Repo fails verification due to censorship
170 170
171 171 $ hg verify
172 172 checking changesets
173 173 checking manifests
174 174 crosschecking files in changesets and manifests
175 175 checking files
176 176 target@1: censored file data
177 177 target@2: censored file data
178 178 not checking dirstate because of previous errors
179 179 checked 5 changesets with 7 changes to 2 files
180 180 2 integrity errors encountered!
181 181 (first damaged changeset appears to be 1)
182 182 [1]
183 183
184 184 Cannot update to revision with censored data
185 185
186 186 $ hg update -r $C2
187 187 abort: censored node: 1e0247a9a4b7
188 188 (set censor.policy to ignore errors)
189 189 [255]
190 190 $ hg update -r $C1
191 191 abort: censored node: 613bc869fceb
192 192 (set censor.policy to ignore errors)
193 193 [255]
194 194 $ hg update -r 0
195 195 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 196 $ hg update -r $H2
197 197 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 198
199 199 Set censor policy to ignore in trusted $HGRC so hg verify passes
200 200
201 201 $ cp $HGRCPATH.orig $HGRCPATH
202 202 $ cat >> $HGRCPATH <<EOF
203 203 > [censor]
204 204 > policy = ignore
205 205 > EOF
206 206
207 207 Repo passes verification with warnings with explicit config
208 208
209 209 $ hg verify -q
210 210
211 211 May update to revision with censored data with explicit config
212 212
213 213 $ hg update -r $C2
214 214 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 215 $ cat target | head -n 10
216 216 $ hg update -r $C1
217 217 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
218 218 $ cat target | head -n 10
219 219 $ hg update -r 0
220 220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 221 $ cat target | head -n 10
222 222 Initially untainted file
223 223 $ hg update -r $H2
224 224 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 225 $ cat target | head -n 10
226 226 Tainted file now super sanitized
227 227
228 228 Can merge in revision with censored data. Test requires one branch of history
229 229 with the file censored, but we can't censor at a head, so advance H1.
230 230
231 231 $ hg update -r $H1
232 232 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 233 $ C3=$H1
234 234 $ echo 'advanced head H1' > target
235 235 $ hg ci -m 'advance head H1' target
236 236 $ H1=`hg id --debug -i`
237 237 $ hg --config extensions.censor= censor -r $C3 target
238 238 $ hg update -r $H2
239 239 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 240 $ hg merge -r $C3
241 241 merging target
242 242 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
243 243 (branch merge, don't forget to commit)
244 244
245 245 Revisions present in repository heads may not be censored
246 246
247 247 $ hg update -C -r $H2
248 248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
249 249 $ hg --config extensions.censor= censor -r $H2 target
250 250 abort: cannot censor file in heads (78a8fc215e79)
251 251 (clean/delete and commit first)
252 252 [255]
253 253 $ echo 'twiddling thumbs' > bystander
254 254 $ hg ci -m 'bystander commit'
255 255 $ H2=`hg id --debug -i`
256 256 $ hg --config extensions.censor= censor -r "$H2^" target
257 257 abort: cannot censor file in heads (efbe78065929)
258 258 (clean/delete and commit first)
259 259 [255]
260 260
261 261 Cannot censor working directory
262 262
263 263 $ echo 'seriously no passwords' > target
264 264 $ hg ci -m 'extend second head arbitrarily' target
265 265 $ H2=`hg id --debug -i`
266 266 $ hg update -r "$H2^"
267 267 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 268 $ hg --config extensions.censor= censor -r . target
269 269 abort: cannot censor working directory
270 270 (clean/delete/update first)
271 271 [255]
272 272 $ hg update -r $H2
273 273 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 274
275 275 Can re-add file after being deleted + censored
276 276
277 277 $ C4=$H2
278 278 $ hg rm target
279 279 $ hg ci -m 'delete target so it may be censored'
280 280 $ H2=`hg id --debug -i`
281 281 $ hg --config extensions.censor= censor -r $C4 target
282 282 $ hg cat -r $C4 target | head -n 10
283 283 $ hg cat -r "$H2^^" target | head -n 10
284 284 Tainted file now super sanitized
285 285 $ echo 'fresh start' > target
286 286 $ hg add target
287 287 $ hg ci -m reincarnated target
288 288 $ H2=`hg id --debug -i`
289 289 $ hg cat -r $H2 target | head -n 10
290 290 fresh start
291 291 $ hg cat -r "$H2^" target | head -n 10
292 292 target: no such file in rev 452ec1762369
293 293 $ hg cat -r $C4 target | head -n 10
294 294 $ hg cat -r "$H2^^^" target | head -n 10
295 295 Tainted file now super sanitized
296 296
297 297 Can censor enough revision to move back to inline storage
298 298
299 299 $ hg debugrevlogstats | grep target
300 300 rev-count data-size inl type target
301 301 8 ??? no file target (glob) (revlogv2 !)
302 302 8 ??? yes file target (glob) (revlogv1 !)
303 $ cat /dev/rand?m | dd status=none count=200 | f --hexdump > target
303 $ cat /dev/rand?m | dd bs=512 count=200 2> /dev/null | f --hexdump > target
304 304 $ hg ci -m 'add 100k passwords'
305 305 $ H2=`hg id --debug -i`
306 306 $ C5=$H2
307 307 $ hg revert -r "$H2^" target
308 308 $ hg ci -m 'cleaned 100k passwords'
309 309 $ H2=`hg id --debug -i`
310 310 $ hg debugrevlogstats | grep target
311 311 rev-count data-size inl type target
312 312 10 ?????? no file target (glob)
313 313 $ hg --config extensions.censor= censor -r $C5 target
314 314
315 315 The important part is for the censor operation to not crash and the repository
316 316 to not be corrupted. Right now this involve keeping the revlog split.
317 317
318 318 $ hg debugrevlogstats | grep target
319 319 rev-count data-size inl type target
320 320 10 ??? no file target (glob)
321 321 $ hg cat -r $C5 target | head -n 10
322 322 $ hg cat -r $H2 target | head -n 10
323 323 fresh start
324 324 $ hg verify
325 325 checking changesets
326 326 checking manifests
327 327 crosschecking files in changesets and manifests
328 328 checking files
329 329 checking dirstate
330 330 checked 12 changesets with 13 changes to 2 files
331 331
332 332 Repo with censored nodes can be cloned and cloned nodes are censored
333 333
334 334 $ cd ..
335 335 $ hg clone r rclone
336 336 updating to branch default
337 337 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
338 338 $ cd rclone
339 339 $ hg cat -r $H1 target | head -n 10
340 340 advanced head H1
341 341 $ hg cat -r $H2~5 target | head -n 10
342 342 Tainted file now super sanitized
343 343 $ hg cat -r $C2 target | head -n 10
344 344 $ hg cat -r $C1 target | head -n 10
345 345 $ hg cat -r 0 target | head -n 10
346 346 Initially untainted file
347 347 $ hg verify -q
348 348
349 349 Repo cloned before tainted content introduced can pull censored nodes
350 350
351 351 $ cd ../rpull
352 352 $ hg cat -r tip target | head -n 10
353 353 Initially untainted file
354 354 $ hg verify -q
355 355 $ hg pull -r $H1 -r $H2
356 356 pulling from $TESTTMP/r
357 357 searching for changes
358 358 adding changesets
359 359 adding manifests
360 360 adding file changes
361 361 added 11 changesets with 11 changes to 2 files (+1 heads)
362 362 new changesets * (glob)
363 363 (run 'hg heads' to see heads, 'hg merge' to merge)
364 364 $ hg update 4
365 365 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
366 366 $ cat target | head -n 10
367 367 Tainted file now super sanitized
368 368 $ hg cat -r $H1 target | head -n 10
369 369 advanced head H1
370 370 $ hg cat -r $H2~5 target | head -n 10
371 371 Tainted file now super sanitized
372 372 $ hg cat -r $C2 target | head -n 10
373 373 $ hg cat -r $C1 target | head -n 10
374 374 $ hg cat -r 0 target | head -n 10
375 375 Initially untainted file
376 376 $ hg verify -q
377 377
378 378 Censored nodes can be pushed if they censor previously unexchanged nodes
379 379
380 380 $ echo 'Passwords: hunter2hunter2' > target
381 381 $ hg ci -m 're-add password from clone' target
382 382 created new head
383 383 $ H3=`hg id --debug -i`
384 384 $ REV=$H3
385 385 $ echo 'Re-sanitized; nothing to see here' > target
386 386 $ hg ci -m 're-sanitized' target
387 387 $ H2=`hg id --debug -i`
388 388 $ CLEANREV=$H2
389 389 $ hg cat -r $REV target | head -n 10
390 390 Passwords: hunter2hunter2
391 391 $ hg --config extensions.censor= censor -r $REV target
392 392 $ hg cat -r $REV target | head -n 10
393 393 $ hg cat -r $CLEANREV target | head -n 10
394 394 Re-sanitized; nothing to see here
395 395 $ hg push -f -r $H2
396 396 pushing to $TESTTMP/r
397 397 searching for changes
398 398 adding changesets
399 399 adding manifests
400 400 adding file changes
401 401 added 2 changesets with 2 changes to 1 files (+1 heads)
402 402
403 403 $ cd ../r
404 404 $ hg cat -r $REV target | head -n 10
405 405 $ hg cat -r $CLEANREV target | head -n 10
406 406 Re-sanitized; nothing to see here
407 407 $ hg update $CLEANREV
408 408 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
409 409 $ cat target | head -n 10
410 410 Re-sanitized; nothing to see here
411 411
412 412 Censored nodes can be bundled up and unbundled in another repo
413 413
414 414 $ hg bundle --base 0 ../pwbundle
415 415 13 changesets found
416 416 $ cd ../rclone
417 417 $ hg unbundle ../pwbundle
418 418 adding changesets
419 419 adding manifests
420 420 adding file changes
421 421 added 2 changesets with 2 changes to 2 files (+1 heads)
422 422 new changesets * (glob)
423 423 (run 'hg heads .' to see heads, 'hg merge' to merge)
424 424 $ hg cat -r $REV target | head -n 10
425 425 $ hg cat -r $CLEANREV target | head -n 10
426 426 Re-sanitized; nothing to see here
427 427 $ hg update $CLEANREV
428 428 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
429 429 $ cat target | head -n 10
430 430 Re-sanitized; nothing to see here
431 431 $ hg verify -q
432 432
433 433 Grepping only warns, doesn't error out
434 434
435 435 $ cd ../rpull
436 436 $ hg grep 'Normal file'
437 437 bystander:Normal file v2
438 438 $ hg grep nothing
439 439 target:Re-sanitized; nothing to see here
440 440 $ hg grep --diff 'Normal file'
441 441 cannot search in censored file: target:7
442 442 cannot search in censored file: target:10
443 443 cannot search in censored file: target:12
444 444 bystander:6:-:Normal file v2
445 445 cannot search in censored file: target:1
446 446 cannot search in censored file: target:2
447 447 cannot search in censored file: target:3
448 448 bystander:2:-:Normal file here
449 449 bystander:2:+:Normal file v2
450 450 bystander:0:+:Normal file here
451 451 $ hg grep --diff nothing
452 452 cannot search in censored file: target:7
453 453 cannot search in censored file: target:10
454 454 cannot search in censored file: target:12
455 455 target:13:+:Re-sanitized; nothing to see here
456 456 cannot search in censored file: target:1
457 457 cannot search in censored file: target:2
458 458 cannot search in censored file: target:3
459 459
460 460 Censored nodes can be imported on top of censored nodes, consecutively
461 461
462 462 $ hg init ../rimport
463 463 $ hg bundle --base 1 ../rimport/splitbundle
464 464 12 changesets found
465 465 $ cd ../rimport
466 466 $ hg pull -r $H1 -r $H2 ../r
467 467 pulling from ../r
468 468 adding changesets
469 469 adding manifests
470 470 adding file changes
471 471 added 8 changesets with 10 changes to 2 files (+1 heads)
472 472 new changesets e97f55b2665a:dcbaf17bf3a1
473 473 (run 'hg heads' to see heads, 'hg merge' to merge)
474 474 $ hg unbundle splitbundle
475 475 adding changesets
476 476 adding manifests
477 477 adding file changes
478 478 added 6 changesets with 5 changes to 2 files (+1 heads)
479 479 new changesets * (glob)
480 480 (run 'hg heads .' to see heads, 'hg merge' to merge)
481 481 $ hg update $H2
482 482 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
483 483 $ cat target | head -n 10
484 484 Re-sanitized; nothing to see here
485 485 $ hg verify -q
486 486 $ cd ../r
487 487
488 488 Can import bundle where first revision of a file is censored
489 489
490 490 $ hg init ../rinit
491 491 $ hg --config extensions.censor= censor -r 0 target
492 492 $ hg bundle -r 0 --base null ../rinit/initbundle
493 493 1 changesets found
494 494 $ cd ../rinit
495 495 $ hg unbundle initbundle
496 496 adding changesets
497 497 adding manifests
498 498 adding file changes
499 499 added 1 changesets with 2 changes to 2 files
500 500 new changesets e97f55b2665a (1 drafts)
501 501 (run 'hg update' to get a working copy)
502 502 $ hg cat -r 0 target | head -n 10
503 503
504 504 #if revlogv2
505 505
506 506 Testing feature that does not work in revlog v1
507 507 ===============================================
508 508
509 509 Censoring a revision that is used as delta base
510 510 -----------------------------------------------
511 511
512 512 $ cd ..
513 513 $ hg init censor-with-delta
514 514 $ cd censor-with-delta
515 515 $ echo root > target
516 516 $ hg add target
517 517 $ hg commit -m root
518 518 $ B0=`hg id --debug -i`
519 519 $ for x in `"$PYTHON" $TESTDIR/seq.py 0 50000`
520 520 > do
521 521 > echo "Password: hunter$x" >> target
522 522 > done
523 523 $ hg ci -m 'write a long file'
524 524 $ B1=`hg id --debug -i`
525 525 $ echo 'small change (should create a delta)' >> target
526 526 $ hg ci -m 'create a delta over the password'
527 527 (should show that the last revision is a delta, not a snapshot)
528 528 $ B2=`hg id --debug -i`
529 529
530 530 Make sure the last revision is a delta against the revision we will censor
531 531
532 532 $ hg debugdeltachain target -T '{rev} {chainid} {chainlen} {prevrev}\n'
533 533 0 1 1 -1
534 534 1 2 1 -1
535 535 2 2 2 1
536 536
537 537 Censor the file
538 538
539 539 $ hg cat -r $B1 target | wc -l
540 540 *50002 (re)
541 541 $ hg --config extensions.censor= censor -r $B1 target
542 542 $ hg cat -r $B1 target | wc -l
543 543 *0 (re)
544 544
545 545 Check the children is fine
546 546
547 547 $ hg cat -r $B2 target | wc -l
548 548 *50003 (re)
549 549
550 550 #endif
551 551
552 552 Testing repository upgrade with censors revision
553 553 ================================================
554 554
555 555 $ cd ../rclone
556 556
557 557 With the "abort" policy
558 558 =======================
559 559
560 560 $ hg verify --config censor.policy=ignore
561 561 checking changesets
562 562 checking manifests
563 563 crosschecking files in changesets and manifests
564 564 checking files
565 565 checking dirstate
566 566 checked 14 changesets with 15 changes to 2 files
567 567 $ hg debugupgraderepo --run --quiet \
568 568 > --optimize re-delta-parent \
569 569 > --config censor.policy=abort
570 570 upgrade will perform the following actions:
571 571
572 572 requirements
573 573 preserved: * (glob)
574 574
575 575 optimisations: re-delta-parent
576 576
577 577 processed revlogs:
578 578 - all-filelogs
579 579 - changelog
580 580 - manifest
581 581
582 582 $ hg verify --config censor.policy=ignore
583 583 checking changesets
584 584 checking manifests
585 585 crosschecking files in changesets and manifests
586 586 checking files
587 587 checking dirstate
588 588 checked 14 changesets with 15 changes to 2 files
589 589
590 590 With the "ignore" policy
591 591 ========================
592 592
593 593 $ hg verify --config censor.policy=ignore
594 594 checking changesets
595 595 checking manifests
596 596 crosschecking files in changesets and manifests
597 597 checking files
598 598 checking dirstate
599 599 checked 14 changesets with 15 changes to 2 files
600 600 $ hg debugupgraderepo --run --quiet \
601 601 > --optimize re-delta-parent \
602 602 > --config censor.policy=ignore
603 603 upgrade will perform the following actions:
604 604
605 605 requirements
606 606 preserved: * (glob)
607 607
608 608 optimisations: re-delta-parent
609 609
610 610 processed revlogs:
611 611 - all-filelogs
612 612 - changelog
613 613 - manifest
614 614
615 615 $ hg verify --config censor.policy=ignore
616 616 checking changesets
617 617 checking manifests
618 618 crosschecking files in changesets and manifests
619 619 checking files
620 620 checking dirstate
621 621 checked 14 changesets with 15 changes to 2 files
General Comments 1
Approved

Status change > Approved

You need to be logged in to leave comments. Login now