[Laravel 5] Upload artifact van build-server

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 11-09 20:27

Matis

Rubber Rocket

Topicstarter
Beste PRGers,

Ik heb een interne website (restfull) in Laravel 5.1 gebouwd waar onze medewerkers de artifacts van onze buildservers (Jenkins) kunnen uploaden.
Momenteel gaat dit nog handmatig. Het zou veel fijner zijn wanneer we dat zouden kunnen automatiseren.

Helaas is er geen (bruikbare) plugin voor Jenkins waarmee ik een artifact kan uploaden middels HTTP Post. Dus heb ik een eenvoudig PHP script gemaakt dat dat zou moeten realiseren.

PHP:
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
<?php
$host = 'http://localhost:8081';

$shortopts = "";
$shortopts .= "p:"; // Project ID
$shortopts .= "v:"; // Version ID
$shortopts .= "b:"; // File to upload
$shortopts .= "d:"; // Description

$options = getopt($shortopts);
var_dump($options);

if (sizeof($options) !== 4)
{
    die("Please provide 4 arguments");
}

$pid = (int)$options['p'];
$vid = (int)$options['v'];
$blob = realpath($options['b']);
if ($blob === false)
{
    die("File not found: " . $options['b']);
}

$description = $options['d'];

$url = sprintf('%s/project/%d/version/%d/blob/create', $host, $pid, $vid);
$fields = array(
    'blob_name' => '@'.$blob,
    'blob_preferred' => false,
    'blob_desc' => $description,
    '_token' => 'hier moet iets komen',
);

var_dump($fields);

$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

//execute post
$result = curl_exec($ch);

//close connection
curl_close($ch);

// Dump result for debugging purpose
echo $result;


Zoals verwacht krijg ik een TokenMismatchException.

Het is een inhouse website, de gebruikers hoeven zichzelf niet eens te registeren / inloggen om artifacten op te slaan.
Hoe kan ik er voor zorgen dat Jenkins de artifacten kan uploaden in acht nemende de anti-CSRF maatregelen, of is het (aangezien het inhouse-only is) ook goed genoeg om de hele CSRF uit te schakelen?

Alvast bedankt voor jullie reactie!

Matis

If money talks then I'm a mime
If time is money then I'm out of time

Beste antwoord (via Matis op 29-03-2016 15:25)


  • TJVB
  • Registratie: Januari 2008
  • Laatst online: 10-09 10:37
Het gebruik van anti-CSRF betekent dat je een sessie moet starten waarvan je het token krijgt en in die sessie de post aanroep uitvoert.

Het uitschakelen kan op 3 manieren.
  1. In VerifyCsrfToken (app/Http/Middleware/VerifyCsrfToken.php) kun je de url toevoegen bij except om die call toe te staan zonder token.)
  2. In VerifyCsrfToken (app/Http/Middleware/VerifyCsrfToken.php) overschrijf je de functie shouldPassThrough. (Die erft die van Illuminate\Foundation\Http\Middleware\VerifyCsrfToken ) en daarin zorg je dat het verkeer van je Jenkins installatie het recht heeft om te posten zonder token.
  3. De 3e en minst aan te raden optie is het verwijderen van \App\Http\Middleware\VerifyCsrfToken::class, uit app/Http/Kernel.php

Alle reacties


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • TJVB
  • Registratie: Januari 2008
  • Laatst online: 10-09 10:37
Het gebruik van anti-CSRF betekent dat je een sessie moet starten waarvan je het token krijgt en in die sessie de post aanroep uitvoert.

Het uitschakelen kan op 3 manieren.
  1. In VerifyCsrfToken (app/Http/Middleware/VerifyCsrfToken.php) kun je de url toevoegen bij except om die call toe te staan zonder token.)
  2. In VerifyCsrfToken (app/Http/Middleware/VerifyCsrfToken.php) overschrijf je de functie shouldPassThrough. (Die erft die van Illuminate\Foundation\Http\Middleware\VerifyCsrfToken ) en daarin zorg je dat het verkeer van je Jenkins installatie het recht heeft om te posten zonder token.
  3. De 3e en minst aan te raden optie is het verwijderen van \App\Http\Middleware\VerifyCsrfToken::class, uit app/Http/Kernel.php

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 11-09 20:27

Matis

Rubber Rocket

