package io.jenkins.blueocean.service.embedded;

import hudson.model.FreeStyleProject;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.model.Run;
import hudson.security.GlobalMatrixAuthorizationStrategy;
import hudson.security.HudsonPrivateSecurityRealm;
import hudson.tasks.ArtifactArchiver;
import hudson.tasks.Shell;
import org.junit.Assert;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;

import java.util.List;
import java.util.Map;

public class ArtifactsSecurity564 extends BaseTest {
    static {
        System.setProperty("hudson.security.ArtifactsPermission", "true");
    }

    /**
     * Uses matrix-auth to provide artifacts permission.
     *
     * If hudson.security.ArtifactsPermission is set then the user must have Run.ARTIFACTS set.
     * 
     * @throws Exception
     */
    @Issue("SECURITY-564")
    @Test
    public void testArtifactsWithPermissions() throws Exception {
        String JOB_NAME = "artifactPermissions";
        HudsonPrivateSecurityRealm realm = new HudsonPrivateSecurityRealm(false);
        realm.createAccount("alice","alice");
        realm.createAccount("bob","bob");
        j.jenkins.setSecurityRealm(realm);

        GlobalMatrixAuthorizationStrategy as = new GlobalMatrixAuthorizationStrategy();
        j.jenkins.setAuthorizationStrategy(as);
        as.add(Hudson.READ,"alice");
        as.add(Item.READ,"alice");
        as.add(Run.ARTIFACTS,"alice");

        as.add(Hudson.READ,"bob");
        as.add(Item.READ,"bob");

        FreeStyleProject p = j.createFreeStyleProject(JOB_NAME);
        p.getBuildersList().add(new Shell("#!/bin/bash\nmkdir -p test/me/out; cd test/me/out; touch {0..105}.txt"));
        p.getPublishersList().add(new ArtifactArchiver("**/*"));
        Run r = p.scheduleBuild2(0).waitForStart();

        r = j.waitForCompletion(r);

        List artifacts = request().authAlice().get("/organizations/jenkins/pipelines/"+JOB_NAME+"/runs/"+r.getId()+"/artifacts").build(List.class);

        Assert.assertEquals(100, artifacts.size());
        Assert.assertEquals(0, ((Map) artifacts.get(0)).get("size"));
        Assert.assertEquals("test/me/out/0.txt", ((Map) artifacts.get(0)).get("path"));
        Assert.assertEquals("/job/artifactPermissions/1/artifact/test/me/out/0.txt", ((Map) artifacts.get(0)).get("url"));

        List artifactsBob = request().auth("bob", "bob").get("/organizations/jenkins/pipelines/"+JOB_NAME+"/runs/"+r.getId()+"/artifacts").build(List.class);

        Assert.assertEquals(0, artifactsBob.size());
    }

}

@@ -41,16 +41,161 @@
 edded;%0A%0A
+import hudson.FilePath;%0Aimport hudson.Launcher;%0Aimport hudson.model.AbstractBuild;%0Aimport hudson.model.Build;%0Aimport hudson.model.BuildListener;%0A
 import h
@@ -474,99 +474,353 @@
 sks.
-Shell;%0Aimport org.junit.Assert;%0Aimport org.junit.Test;%0Aimport org.jvnet.hudson.test.Issue;%0A
+Builder;%0Aimport hudson.tasks.Shell;%0Aimport org.junit.AfterClass;%0Aimport org.junit.Assert;%0Aimport org.junit.BeforeClass;%0Aimport org.junit.Test;%0Aimport org.jvnet.hudson.test.Issue;%0Aimport org.jvnet.hudson.test.TouchBuilder;%0A%0Aimport java.io.FileNotFoundException;%0Aimport java.io.IOException;%0Aimport java.io.Serializable;%0Aimport java.net.URLEncoder;
 %0Aimp
@@ -923,14 +923,57 @@
     
-static
+@BeforeClass%0A    public static void beforeClass()
  %7B%0A 
@@ -1053,16 +1053,153 @@
 %0A    %7D%0A%0A
+    @AfterClass%0A    public static void afterClass() %7B%0A        System.setProperty(%22hudson.security.ArtifactsPermission%22, %22false%22);%0A    %7D%0A%0A
     /**%0A
@@ -1364,17 +1364,16 @@
 .%0A     *
- 
 %0A     * 
@@ -1550,16 +1550,54 @@
 sions%22;%0A
+        String artfictPath = %22a/b/c%22;%0A
         
@@ -2045,25 +2045,24 @@
 S,%22alice%22);%0A
-%0A
         as.a
@@ -2223,85 +2223,40 @@
 new 
-Shell(%22#!/bin/bash%5Cnmkdir -p test/me/out; cd test/me/out; touch %7B0..105%7D.txt%22
+ArtifactBuilder(artfictPath, 100
 ));%0A
@@ -2713,20 +2713,23 @@
 als(
-%22test/me/out
+artfictPath + %22
 /0.t
@@ -2841,19 +2841,25 @@
 act/
-test/me/out
+%22+ artfictPath +%22
 /0.t
@@ -3121,10 +3121,753 @@
 %0A    %7D%0A%0A
+    public static class ArtifactBuilder extends Builder implements Serializable %7B%0A        private String path;%0A        private int numberOfFiles;%0A%0A        public ArtifactBuilder(String path, int numberOfFiles) %7B%0A            this.path = path;%0A            this.numberOfFiles = numberOfFiles;%0A        %7D%0A%0A        @Override%0A        public boolean perform(AbstractBuild%3C?, ?%3E build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException %7B%0A            FilePath f = new FilePath(build.getWorkspace(), path);%0A            f.mkdirs();%0A            for (int i = 0; i %3C numberOfFiles; i++) %7B%0A                new FilePath(f, i + %22.txt%22).touch(System.currentTimeMillis());%0A            %7D%0A%0A            return true;%0A        %7D%0A    %7D%0A
 %7D%0A

Use a custom builder to generate files to archive