Topicstarter
Thnx voor je reactie. Aangezien ik een specifieke server (IP) wil toestaan, heb ik gekozen voor optie 2. Ik heb de volgende regels toegevoegd aan de door jou aangegeven klasse:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected $except_ips = [
        //'127.0.0.1',    // localhost
        '10.1.0.100',   // jenkins
    ];

    protected function shouldPassThrough($request)
    {
        $clientIp = $request->getClientIp();
        foreach ($this->except_ips as $except_ip)
        {
            if ($clientIp === $except_ip)
            {
                return true;
            }
        }
        return parent::shouldPassThrough($request);
    }


Wanneer ik in de toekomst een extra IP-adres wil white listen, dan kan hoef ik alleen maar het adres toe te voegen aan de array :D

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • TJVB
  • Registratie: Januari 2008
  • Laatst online: 10-09 10:37
Je zou regel 9 t/m 15 nog kunnen vervangen met:
PHP:
1
2
3
if (in_array($clientIp, $this->except_ips)) {
    return true;
}

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 11-09 20:27

Matis

Rubber Rocket

Topicstarter
Klopt, dat kan ook, maar dan wel met de strict vlag aan.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Kun je niet gewoon vanuit de Laravel app een formulier maken ipv met een extern script te werken, die een artifact importeerd?

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 11-09 20:27

Matis

Rubber Rocket

Topicstarter
Volgens mij begrijp ik je niet goed.

Momenteel heb ik een formulier waarmee mijn collega's handmatig een artifact kunnen uploaden.
Ik wil juist dat het geautomatiseerd na iedere build gebeurd. Derhalve heb ik een script op de buildserver staan welke de artifact (inclusief meta-data) upload, via dezelfde store-functie als dat de gebruiker dat via het form zou doen.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Matis schreef op woensdag 30 maart 2016 @ 21:51:
Volgens mij begrijp ik je niet goed.

Momenteel heb ik een formulier waarmee mijn collega's handmatig een artifact kunnen uploaden.
Ik wil juist dat het geautomatiseerd na iedere build gebeurd. Derhalve heb ik een script op de buildserver staan welke de artifact (inclusief meta-data) upload, via dezelfde store-functie als dat de gebruiker dat via het form zou doen.
Dat formulier kun je dan toch ook in Laravel zelf maken? :) Dan heb je automatisch namelijk ook CSRF protectie. Of eventueel middels een API? Lijkt mij veel handiger om het via een API te doen dan met een formulier?

[ Voor 8% gewijzigd door CH4OS op 31-03-2016 00:19 ]


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 11-09 20:27

Matis

Rubber Rocket

Topicstarter
CptChaos schreef op woensdag 30 maart 2016 @ 23:48:
Dat formulier kun je dan toch ook in Laravel zelf maken? :) Dan heb je automatisch namelijk ook CSRF protectie. Of eventueel middels een API? Lijkt mij veel handiger om het via een API te doen dan met een formulier?
Ik begrijp nu onze spraakverwarring :)

Het formulier waarmee mijn collega's hun artifacts uploaden is al onderdeel van de Laravel-website, inclusief
HTML:
1
    <input type="hidden" name="_token" value="{{ csrf_token() }}">

Echter kan (of lukt het mij althans niet) om Jenkins ook via dat formulier te laten uploaden.
Dus heb ik de csrf-protectie uitgeschakeld voor dat specifieke IP-adres en direct een POST-functie op de store-route van de controller gedaan.

[ Voor 4% gewijzigd door Matis op 02-04-2016 13:17 ]

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Hmmm... Krijgt Jenkins dan wel een sessie? Want het CSRF-token wordt daar wel aan gekoppeld. :)

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 11-09 20:27

Matis

Rubber Rocket

Topicstarter
Nee, dat krijg Jenkins inderdaad niet. Ik ga kijken of ik middels curl of anders Guzzle een sessie + csrf_token kan verkrijgen.

Ik heb al wat leeswerk: http://stackoverflow.com/...009/guzzle-add-csrf-token en ik heb al wel eens vaker met Guzzle gewerkt, maar dat was meer om in te loggen en dan een specifieke GET-operatie te doen (icm Goutte).
Ik heb nog nooit eerder een POST-functie geschreven icm sessie / csrf_token.

If money talks then I'm a mime
If time is money then I'm out of time

Pagina: 1