Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
LinuxSuRen
jenkins
提交
af09aaea
J
jenkins
项目概览
LinuxSuRen
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
af09aaea
编写于
2月 12, 2019
作者:
J
Jesse Glick
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into remotingCLI
上级
9c80cf12
31ee211e
变更
57
隐藏空白更改
内联
并排
Showing
57 changed file
with
746 addition
and
446 deletion
+746
-446
Jenkinsfile
Jenkinsfile
+1
-1
core/pom.xml
core/pom.xml
+1
-1
core/src/main/java/hudson/FilePath.java
core/src/main/java/hudson/FilePath.java
+5
-1
core/src/main/java/hudson/PluginWrapper.java
core/src/main/java/hudson/PluginWrapper.java
+3
-2
core/src/main/java/hudson/model/DirectoryBrowserSupport.java
core/src/main/java/hudson/model/DirectoryBrowserSupport.java
+73
-26
core/src/main/java/hudson/model/UpdateCenter.java
core/src/main/java/hudson/model/UpdateCenter.java
+1
-8
core/src/main/java/hudson/model/UpdateSite.java
core/src/main/java/hudson/model/UpdateSite.java
+3
-2
core/src/main/java/hudson/node_monitors/AbstractDiskSpaceMonitor.java
...n/java/hudson/node_monitors/AbstractDiskSpaceMonitor.java
+2
-2
core/src/main/java/hudson/util/DirScanner.java
core/src/main/java/hudson/util/DirScanner.java
+56
-0
core/src/main/java/jenkins/plugins/DetachedPluginsUtil.java
core/src/main/java/jenkins/plugins/DetachedPluginsUtil.java
+4
-3
core/src/main/java/jenkins/util/VirtualFile.java
core/src/main/java/jenkins/util/VirtualFile.java
+138
-14
core/src/main/java/jenkins/util/java/JavaUtils.java
core/src/main/java/jenkins/util/java/JavaUtils.java
+3
-2
core/src/main/resources/jenkins/model/Messages_es_AR.properties
...rc/main/resources/jenkins/model/Messages_es_AR.properties
+1
-1
core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly
...urces/jenkins/security/s2m/AdminWhitelistRule/index.jelly
+2
-2
core/src/test/java/hudson/FilePathSEC904Test.java
core/src/test/java/hudson/FilePathSEC904Test.java
+4
-4
core/src/test/java/jenkins/util/VirtualFileSEC904Test.java
core/src/test/java/jenkins/util/VirtualFileSEC904Test.java
+102
-1
pom.xml
pom.xml
+3
-3
test-pom/pom.xml
test-pom/pom.xml
+1
-1
test/src/test/java/hudson/AboutJenkinsTest.java
test/src/test/java/hudson/AboutJenkinsTest.java
+6
-4
test/src/test/java/hudson/TcpSlaveAgentListenerTest.java
test/src/test/java/hudson/TcpSlaveAgentListenerTest.java
+16
-32
test/src/test/java/hudson/cli/CLITest.java
test/src/test/java/hudson/cli/CLITest.java
+7
-5
test/src/test/java/hudson/diagnosis/HudsonHomeDiskUsageMonitorTest.java
...java/hudson/diagnosis/HudsonHomeDiskUsageMonitorTest.java
+11
-17
test/src/test/java/hudson/jobs/CreateItemTest.java
test/src/test/java/hudson/jobs/CreateItemTest.java
+22
-22
test/src/test/java/hudson/model/AbstractItemTest.java
test/src/test/java/hudson/model/AbstractItemTest.java
+8
-8
test/src/test/java/hudson/model/AbstractProjectTest.java
test/src/test/java/hudson/model/AbstractProjectTest.java
+15
-21
test/src/test/java/hudson/model/ApiTest.java
test/src/test/java/hudson/model/ApiTest.java
+9
-12
test/src/test/java/hudson/model/AsynchPeopleTest.java
test/src/test/java/hudson/model/AsynchPeopleTest.java
+3
-10
test/src/test/java/hudson/model/ComputerTest.java
test/src/test/java/hudson/model/ComputerTest.java
+10
-12
test/src/test/java/hudson/model/DirectlyModifiableViewTest.java
...rc/test/java/hudson/model/DirectlyModifiableViewTest.java
+2
-2
test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java
...c/test/java/hudson/model/DirectoryBrowserSupportTest.java
+2
-8
test/src/test/java/hudson/model/HudsonTest.java
test/src/test/java/hudson/model/HudsonTest.java
+8
-10
test/src/test/java/hudson/model/ItemsTest.java
test/src/test/java/hudson/model/ItemsTest.java
+10
-9
test/src/test/java/hudson/model/JobTest.java
test/src/test/java/hudson/model/JobTest.java
+20
-16
test/src/test/java/hudson/model/NodeTest.java
test/src/test/java/hudson/model/NodeTest.java
+4
-7
test/src/test/java/hudson/model/ParametersTest.java
test/src/test/java/hudson/model/ParametersTest.java
+19
-18
test/src/test/java/hudson/model/PasswordParameterDefinitionTest.java
...st/java/hudson/model/PasswordParameterDefinitionTest.java
+3
-2
test/src/test/java/hudson/model/ProjectTest.java
test/src/test/java/hudson/model/ProjectTest.java
+3
-1
test/src/test/java/hudson/model/QueueSEC891Test.java
test/src/test/java/hudson/model/QueueSEC891Test.java
+6
-6
test/src/test/java/hudson/model/UserRestartSEC897Test.java
test/src/test/java/hudson/model/UserRestartSEC897Test.java
+4
-4
test/src/test/java/hudson/model/ViewTest.java
test/src/test/java/hudson/model/ViewTest.java
+19
-17
test/src/test/java/hudson/search/SearchTest.java
test/src/test/java/hudson/search/SearchTest.java
+13
-22
test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java
...est/java/hudson/security/csrf/DefaultCrumbIssuerTest.java
+17
-19
test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java
...rc/test/java/hudson/tools/ZipExtractionInstallerTest.java
+6
-6
test/src/test/java/hudson/util/RobustReflectionConverterTest.java
.../test/java/hudson/util/RobustReflectionConverterTest.java
+8
-9
test/src/test/java/jenkins/bugs/Jenkins19124Test.java
test/src/test/java/jenkins/bugs/Jenkins19124Test.java
+3
-0
test/src/test/java/jenkins/model/JenkinsTest.java
test/src/test/java/jenkins/model/JenkinsTest.java
+20
-23
test/src/test/java/jenkins/security/ApiTokenPropertyTest.java
.../src/test/java/jenkins/security/ApiTokenPropertyTest.java
+9
-5
test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java
...st/java/jenkins/security/RekeySecretAdminMonitorTest.java
+13
-4
test/src/test/java/jenkins/security/Security177Test.java
test/src/test/java/jenkins/security/Security177Test.java
+2
-2
test/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java
...est/java/jenkins/security/apitoken/ApiTokenStatsTest.java
+3
-2
test/src/test/java/jenkins/security/stapler/Security914Test.java
...c/test/java/jenkins/security/stapler/Security914Test.java
+7
-6
test/src/test/java/lib/form/ExpandableTextboxTest.java
test/src/test/java/lib/form/ExpandableTextboxTest.java
+4
-4
test/src/test/java/lib/form/PasswordTest.java
test/src/test/java/lib/form/PasswordTest.java
+4
-2
test/src/test/java/lib/form/ValidateButtonTest.java
test/src/test/java/lib/form/ValidateButtonTest.java
+6
-6
test/src/test/java/lib/layout/ConfirmationLinkTest.java
test/src/test/java/lib/layout/ConfirmationLinkTest.java
+13
-11
test/src/test/java/lib/layout/StopButtonTest.java
test/src/test/java/lib/layout/StopButtonTest.java
+6
-6
war/pom.xml
war/pom.xml
+2
-2
未找到文件。
Jenkinsfile
浏览文件 @
af09aaea
...
...
@@ -13,7 +13,7 @@
def
runTests
=
true
def
failFast
=
false
properties
([
buildDiscarder
(
logRotator
(
numToKeepStr:
'50'
,
artifactNumToKeepStr:
'
20
'
)),
durabilityHint
(
'PERFORMANCE_OPTIMIZED'
)])
properties
([
buildDiscarder
(
logRotator
(
numToKeepStr:
'50'
,
artifactNumToKeepStr:
'
3
'
)),
durabilityHint
(
'PERFORMANCE_OPTIMIZED'
)])
// see https://github.com/jenkins-infra/documentation/blob/master/ci.adoc for information on what node types are available
def
buildTypes
=
[
'Linux'
,
'Windows'
]
...
...
core/pom.xml
浏览文件 @
af09aaea
...
...
@@ -63,7 +63,7 @@ THE SOFTWARE.
<dependency>
<groupId>
org.jenkins-ci
</groupId>
<artifactId>
version-number
</artifactId>
<version>
1.
5
</version>
<version>
1.
6
</version>
</dependency>
<dependency>
<groupId>
org.jenkins-ci
</groupId>
...
...
core/src/main/java/hudson/FilePath.java
浏览文件 @
af09aaea
...
...
@@ -79,6 +79,7 @@ import java.net.MalformedURLException;
import
java.net.URI
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.nio.file.FileSystemException
;
import
java.nio.file.FileSystems
;
import
java.nio.file.Files
;
import
java.nio.file.NoSuchFileException
;
...
...
@@ -3266,7 +3267,7 @@ public final class FilePath implements Serializable {
parentRealPath
=
parentAbsolutePath
.
toRealPath
();
}
catch
(
NoSuchFileException
e
)
{
throw
new
IllegalArgumentException
(
"The parent does not exist"
)
;
return
false
;
}
// example: "a/b/c" that will become "b/c" then just "c", and finally an empty string
...
...
@@ -3307,6 +3308,9 @@ public final class FilePath implements Serializable {
Path
child
=
currentFileAbsolutePath
.
normalize
();
Path
parent
=
parentAbsolutePath
.
normalize
();
return
child
.
startsWith
(
parent
);
}
catch
(
FileSystemException
e
)
{
LOGGER
.
log
(
Level
.
WARNING
,
String
.
format
(
"Problem during call to the method toRealPath on %s"
,
currentFileAbsolutePath
),
e
);
return
false
;
}
}
...
...
core/src/main/java/hudson/PluginWrapper.java
浏览文件 @
af09aaea
...
...
@@ -33,6 +33,7 @@ import hudson.model.ModelObject;
import
hudson.model.UpdateCenter
;
import
hudson.model.UpdateSite
;
import
hudson.util.VersionNumber
;
import
io.jenkins.lib.versionnumber.JavaSpecificationVersion
;
import
jenkins.YesNoMaybe
;
import
jenkins.model.Jenkins
;
import
jenkins.util.java.JavaUtils
;
...
...
@@ -763,8 +764,8 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
String
minimumJavaVersion
=
getMinimumJavaVersion
();
if
(
minimumJavaVersion
!=
null
)
{
VersionNumber
actualVersion
=
JavaUtils
.
getCurrentJavaRuntimeVersionNumber
();
if
(
actualVersion
.
isOlderThan
(
new
VersionNumber
(
minimumJavaVersion
)))
{
JavaSpecificationVersion
actualVersion
=
JavaUtils
.
getCurrentJavaRuntimeVersionNumber
();
if
(
actualVersion
.
isOlderThan
(
new
JavaSpecificationVersion
(
minimumJavaVersion
)))
{
versionDependencyError
(
Messages
.
PluginWrapper_obsoleteJava
(
actualVersion
.
toString
(),
minimumJavaVersion
),
actualVersion
.
toString
(),
minimumJavaVersion
);
}
}
...
...
core/src/main/java/hudson/model/DirectoryBrowserSupport.java
浏览文件 @
af09aaea
...
...
@@ -39,8 +39,10 @@ import java.util.Collection;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.GregorianCalendar
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.StringTokenizer
;
import
java.util.logging.Level
;
...
...
@@ -59,7 +61,6 @@ import org.apache.tools.zip.ZipOutputStream;
import
org.kohsuke.accmod.Restricted
;
import
org.kohsuke.accmod.restrictions.NoExternalUse
;
import
org.kohsuke.stapler.HttpResponse
;
import
org.kohsuke.stapler.HttpResponses
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
...
...
@@ -75,7 +76,7 @@ import org.kohsuke.stapler.StaplerResponse;
public
final
class
DirectoryBrowserSupport
implements
HttpResponse
{
// escape hatch for SECURITY-904 to keep legacy behavior
@SuppressFBWarnings
(
value
=
"MS_SHOULD_BE_FINAL"
,
justification
=
"Accessible via System Groovy Scripts"
)
public
static
boolean
ALLOW_SYMLINK_ESCAPE
=
Boolean
.
getBoolean
(
DirectoryBrowserSupport
.
class
.
getName
()
+
".allowSymlinkEscape"
);
public
static
boolean
ALLOW_SYMLINK_ESCAPE
=
SystemProperties
.
getBoolean
(
DirectoryBrowserSupport
.
class
.
getName
()
+
".allowSymlinkEscape"
);
public
final
ModelObject
owner
;
...
...
@@ -436,33 +437,79 @@ public final class DirectoryBrowserSupport implements HttpResponse {
try
(
ZipOutputStream
zos
=
new
ZipOutputStream
(
outputStream
))
{
zos
.
setEncoding
(
System
.
getProperty
(
"file.encoding"
));
// TODO JENKINS-20663 make this overridable via query parameter
// TODO consider using run(Callable) here
for
(
String
n
:
dir
.
list
(
glob
.
isEmpty
()
?
"**"
:
glob
,
null
,
/* TODO what is the user expectation? */
true
))
{
String
relativePath
;
if
(
glob
.
length
()
==
0
)
{
// JENKINS-19947: traditional behavior is to prepend the directory name
relativePath
=
dir
.
getName
()
+
'/'
+
n
;
}
else
{
relativePath
=
n
;
}
String
targetFile
=
dir
.
toString
().
substring
(
root
.
toString
().
length
())
+
n
;
if
(!
ALLOW_SYMLINK_ESCAPE
&&
root
.
supportIsDescendant
()
&&
!
root
.
isDescendant
(
targetFile
))
{
LOGGER
.
log
(
Level
.
INFO
,
"Trying to access a file outside of the directory: "
+
root
+
", illicit target: "
+
targetFile
);
}
else
{
// In ZIP archives "All slashes MUST be forward slashes" (http://pkware.com/documents/casestudies/APPNOTE.TXT)
// TODO On Linux file names can contain backslashes which should not treated as file separators.
// Unfortunately, only the file separator char of the master is known (File.separatorChar)
// but not the file separator char of the (maybe remote) "dir".
ZipEntry
e
=
new
ZipEntry
(
relativePath
.
replace
(
'\\'
,
'/'
));
VirtualFile
f
=
dir
.
child
(
n
);
e
.
setTime
(
f
.
lastModified
());
zos
.
putNextEntry
(
e
);
try
(
InputStream
in
=
f
.
open
())
{
IOUtils
.
copy
(
in
,
zos
);
}
zos
.
closeEntry
();
if
(
glob
.
isEmpty
())
{
if
(!
root
.
supportsQuickRecursiveListing
())
{
// avoid slow listing when the Glob can do a quicker job
glob
=
"**"
;
}
}
if
(
glob
.
isEmpty
())
{
Map
<
String
,
VirtualFile
>
nameToVirtualFiles
=
collectRecursivelyAllLegalChildren
(
dir
);
sendZipUsingMap
(
zos
,
dir
,
nameToVirtualFiles
);
}
else
{
Collection
<
String
>
listOfFile
=
dir
.
list
(
glob
,
null
,
/* TODO what is the user expectation? */
true
);
sendZipUsingListOfNames
(
zos
,
dir
,
listOfFile
);
}
}
}
private
static
void
sendZipUsingMap
(
ZipOutputStream
zos
,
VirtualFile
dir
,
Map
<
String
,
VirtualFile
>
nameToVirtualFiles
)
throws
IOException
{
for
(
Map
.
Entry
<
String
,
VirtualFile
>
entry
:
nameToVirtualFiles
.
entrySet
())
{
String
n
=
entry
.
getKey
();
// JENKINS-19947: traditional behavior is to prepend the directory name
String
relativePath
=
dir
.
getName
()
+
'/'
+
n
;
VirtualFile
f
=
entry
.
getValue
();
sendOneZipEntry
(
zos
,
f
,
relativePath
);
}
}
private
static
void
sendZipUsingListOfNames
(
ZipOutputStream
zos
,
VirtualFile
dir
,
Collection
<
String
>
listOfFileNames
)
throws
IOException
{
for
(
String
relativePath
:
listOfFileNames
)
{
VirtualFile
f
=
dir
.
child
(
relativePath
);
sendOneZipEntry
(
zos
,
f
,
relativePath
);
}
}
private
static
void
sendOneZipEntry
(
ZipOutputStream
zos
,
VirtualFile
vf
,
String
relativePath
)
throws
IOException
{
// In ZIP archives "All slashes MUST be forward slashes" (http://pkware.com/documents/casestudies/APPNOTE.TXT)
// TODO On Linux file names can contain backslashes which should not treated as file separators.
// Unfortunately, only the file separator char of the master is known (File.separatorChar)
// but not the file separator char of the (maybe remote) "dir".
ZipEntry
e
=
new
ZipEntry
(
relativePath
.
replace
(
'\\'
,
'/'
));
e
.
setTime
(
vf
.
lastModified
());
zos
.
putNextEntry
(
e
);
try
(
InputStream
in
=
vf
.
open
())
{
IOUtils
.
copy
(
in
,
zos
);
}
finally
{
zos
.
closeEntry
();
}
}
private
static
Map
<
String
,
VirtualFile
>
collectRecursivelyAllLegalChildren
(
VirtualFile
dir
)
throws
IOException
{
Map
<
String
,
VirtualFile
>
nameToFiles
=
new
LinkedHashMap
<>();
collectRecursivelyAllLegalChildren
(
dir
,
""
,
nameToFiles
);
return
nameToFiles
;
}
private
static
void
collectRecursivelyAllLegalChildren
(
VirtualFile
currentDir
,
String
currentPrefix
,
Map
<
String
,
VirtualFile
>
nameToFiles
)
throws
IOException
{
if
(
currentDir
.
isFile
())
{
if
(
currentDir
.
isDescendant
(
""
))
{
nameToFiles
.
put
(
currentPrefix
,
currentDir
);
}
}
else
{
if
(!
currentPrefix
.
isEmpty
())
{
currentPrefix
+=
"/"
;
}
List
<
VirtualFile
>
children
=
currentDir
.
listOnlyDescendants
();
for
(
VirtualFile
child
:
children
)
{
collectRecursivelyAllLegalChildren
(
child
,
currentPrefix
+
child
.
getName
(),
nameToFiles
);
}
}
}
...
...
core/src/main/java/hudson/model/UpdateCenter.java
浏览文件 @
af09aaea
...
...
@@ -216,15 +216,8 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
if
(
ucOverride
!=
null
)
{
logger
.
log
(
Level
.
INFO
,
"Using a custom update center defined by the system property: {0}"
,
ucOverride
);
UPDATE_CENTER_URL
=
ucOverride
;
}
else
if
(
JavaUtils
.
isRunningWithJava8OrBelow
())
{
UPDATE_CENTER_URL
=
"https://updates.jenkins.io/"
;
}
else
{
//TODO: Rollback the default for Java 11 when it goes to GA
String
experimentalJava11UC
=
"https://updates.jenkins.io/temporary-experimental-java11/"
;
logger
.
log
(
Level
.
WARNING
,
"Running Jenkins with Java {0} which is available in the preview mode only. "
+
"A custom experimental update center will be used: {1}"
,
new
Object
[]
{
System
.
getProperty
(
"java.specification.version"
),
experimentalJava11UC
});
UPDATE_CENTER_URL
=
experimentalJava11UC
;
UPDATE_CENTER_URL
=
"https://updates.jenkins.io/"
;
}
}
...
...
core/src/main/java/hudson/model/UpdateSite.java
浏览文件 @
af09aaea
...
...
@@ -64,6 +64,7 @@ import javax.annotation.CheckForNull;
import
javax.annotation.Nonnull
;
import
javax.annotation.Nullable
;
import
io.jenkins.lib.versionnumber.JavaSpecificationVersion
;
import
jenkins.model.Jenkins
;
import
jenkins.model.DownloadSettings
;
import
jenkins.plugins.DetachedPluginsUtil
;
...
...
@@ -1133,8 +1134,8 @@ public class UpdateSite {
*/
public
boolean
isForNewerJava
()
{
try
{
final
VersionNumber
currentRuntimeJavaVersion
=
JavaUtils
.
getCurrentJavaRuntimeVersionNumber
();
return
minimumJavaVersion
!=
null
&&
new
VersionNumber
(
minimumJavaVersion
).
isNewerThan
(
final
JavaSpecificationVersion
currentRuntimeJavaVersion
=
JavaUtils
.
getCurrentJavaRuntimeVersionNumber
();
return
minimumJavaVersion
!=
null
&&
new
JavaSpecificationVersion
(
minimumJavaVersion
).
isNewerThan
(
currentRuntimeJavaVersion
);
}
catch
(
NumberFormatException
nfe
)
{
logBadMinJavaVersion
();
...
...
core/src/main/java/hudson/node_monitors/AbstractDiskSpaceMonitor.java
浏览文件 @
af09aaea
...
...
@@ -47,7 +47,7 @@ public abstract class AbstractDiskSpaceMonitor extends NodeMonitor {
if
(
size
!=
null
&&
size
.
size
>
getThresholdBytes
()
&&
c
.
isOffline
()
&&
c
.
getOfflineCause
()
instanceof
DiskSpace
)
if
(
this
.
getClass
().
equals
(((
DiskSpace
)
c
.
getOfflineCause
()).
getTrigger
()))
if
(
getDescriptor
().
markOnline
(
c
))
{
LOGGER
.
info
(
Messages
.
DiskSpaceMonitor_MarkedOnline
(
c
.
getName
()));
LOGGER
.
info
(
Messages
.
DiskSpaceMonitor_MarkedOnline
(
c
.
get
Display
Name
()));
}
return
size
;
}
...
...
@@ -64,7 +64,7 @@ public abstract class AbstractDiskSpaceMonitor extends NodeMonitor {
if
(
size
!=
null
&&
size
.
size
<
getThresholdBytes
())
{
size
.
setTriggered
(
this
.
getClass
(),
true
);
if
(
getDescriptor
().
markOffline
(
c
,
size
))
{
LOGGER
.
warning
(
Messages
.
DiskSpaceMonitor_MarkedOffline
(
c
.
getName
()));
LOGGER
.
warning
(
Messages
.
DiskSpaceMonitor_MarkedOffline
(
c
.
get
Display
Name
()));
}
}
return
size
;
...
...
core/src/main/java/hudson/util/DirScanner.java
浏览文件 @
af09aaea
package
hudson.util
;
import
hudson.FilePath
;
import
hudson.Util
;
import
org.apache.tools.ant.BuildException
;
import
org.apache.tools.ant.DirectoryScanner
;
import
org.apache.tools.ant.types.FileSet
;
import
org.apache.tools.ant.types.selectors.FileSelector
;
import
java.io.File
;
import
java.io.FileFilter
;
import
java.io.IOException
;
import
java.io.Serializable
;
import
java.util.HashSet
;
import
java.util.Set
;
import
static
hudson
.
Util
.
fixEmpty
;
...
...
@@ -119,8 +124,12 @@ public abstract class DirScanner implements Serializable {
FileSet
fs
=
Util
.
createFileSet
(
dir
,
includes
,
excludes
);
fs
.
setDefaultexcludes
(
useDefaultExcludes
);
fs
.
appendSelector
(
new
DescendantFileSelector
(
fs
.
getDir
()));
if
(
dir
.
exists
())
{
DirectoryScanner
ds
=
fs
.
getDirectoryScanner
(
new
org
.
apache
.
tools
.
ant
.
Project
());
// due to the DescendantFileSelector usage,
// the includedFiles are only the ones that are descendant
for
(
String
f
:
ds
.
getIncludedFiles
())
{
File
file
=
new
File
(
dir
,
f
);
scanSingle
(
file
,
f
,
visitor
);
...
...
@@ -130,6 +139,53 @@ public abstract class DirScanner implements Serializable {
private
static
final
long
serialVersionUID
=
1L
;
}
private
static
class
DescendantFileSelector
implements
FileSelector
{
private
final
Set
<
String
>
alreadyDeselected
;
private
final
FilePath
baseDirFP
;
private
final
int
baseDirPathLength
;
private
DescendantFileSelector
(
File
basedir
){
this
.
baseDirFP
=
new
FilePath
(
basedir
);
this
.
baseDirPathLength
=
basedir
.
getPath
().
length
();
this
.
alreadyDeselected
=
new
HashSet
<>();
}
@Override
public
boolean
isSelected
(
File
basedir
,
String
filename
,
File
file
)
throws
BuildException
{
String
parentName
=
file
.
getParent
();
if
(
parentName
.
length
()
>
baseDirPathLength
)
{
// remove the trailing slash
String
parentRelativeName
=
parentName
.
substring
(
baseDirPathLength
+
1
);
// as the visit is done following depth-first approach, we just have to check the parent once
// and then simply using the set
// in case something went wrong with the order, the isDescendant is called with just a lost
// in terms of performance, no impact on the result
if
(
alreadyDeselected
.
contains
(
parentRelativeName
))
{
alreadyDeselected
.
add
(
filename
);
return
false
;
}
}
// else: we have the direct children of the basedir
if
(
file
.
isDirectory
())
{
try
{
if
(
baseDirFP
.
isDescendant
(
filename
))
{
return
true
;
}
else
{
alreadyDeselected
.
add
(
filename
);
return
false
;
}
}
catch
(
IOException
|
InterruptedException
e
)
{
return
true
;
}
}
else
{
return
true
;
}
}
}
private
static
final
long
serialVersionUID
=
1L
;
}
core/src/main/java/jenkins/plugins/DetachedPluginsUtil.java
浏览文件 @
af09aaea
...
...
@@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableSet;
import
hudson.ClassicPluginStrategy
;
import
hudson.PluginWrapper
;
import
hudson.util.VersionNumber
;
import
io.jenkins.lib.versionnumber.JavaSpecificationVersion
;
import
jenkins.util.java.JavaUtils
;
import
org.kohsuke.accmod.Restricted
;
import
org.kohsuke.accmod.restrictions.NoExternalUse
;
...
...
@@ -174,13 +175,13 @@ public class DetachedPluginsUtil {
*/
private
final
VersionNumber
splitWhen
;
private
final
String
requiredVersion
;
private
final
VersionNumber
minJavaVersion
;
private
final
JavaSpecificationVersion
minJavaVersion
;
private
DetachedPlugin
(
String
shortName
,
String
splitWhen
,
String
requiredVersion
,
String
minJavaVersion
)
{
this
.
shortName
=
shortName
;
this
.
splitWhen
=
new
VersionNumber
(
splitWhen
);
this
.
requiredVersion
=
requiredVersion
;
this
.
minJavaVersion
=
new
VersionNumber
(
minJavaVersion
);
this
.
minJavaVersion
=
new
JavaSpecificationVersion
(
minJavaVersion
);
}
/**
...
...
@@ -217,7 +218,7 @@ public class DetachedPluginsUtil {
}
@Nonnull
public
VersionNumber
getMinimumJavaVersion
()
{
public
JavaSpecificationVersion
getMinimumJavaVersion
()
{
return
minJavaVersion
;
}
}
...
...
core/src/main/java/jenkins/util/VirtualFile.java
浏览文件 @
af09aaea
...
...
@@ -51,6 +51,7 @@ import java.util.Collections;
import
java.util.Deque
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
java.util.stream.Collectors
;
...
...
@@ -168,12 +169,38 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
public
abstract
boolean
exists
()
throws
IOException
;
/**
* Lists children of this directory.
* Lists children of this directory. Only one level deep.
*
* @return a list of children (files and subdirectories); empty for a file or nonexistent directory
* @throws IOException if this directory exists but listing was not possible for some other reason
*/
public
abstract
@Nonnull
VirtualFile
[]
list
()
throws
IOException
;
@Restricted
(
NoExternalUse
.
class
)
public
boolean
supportsQuickRecursiveListing
()
{
return
false
;
}
/**
* Lists only the children that are descendant of the root directory (not necessarily the current VirtualFile).
* Only one level deep.
*
* @return a list of descendant children (files and subdirectories); empty for a file or nonexistent directory
* @throws IOException if this directory exists but listing was not possible for some other reason
*/
@Restricted
(
NoExternalUse
.
class
)
public
@Nonnull
List
<
VirtualFile
>
listOnlyDescendants
()
throws
IOException
{
VirtualFile
[]
children
=
list
();
List
<
VirtualFile
>
result
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
children
.
length
;
i
++)
{
VirtualFile
child
=
children
[
i
];
if
(
child
.
isDescendant
(
""
))
{
result
.
add
(
child
);
}
}
return
result
;
}
/**
* @deprecated use {@link #list(String, String, boolean)} instead
*/
...
...
@@ -379,6 +406,12 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
public
boolean
isDescendant
(
String
childRelativePath
)
throws
IOException
{
return
false
;
}
String
joinWithForwardSlashes
(
Collection
<
String
>
relativePath
){
// instead of File.separator that is specific to the master, the / has the advantage to be supported
// by either Windows AND Linux for the Path.toRealPath() used in isDescendant
return
String
.
join
(
"/"
,
relativePath
)
+
"/"
;
}
/**
* Creates a virtual file wrapper for a local file.
...
...
@@ -391,6 +424,7 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
private
static
final
class
FileVF
extends
VirtualFile
{
private
final
File
f
;
private
final
File
root
;
private
boolean
cacheDescendant
=
false
;
FileVF
(
File
f
,
File
root
)
{
this
.
f
=
f
;
this
.
root
=
root
;
...
...
@@ -442,6 +476,29 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
}
return
vfs
;
}
@Override
public
boolean
supportsQuickRecursiveListing
()
{
return
true
;
}
@Override
public
@Nonnull
List
<
VirtualFile
>
listOnlyDescendants
()
throws
IOException
{
if
(
isIllegalSymlink
())
{
return
Collections
.
emptyList
();
}
File
[]
children
=
f
.
listFiles
();
if
(
children
==
null
)
{
return
Collections
.
emptyList
();
}
List
<
VirtualFile
>
legalChildren
=
new
ArrayList
<>(
children
.
length
);
for
(
File
child
:
children
)
{
if
(
isDescendant
(
child
.
getName
()))
{
FileVF
legalChild
=
new
FileVF
(
child
,
root
);
legalChild
.
cacheDescendant
=
true
;
legalChildren
.
add
(
legalChild
);
}
}
return
legalChildren
;
}
@Override
public
Collection
<
String
>
list
(
String
includes
,
String
excludes
,
boolean
useDefaultExcludes
)
throws
IOException
{
if
(
isIllegalSymlink
())
{
...
...
@@ -487,17 +544,14 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
}
}
private
boolean
isIllegalSymlink
()
{
// TODO JENKINS-26838
private
boolean
isIllegalSymlink
()
{
try
{
String
myPath
=
f
.
toPath
().
toRealPath
(
new
LinkOption
[
0
]).
toString
();
String
rootPath
=
root
.
toPath
().
toRealPath
(
new
LinkOption
[
0
]).
toString
();
if
(!
myPath
.
equals
(
rootPath
)
&&
!
myPath
.
startsWith
(
rootPath
+
File
.
separatorChar
))
{
return
true
;
}
return
!
this
.
isDescendant
(
""
);
}
catch
(
IOException
x
)
{
Logger
.
getLogger
(
VirtualFile
.
class
.
getName
()).
log
(
Level
.
FINE
,
"could not determine symlink status of "
+
f
,
x
);
}
catch
(
InvalidPathException
x2
)
{
// if this cannot be converted to a path, it cannot be an illegal symlink, as it cannot exist
// it's the case when we are calling it with *zip*
Logger
.
getLogger
(
VirtualFile
.
class
.
getName
()).
log
(
Level
.
FINE
,
"Could not convert "
+
f
+
" to path"
,
x2
);
}
return
false
;
...
...
@@ -518,15 +572,35 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
@Override
@Restricted
(
NoExternalUse
.
class
)
public
boolean
isDescendant
(
String
potentialChildRelativePath
)
throws
IOException
{
if
(
potentialChildRelativePath
.
isEmpty
()
&&
cacheDescendant
)
{
return
true
;
}
if
(
new
File
(
potentialChildRelativePath
).
isAbsolute
())
{
throw
new
IllegalArgumentException
(
"Only a relative path is supported, the given path is absolute: "
+
potentialChildRelativePath
);
}
// shortcut for direct child to avoid the complexity of the whole computation
// as we know that a file that is a direct descendant of its parent can only be descendant of the root
// if the parent is descendant AND the file itself is not symbolic
File
directChild
=
new
File
(
f
,
potentialChildRelativePath
);
if
(
directChild
.
getParentFile
().
equals
(
f
))
{
// potential shortcut for "simple" / direct child
if
(!
Util
.
isSymlink
(
directChild
))
{
return
true
;
}
}
FilePath
root
=
new
FilePath
(
this
.
root
);
String
relativePath
=
computeRelativePathToRoot
();
try
{
return
root
.
isDescendant
(
relativePath
+
potentialChildRelativePath
);
boolean
isDescendant
=
root
.
isDescendant
(
relativePath
+
potentialChildRelativePath
);
if
(
isDescendant
&&
potentialChildRelativePath
.
isEmpty
())
{
// in DirectoryBrowserSupport#zip, multiple calls to isDescendant are done for the same VirtualFile
cacheDescendant
=
true
;
}
return
isDescendant
;
}
catch
(
InterruptedException
e
)
{
return
false
;
...
...
@@ -547,8 +621,8 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
relativePath
.
addFirst
(
current
.
getName
());
current
=
current
.
getParentFile
();
}
return
String
.
join
(
File
.
separator
,
relativePath
)
+
File
.
separator
;
return
joinWithForwardSlashes
(
relativePath
)
;
}
}
...
...
@@ -563,6 +637,7 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
private
static
final
class
FilePathVF
extends
VirtualFile
{
private
final
FilePath
f
;
private
final
FilePath
root
;
private
boolean
cacheDescendant
=
false
;
FilePathVF
(
FilePath
f
,
FilePath
root
)
{
this
.
f
=
f
;
this
.
root
=
root
;
...
...
@@ -617,13 +692,40 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
throw
new
IOException
(
x
);
}
}
@Override
public
Collection
<
String
>
list
(
String
includes
,
String
excludes
,
boolean
useDefaultExcludes
)
throws
IOException
{
@Override
public
boolean
supportsQuickRecursiveListing
()
{
return
this
.
f
.
getChannel
()
==
FilePath
.
localChannel
;
}
@Override
public
@Nonnull
List
<
VirtualFile
>
listOnlyDescendants
()
throws
IOException
{
try
{
return
f
.
act
(
new
Scanner
(
includes
,
excludes
,
useDefaultExcludes
));
if
(!
isDescendant
(
""
))
{
return
Collections
.
emptyList
();
}
List
<
FilePath
>
children
=
f
.
list
();
List
<
VirtualFile
>
legalChildren
=
new
ArrayList
<>(
children
.
size
());
for
(
FilePath
child
:
children
){
if
(
isDescendant
(
child
.
getName
()))
{
FilePathVF
legalChild
=
new
FilePathVF
(
child
,
this
.
root
);
legalChild
.
cacheDescendant
=
true
;
legalChildren
.
add
(
legalChild
);
}
}
return
legalChildren
;
}
catch
(
InterruptedException
x
)
{
throw
new
IOException
(
x
);
}
}
@Override
public
Collection
<
String
>
list
(
String
includes
,
String
excludes
,
boolean
useDefaultExcludes
)
throws
IOException
{
try
{
return
f
.
act
(
new
Scanner
(
includes
,
excludes
,
useDefaultExcludes
));
}
catch
(
InterruptedException
x
)
{
throw
new
IOException
(
x
);
}
}
@Override
public
VirtualFile
child
(
String
name
)
{
return
new
FilePathVF
(
f
.
child
(
name
),
this
.
root
);
}
...
...
@@ -685,9 +787,31 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
@Override
@Restricted
(
NoExternalUse
.
class
)
public
boolean
isDescendant
(
String
potentialChildRelativePath
)
throws
IOException
{
if
(
potentialChildRelativePath
.
equals
(
""
)
&&
cacheDescendant
)
{
return
true
;
}
if
(
new
File
(
potentialChildRelativePath
).
isAbsolute
())
{
throw
new
IllegalArgumentException
(
"Only a relative path is supported, the given path is absolute: "
+
potentialChildRelativePath
);
}
// shortcut for direct child to avoid the complexity of the whole computation
// as we know that a file that is a direct descendant of its parent can only be descendant of the root
// if the parent is descendant
FilePath
directChild
=
this
.
f
.
child
(
potentialChildRelativePath
);
if
(
Objects
.
equals
(
directChild
.
getParent
(),
this
.
f
))
{
try
{
boolean
isDirectDescendant
=
this
.
f
.
isDescendant
(
potentialChildRelativePath
);
if
(
isDirectDescendant
)
{
return
true
;
}
// not a return false because you can be a non-descendant of your parent but still
// inside the root directory
}
catch
(
InterruptedException
e
)
{
return
false
;
}
}
String
relativePath
=
computeRelativePathToRoot
();
...
...
@@ -714,7 +838,7 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
current
=
current
.
getParent
();
}
return
String
.
join
(
File
.
separator
,
relativePath
)
+
File
.
separator
;
return
joinWithForwardSlashes
(
relativePath
)
;
}
}
private
static
final
class
Scanner
extends
MasterToSlaveFileCallable
<
List
<
String
>>
{
...
...
core/src/main/java/jenkins/util/java/JavaUtils.java
浏览文件 @
af09aaea
...
...
@@ -24,6 +24,7 @@
package
jenkins.util.java
;
import
hudson.util.VersionNumber
;
import
io.jenkins.lib.versionnumber.JavaSpecificationVersion
;
import
org.kohsuke.accmod.Restricted
;
import
org.kohsuke.accmod.restrictions.NoExternalUse
;
...
...
@@ -59,8 +60,8 @@ public class JavaUtils {
/**
* Returns the JVM's current version as a {@link VersionNumber} instance.
*/
public
static
VersionNumber
getCurrentJavaRuntimeVersionNumber
()
{
return
new
VersionNumber
(
getCurrentRuntimeJavaVersion
()
);
public
static
JavaSpecificationVersion
getCurrentJavaRuntimeVersionNumber
()
{
return
JavaSpecificationVersion
.
forCurrentJVM
(
);
}
/**
...
...
core/src/main/resources/jenkins/model/Messages_es_AR.properties
浏览文件 @
af09aaea
BuildDiscarderProperty.displayName
=
Descar
g
ar build antiguos
BuildDiscarderProperty.displayName
=
Descar
t
ar build antiguos
core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly
浏览文件 @
af09aaea
...
...
@@ -53,7 +53,7 @@ THE SOFTWARE.
The following commands are currently whitelisted for agents to execute on the master.
Type in any fully-qualified class names to whitelist them:
</p>
<textarea id="whitelist" name="whitelist" style="width:100%; height:5em">${it.whitelisted.
read()
}</textarea>
<textarea id="whitelist" name="whitelist" style="width:100%; height:5em">${it.whitelisted.
exists() ? it.whitelisted.read() : ""
}</textarea>
<j:set var="rejectedList" value="${it.rejected.describe()}"/>
...
...
@@ -88,7 +88,7 @@ THE SOFTWARE.
<p>
The following rules control which part of <tt>$JENKINS_HOME</tt> can be accessed from agents:
</p>
<textarea id="filePathRules" name="filePathRules" style="width:100%; height:5em">${it.filePathRules.
read()
}</textarea>
<textarea id="filePathRules" name="filePathRules" style="width:100%; height:5em">${it.filePathRules.
exists() ? it.filePathRules.read() : ""
}</textarea>
<p>
Example:
</p>
...
...
core/src/test/java/hudson/FilePathSEC904Test.java
浏览文件 @
af09aaea
...
...
@@ -33,7 +33,9 @@ import java.io.IOException;
import
java.nio.charset.StandardCharsets
;
import
java.util.concurrent.TimeUnit
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assume
.
assumeTrue
;
...
...
@@ -221,7 +223,6 @@ public class FilePathSEC904Test {
p
.
waitFor
(
2
,
TimeUnit
.
SECONDS
);
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
@Issue
(
"SECURITY-904"
)
public
void
isDescendant_throwIfParentDoesNotExist_symlink
()
throws
Exception
{
FilePath
rootFolder
=
new
FilePath
(
temp
.
newFolder
(
"root"
));
...
...
@@ -230,15 +231,14 @@ public class FilePathSEC904Test {
FilePath
linkToNonexistent
=
aFolder
.
child
(
"linkToNonexistent"
);
linkToNonexistent
.
symlinkTo
(
"__nonexistent__"
,
null
);
linkToNonexistent
.
isDescendant
(
"."
);
assertThat
(
linkToNonexistent
.
isDescendant
(
"."
),
is
(
false
)
);
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
@Issue
(
"SECURITY-904"
)
public
void
isDescendant_throwIfParentDoesNotExist_directNonexistent
()
throws
Exception
{
FilePath
rootFolder
=
new
FilePath
(
temp
.
newFolder
(
"root"
));
FilePath
nonexistent
=
rootFolder
.
child
(
"nonexistent"
);
nonexistent
.
isDescendant
(
"."
);
assertThat
(
nonexistent
.
isDescendant
(
"."
),
is
(
false
)
);
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
...
...
core/src/test/java/jenkins/util/VirtualFileSEC904Test.java
浏览文件 @
af09aaea
...
...
@@ -27,15 +27,20 @@ package jenkins.util;
import
hudson.FilePath
;
import
hudson.model.TaskListener
;
import
org.apache.commons.io.FileUtils
;
import
org.hamcrest.Description
;
import
org.hamcrest.TypeSafeMatcher
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.ExpectedException
;
import
org.junit.rules.TemporaryFolder
;
import
org.jvnet.hudson.test.Issue
;
import
java.io.File
;
import
static
org
.
hamcrest
.
Matchers
.
contains
;
import
static
org
.
hamcrest
.
Matchers
.
containsInAnyOrder
;
import
static
org
.
hamcrest
.
Matchers
.
hasSize
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
...
...
@@ -56,6 +61,7 @@ public class VirtualFileSEC904Test {
// /_b => symlink to /root/b
// /b
// /_a => symlink to /root/a
// /_aatxt => symlink to /root/a/aa/aa.txt
// /ba
// ba.txt
private
void
prepareFileStructureForIsDescendant
()
throws
Exception
{
...
...
@@ -82,6 +88,9 @@ public class VirtualFileSEC904Test {
File
_a
=
new
File
(
b
,
"_a"
);
new
FilePath
(
_a
).
symlinkTo
(
a
.
getAbsolutePath
(),
TaskListener
.
NULL
);
File
_aatxt
=
new
File
(
b
,
"_aatxt"
);
new
FilePath
(
_aatxt
).
symlinkTo
(
aaTxt
.
getAbsolutePath
(),
TaskListener
.
NULL
);
File
_b
=
new
File
(
a
,
"_b"
);
new
FilePath
(
_b
).
symlinkTo
(
b
.
getAbsolutePath
(),
TaskListener
.
NULL
);
File
_b2
=
new
File
(
aaa
,
"_b2"
);
...
...
@@ -177,4 +186,96 @@ public class VirtualFileSEC904Test {
assertTrue
(
virtualRoot
.
isDescendant
(
"_b/_a/aa/../ab/ab.txt"
));
assertTrue
(
virtualRoot
.
isDescendant
(
"_b/_a/aa/aa.txt"
));
}
@Test
@Issue
(
"JENKINS-55050"
)
public
void
forFile_listOnlyDescendants_withoutIllegal
()
throws
Exception
{
this
.
prepareFileStructureForIsDescendant
();
File
root
=
tmp
.
getRoot
();
File
a
=
new
File
(
root
,
"a"
);
File
b
=
new
File
(
root
,
"b"
);
VirtualFile
virtualRoot
=
VirtualFile
.
forFile
(
root
);
VirtualFile
virtualFromA
=
VirtualFile
.
forFile
(
a
);
VirtualFile
virtualFromB
=
VirtualFile
.
forFile
(
b
);
checkCommonAssertionForList
(
virtualRoot
,
virtualFromA
,
virtualFromB
);
}
@Test
@Issue
(
"SECURITY-904"
)
public
void
forFilePath_listOnlyDescendants_withoutIllegal
()
throws
Exception
{
this
.
prepareFileStructureForIsDescendant
();
File
root
=
tmp
.
getRoot
();
File
a
=
new
File
(
root
,
"a"
);
File
b
=
new
File
(
root
,
"b"
);
VirtualFile
virtualRoot
=
VirtualFile
.
forFilePath
(
new
FilePath
(
root
));
VirtualFile
virtualFromA
=
VirtualFile
.
forFilePath
(
new
FilePath
(
a
));
VirtualFile
virtualFromB
=
VirtualFile
.
forFilePath
(
new
FilePath
(
b
));
checkCommonAssertionForList
(
virtualRoot
,
virtualFromA
,
virtualFromB
);
}
private
void
checkCommonAssertionForList
(
VirtualFile
virtualRoot
,
VirtualFile
virtualFromA
,
VirtualFile
virtualFromB
)
throws
Exception
{
// outside link to folder is not returned
assertThat
(
virtualFromA
.
listOnlyDescendants
(),
containsInAnyOrder
(
VFMatcher
.
hasName
(
"aa"
),
VFMatcher
.
hasName
(
"ab"
)
));
// outside link to file is not returned
assertThat
(
virtualFromB
.
listOnlyDescendants
(),
contains
(
VFMatcher
.
hasName
(
"ba"
)
));
assertThat
(
virtualFromA
.
child
(
"_b"
).
listOnlyDescendants
(),
hasSize
(
0
));
assertThat
(
virtualFromA
.
child
(
"aa"
).
listOnlyDescendants
(),
containsInAnyOrder
(
VFMatcher
.
hasName
(
"aaa"
),
VFMatcher
.
hasName
(
"aa.txt"
)
));
// only a outside link
assertThat
(
virtualFromA
.
child
(
"aa"
).
child
(
"aaa"
).
listOnlyDescendants
(),
hasSize
(
0
));
// as we start from the root, the a/_b linking to root/b is legal
assertThat
(
virtualRoot
.
child
(
"a"
).
listOnlyDescendants
(),
containsInAnyOrder
(
VFMatcher
.
hasName
(
"aa"
),
VFMatcher
.
hasName
(
"ab"
),
VFMatcher
.
hasName
(
"_b"
)
));
assertThat
(
virtualRoot
.
child
(
"a"
).
child
(
"_b"
).
listOnlyDescendants
(),
containsInAnyOrder
(
VFMatcher
.
hasName
(
"_a"
),
VFMatcher
.
hasName
(
"_aatxt"
),
VFMatcher
.
hasName
(
"ba"
)
));
assertThat
(
virtualRoot
.
child
(
"a"
).
child
(
"_b"
).
child
(
"_a"
).
listOnlyDescendants
(),
containsInAnyOrder
(
VFMatcher
.
hasName
(
"aa"
),
VFMatcher
.
hasName
(
"ab"
),
VFMatcher
.
hasName
(
"_b"
)
));
}
private
abstract
static
class
VFMatcher
extends
TypeSafeMatcher
<
VirtualFile
>
{
private
final
String
description
;
private
VFMatcher
(
String
description
)
{
this
.
description
=
description
;
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
this
.
description
);
}
public
static
VFMatcher
hasName
(
String
expectedName
)
{
return
new
VFMatcher
(
"Has name: "
+
expectedName
)
{
protected
boolean
matchesSafely
(
VirtualFile
vf
)
{
return
expectedName
.
equals
(
vf
.
getName
());
}
};
}
}
}
pom.xml
浏览文件 @
af09aaea
...
...
@@ -76,7 +76,7 @@ THE SOFTWARE.
</issueManagement>
<properties>
<revision>
2.16
4
</revision>
<revision>
2.16
5
</revision>
<changelist>
-SNAPSHOT
</changelist>
<!-- *.html files are in UTF-8, and *.properties are in iso-8859-1, so this configuration is actually incorrect,
...
...
@@ -107,7 +107,7 @@ THE SOFTWARE.
<maven-war-plugin.version>
3.0.0
</maven-war-plugin.version>
<!-- JENKINS-47127 bump when 3.2.0 is out. Cf. MWAR-407 -->
<!-- Bundled Remoting version -->
<remoting.version>
3.2
8
</remoting.version>
<remoting.version>
3.2
9
</remoting.version>
<!-- Minimum Remoting version, which is tested for API compatibility -->
<remoting.minimum.supported.version>
3.4
</remoting.minimum.supported.version>
...
...
@@ -146,7 +146,7 @@ THE SOFTWARE.
<dependency>
<groupId>
commons-io
</groupId>
<artifactId>
commons-io
</artifactId>
<version>
2.
4
</version>
<version>
2.
6
</version>
</dependency>
<dependency>
...
...
test-pom/pom.xml
浏览文件 @
af09aaea
...
...
@@ -54,7 +54,7 @@ THE SOFTWARE.
<dependency>
<groupId>
${project.groupId}
</groupId>
<artifactId>
jenkins-test-harness
</artifactId>
<version>
2.4
1.1
</version>
<version>
2.4
6
</version>
<scope>
test
</scope>
<exclusions>
<exclusion>
...
...
test/src/test/java/hudson/AboutJenkinsTest.java
浏览文件 @
af09aaea
...
...
@@ -33,6 +33,8 @@ import org.jvnet.hudson.test.JenkinsRule;
import
org.jvnet.hudson.test.MockAuthorizationStrategy
;
import
org.jvnet.hudson.test.SmokeTest
;
import
java.net.HttpURLConnection
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertThat
;
...
...
@@ -55,19 +57,19 @@ public class AboutJenkinsTest {
.
grant
(
Jenkins
.
READ
).
everywhere
().
to
(
USER
)
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
{
// user cannot see it
wc
.
login
(
USER
);
HtmlPage
page
=
wc
.
goTo
(
"about/"
);
assertEquals
(
403
,
page
.
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
page
.
getWebResponse
().
getStatusCode
());
}
{
// admin can access it
wc
.
login
(
ADMIN
);
HtmlPage
page
=
wc
.
goTo
(
"about/"
);
assertEquals
(
200
,
page
.
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
page
.
getWebResponse
().
getStatusCode
());
assertThat
(
page
.
getWebResponse
().
getContentAsString
(),
containsString
(
"Mavenized dependencies"
));
}
}
...
...
test/src/test/java/hudson/TcpSlaveAgentListenerTest.java
浏览文件 @
af09aaea
package
hudson
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.TextPage
;
import
com.gargoylesoftware.htmlunit.html.HtmlPage
;
import
hudson.remoting.Base64
;
import
java.io.IOException
;
import
java.security.KeyFactory
;
import
java.security.KeyPair
;
import
java.security.KeyPairGenerator
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.cert.X509Certificate
;
import
java.security.interfaces.RSAPrivateKey
;
import
java.security.interfaces.RSAPublicKey
;
import
java.security.spec.InvalidKeySpecException
;
import
java.security.spec.PKCS8EncodedKeySpec
;
import
javax.annotation.Nullable
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
jenkins.model.Jenkins
;
import
jenkins.model.identity.InstanceIdentityProvider
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.jvnet.hudson.test.JenkinsRule
;
import
org.jvnet.hudson.test.JenkinsRule.WebClient
;
import
org.jvnet.hudson.test.TestExtension
;
import
static
org
.
hamcrest
.
Matchers
.*;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
fail
;
public
class
TcpSlaveAgentListenerTest
{
...
...
@@ -37,15 +23,15 @@ public class TcpSlaveAgentListenerTest {
@Test
public
void
headers
()
throws
Exception
{
WebClient
wc
=
r
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
r
.
getInstance
().
setSlaveAgentPort
(-
1
);
try
{
r
.
createWebClient
().
goTo
(
"tcpSlaveAgentListener"
);
fail
(
"Should get 404"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertThat
(
e
.
getStatusCode
(),
is
(
404
));
}
wc
.
assertFails
(
"tcpSlaveAgentListener"
,
HttpURLConnection
.
HTTP_NOT_FOUND
);
r
.
getInstance
().
setSlaveAgentPort
(
0
);
Page
p
=
r
.
createWebClient
().
goTo
(
"tcpSlaveAgentListener"
,
"text/plain"
);
Page
p
=
wc
.
goTo
(
"tcpSlaveAgentListener"
,
"text/plain"
);
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
p
.
getWebResponse
().
getStatusCode
());
assertThat
(
p
.
getWebResponse
().
getResponseHeaderValue
(
"X-Instance-Identity"
),
notNullValue
());
}
...
...
@@ -54,15 +40,13 @@ public class TcpSlaveAgentListenerTest {
r
.
getInstance
().
setSlaveAgentPort
(
0
);
int
p
=
r
.
jenkins
.
getTcpSlaveAgentListener
().
getPort
();
WebClient
wc
=
r
.
createWebClient
();
TextPage
text
=
(
TextPage
)
wc
.
getPage
(
"http://localhost:"
+
p
+
"/"
);
TextPage
text
=
wc
.
getPage
(
new
URL
(
"http://localhost:"
+
p
+
"/"
));
String
c
=
text
.
getContent
();
assertThat
(
c
,
containsString
(
Jenkins
.
VERSION
));
assertThat
(
c
,
containsString
(
Jenkins
.
VERSION
));
try
{
wc
.
getPage
(
"http://localhost:"
+
p
+
"/xxx"
);
fail
(
"Expected 404"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertThat
(
e
.
getStatusCode
(),
equalTo
(
404
));
}
wc
.
setThrowExceptionOnFailingStatusCode
(
false
);
Page
page
=
wc
.
getPage
(
new
URL
(
"http://localhost:"
+
p
+
"/xxx"
));
assertEquals
(
HttpURLConnection
.
HTTP_NOT_FOUND
,
page
.
getWebResponse
().
getStatusCode
());
}
}
test/src/test/java/hudson/cli/CLITest.java
浏览文件 @
af09aaea
...
...
@@ -37,6 +37,7 @@ import java.io.ByteArrayOutputStream;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.net.HttpURLConnection
;
import
java.nio.file.Files
;
import
java.util.Arrays
;
import
java.util.List
;
...
...
@@ -233,11 +234,12 @@ public class CLITest {
sshd
.
start
();
// Sanity check
JenkinsRule
.
WebClient
wc
=
r
.
createWebClient
();
wc
.
getOptions
().
setRedirectEnabled
(
false
);
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
r
.
createWebClient
()
.
withRedirectEnabled
(
false
)
.
withThrowExceptionOnFailingStatusCode
(
false
);
WebResponse
rsp
=
wc
.
goTo
(
"cli-proxy/"
).
getWebResponse
();
assertEquals
(
rsp
.
getContentAsString
(),
302
,
rsp
.
getStatusCode
());
assertEquals
(
rsp
.
getContentAsString
(),
HttpURLConnection
.
HTTP_MOVED_TEMP
,
rsp
.
getStatusCode
());
assertEquals
(
rsp
.
getContentAsString
(),
null
,
rsp
.
getResponseHeaderValue
(
"X-Jenkins"
));
assertEquals
(
rsp
.
getContentAsString
(),
null
,
rsp
.
getResponseHeaderValue
(
"X-Jenkins-CLI-Port"
));
assertEquals
(
rsp
.
getContentAsString
(),
null
,
rsp
.
getResponseHeaderValue
(
"X-SSH-Endpoint"
));
...
...
@@ -307,7 +309,7 @@ public class CLITest {
public
void
generateResponse
(
StaplerRequest
req
,
StaplerResponse
rsp
,
Object
node
)
throws
IOException
,
ServletException
{
rsp
.
setHeader
(
"Location"
,
url
);
rsp
.
setContentType
(
"text/html"
);
rsp
.
setStatus
(
302
);
rsp
.
setStatus
(
HttpURLConnection
.
HTTP_MOVED_TEMP
);
PrintWriter
w
=
rsp
.
getWriter
();
w
.
append
(
"Redirect to "
).
append
(
url
);
}
...
...
test/src/test/java/hudson/diagnosis/HudsonHomeDiskUsageMonitorTest.java
浏览文件 @
af09aaea
...
...
@@ -5,14 +5,13 @@ import static org.junit.Assert.assertFalse;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
import
com.gargoylesoftware.htmlunit.util.NameValuePair
;
import
hudson.model.User
;
import
hudson.security.GlobalMatrixAuthorizationStrategy
;
import
jenkins.model.Jenkins
;
import
jenkins.security.apitoken.ApiTokenPropertyConfiguration
;
import
jenkins.security.apitoken.ApiTokenTestHelper
;
import
org.junit.Rule
;
import
org.junit.Test
;
...
...
@@ -24,6 +23,7 @@ import com.gargoylesoftware.htmlunit.html.HtmlForm;
import
com.gargoylesoftware.htmlunit.ElementNotFoundException
;
import
java.io.IOException
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.util.Collections
;
...
...
@@ -63,7 +63,8 @@ public class HudsonHomeDiskUsageMonitorTest {
public
void
noAccessForNonAdmin
()
throws
Exception
{
ApiTokenTestHelper
.
enableLegacyBehavior
();
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
();
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
// TODO: Use MockAuthorizationStrategy in later versions
JenkinsRule
.
DummySecurityRealm
realm
=
j
.
createDummySecurityRealm
();
...
...
@@ -85,26 +86,19 @@ public class HudsonHomeDiskUsageMonitorTest {
HudsonHomeDiskUsageMonitor
mon
=
HudsonHomeDiskUsageMonitor
.
get
();
wc
.
withBasicApiToken
(
bob
);
try
{
wc
.
getPage
(
request
);
fail
();
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
403
,
e
.
getStatusCode
());
}
Page
p
=
wc
.
getPage
(
request
);
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
p
.
getWebResponse
().
getStatusCode
());
assertTrue
(
mon
.
isEnabled
());
WebRequest
requestReadOnly
=
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
"administrativeMonitor/hudsonHomeIsFull"
),
HttpMethod
.
GET
);
try
{
wc
.
getPage
(
requestReadOnly
);
fail
();
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
403
,
e
.
getStatusCode
());
}
p
=
wc
.
getPage
(
requestReadOnly
);
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
p
.
getWebResponse
().
getStatusCode
());
wc
.
withBasicApiToken
(
administrator
);
wc
.
getPage
(
request
);
p
=
wc
.
getPage
(
request
);
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
p
.
getWebResponse
().
getStatusCode
());
assertFalse
(
mon
.
isEnabled
());
}
/**
...
...
test/src/test/java/hudson/jobs/CreateItemTest.java
浏览文件 @
af09aaea
...
...
@@ -26,22 +26,22 @@ package hudson.jobs;
import
static
org
.
hamcrest
.
Matchers
.
nullValue
;
import
static
org
.
junit
.
Assert
.*;
import
hudson.AbortException
;
import
com.gargoylesoftware.htmlunit.Page
;
import
hudson.model.Failure
;
import
hudson.model.Item
;
import
hudson.model.ItemGroup
;
import
hudson.model.listeners.ItemListener
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.text.MessageFormat
;
import
org.acegisecurity.AccessDeniedException
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.jvnet.hudson.test.Issue
;
import
org.jvnet.hudson.test.JenkinsRule
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
import
hudson.model.FreeStyleProject
;
...
...
@@ -54,7 +54,6 @@ import org.jvnet.hudson.test.TestExtension;
* @author Christopher Simons
*/
public
class
CreateItemTest
{
private
static
final
int
ERROR_PRESET
=
(-
1
);
@Rule
public
JenkinsRule
rule
=
new
JenkinsRule
();
...
...
@@ -78,15 +77,13 @@ public class CreateItemTest {
WebRequest
request
=
new
WebRequest
(
apiURL
,
HttpMethod
.
POST
);
deleteContentTypeHeader
(
request
);
int
result
=
ERROR_PRESET
;
try
{
result
=
rule
.
createWebClient
()
.
getPage
(
request
).
getWebResponse
().
getStatusCode
();
}
catch
(
FailingHttpStatusCodeException
e
)
{
result
=
e
.
getResponse
().
getStatusCode
();
}
assertEquals
(
"Creating job from copy should succeed."
,
200
,
result
);
Page
p
=
rule
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
)
.
getPage
(
request
);
assertEquals
(
"Creating job from copy should succeed."
,
HttpURLConnection
.
HTTP_OK
,
p
.
getWebResponse
().
getStatusCode
());
}
@Issue
(
"JENKINS-34691"
)
...
...
@@ -104,15 +101,14 @@ public class CreateItemTest {
WebRequest
request
=
new
WebRequest
(
apiURL
,
HttpMethod
.
POST
);
deleteContentTypeHeader
(
request
);
int
result
=
ERROR_PRESET
;
try
{
result
=
rule
.
createWebClient
()
.
getPage
(
request
).
getWebResponse
().
getStatusCode
();
}
catch
(
FailingHttpStatusCodeException
e
)
{
result
=
e
.
getResponse
().
getStatusCode
();
}
assertEquals
(
"Creating job from copy should fail."
,
400
,
result
);
Page
p
=
rule
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
)
.
getPage
(
request
);
assertEquals
(
"Creating job from copy should fail."
,
HttpURLConnection
.
HTTP_BAD_REQUEST
,
p
.
getWebResponse
().
getStatusCode
());
assertThat
(
rule
.
jenkins
.
getItem
(
"newJob"
),
nullValue
());
}
...
...
@@ -125,9 +121,13 @@ public class CreateItemTest {
rule
.
jenkins
.
setCrumbIssuer
(
null
);
rule
.
createFolder
(
"d1"
).
createProject
(
FreeStyleProject
.
class
,
"p"
);
MockFolder
d2
=
rule
.
createFolder
(
"d2"
);
rule
.
createWebClient
().
getPage
(
new
WebRequest
(
new
URL
(
d2
.
getAbsoluteUrl
()
+
"createItem?mode=copy&name=p2&from=../d1/p"
),
HttpMethod
.
POST
));
JenkinsRule
.
WebClient
wc
=
rule
.
createWebClient
();
wc
.
getPage
(
new
WebRequest
(
new
URL
(
d2
.
getAbsoluteUrl
()
+
"createItem?mode=copy&name=p2&from=../d1/p"
),
HttpMethod
.
POST
));
assertNotNull
(
d2
.
getItem
(
"p2"
));
rule
.
createWebClient
().
getPage
(
new
WebRequest
(
new
URL
(
d2
.
getAbsoluteUrl
()
+
"createItem?mode=copy&name=p3&from=/d1/p"
),
HttpMethod
.
POST
));
wc
.
getPage
(
new
WebRequest
(
new
URL
(
d2
.
getAbsoluteUrl
()
+
"createItem?mode=copy&name=p3&from=/d1/p"
),
HttpMethod
.
POST
));
assertNotNull
(
d2
.
getItem
(
"p3"
));
}
...
...
test/src/test/java/hudson/model/AbstractItemTest.java
浏览文件 @
af09aaea
package
hudson.model
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
import
com.gargoylesoftware.htmlunit.util.NameValuePair
;
import
hudson.security.ACL
;
...
...
@@ -9,6 +9,7 @@ import hudson.security.ACLContext;
import
hudson.security.AccessDeniedException2
;
import
hudson.util.FormValidation
;
import
java.io.File
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.util.Arrays
;
import
jenkins.model.Jenkins
;
...
...
@@ -117,18 +118,17 @@ public class AbstractItemTest {
WebRequest
wr
=
new
WebRequest
(
w
.
createCrumbedUrl
(
p
.
getUrl
()
+
"confirmRename"
),
HttpMethod
.
POST
);
wr
.
setRequestParameters
(
Arrays
.
asList
(
new
NameValuePair
(
"newName"
,
"bar"
)));
w
.
login
(
"alice"
,
"alice"
);
assertThat
(
getPath
(
w
.
getPage
(
wr
).
getUrl
()),
equalTo
(
p
.
getUrl
()));
Page
page
=
w
.
getPage
(
wr
);
assertThat
(
getPath
(
page
.
getUrl
()),
equalTo
(
p
.
getUrl
()));
assertThat
(
p
.
getName
(),
equalTo
(
"bar"
));
wr
=
new
WebRequest
(
w
.
createCrumbedUrl
(
p
.
getUrl
()
+
"confirmRename"
),
HttpMethod
.
POST
);
wr
.
setRequestParameters
(
Arrays
.
asList
(
new
NameValuePair
(
"newName"
,
"baz"
)));
w
.
login
(
"bob"
,
"bob"
);
try
{
assertThat
(
getPath
(
w
.
getPage
(
wr
).
getUrl
()),
equalTo
(
p
.
getUrl
()));
fail
(
"Expecting HTTP 403 Forbidden"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertThat
(
e
.
getStatusCode
(),
equalTo
(
403
));
}
w
.
setThrowExceptionOnFailingStatusCode
(
false
);
page
=
w
.
getPage
(
wr
);
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
page
.
getWebResponse
().
getStatusCode
());
assertThat
(
p
.
getName
(),
equalTo
(
"bar"
));
}
...
...
test/src/test/java/hudson/model/AbstractProjectTest.java
浏览文件 @
af09aaea
...
...
@@ -24,8 +24,8 @@
package
hudson.model
;
import
com.gargoylesoftware.htmlunit.ElementNotFoundException
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
import
com.gargoylesoftware.htmlunit.WebResponse
;
import
com.gargoylesoftware.htmlunit.html.HtmlForm
;
...
...
@@ -120,16 +120,13 @@ public class AbstractProjectTest {
FreeStyleBuild
b
=
project
.
scheduleBuild2
(
0
).
get
();
assert
b
.
getWorkspace
().
exists
()
:
"Workspace should exist by now"
;
assert
True
(
"Workspace should exist by now"
,
b
.
getWorkspace
().
exists
())
;
// make sure that the action link is protected
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
();
try
{
wc
.
getPage
(
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
project
.
getUrl
()
+
"doWipeOutWorkspace"
),
HttpMethod
.
POST
));
fail
(
"Expected HTTP status code 403"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
e
.
getStatusCode
());
}
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
Page
page
=
wc
.
getPage
(
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
project
.
getUrl
()
+
"doWipeOutWorkspace"
),
HttpMethod
.
POST
));
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
page
.
getWebResponse
().
getStatusCode
());
}
/**
...
...
@@ -148,7 +145,7 @@ public class AbstractProjectTest {
JenkinsRule
.
WebClient
webClient
=
j
.
createWebClient
();
HtmlPage
page
=
webClient
.
getPage
(
j
.
jenkins
.
getItem
(
"test0"
));
page
=
(
HtmlPage
)
page
.
getAnchorByText
(
"Workspace"
).
click
();
page
=
page
.
getAnchorByText
(
"Workspace"
).
click
();
try
{
String
wipeOutLabel
=
ResourceBundle
.
getBundle
(
"hudson/model/AbstractProject/sidepanel"
).
getString
(
"Wipe Out Workspace"
);
page
.
getAnchorByText
(
wipeOutLabel
);
...
...
@@ -405,24 +402,21 @@ public class AbstractProjectTest {
j
.
jenkins
.
setNumExecutors
(
0
);
FreeStyleProject
p
=
j
.
createFreeStyleProject
();
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
();
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
WebResponse
rsp
=
wc
.
g
etPage
(
j
.
getURL
()
+
p
.
getUrl
()
+
"build"
).
getWebResponse
();
assertEquals
(
201
,
rsp
.
getStatusCode
());
WebResponse
rsp
=
wc
.
g
oTo
(
p
.
getUrl
()
+
"build"
,
null
).
getWebResponse
();
assertEquals
(
HttpURLConnection
.
HTTP_CREATED
,
rsp
.
getStatusCode
());
assertNotNull
(
rsp
.
getResponseHeaderValue
(
"Location"
));
WebResponse
rsp2
=
wc
.
g
etPage
(
j
.
getURL
()
+
p
.
getUrl
()
+
"build"
).
getWebResponse
();
assertEquals
(
201
,
rsp2
.
getStatusCode
());
WebResponse
rsp2
=
wc
.
g
oTo
(
p
.
getUrl
()
+
"build"
,
null
).
getWebResponse
();
assertEquals
(
HttpURLConnection
.
HTTP_CREATED
,
rsp2
.
getStatusCode
());
assertEquals
(
rsp
.
getResponseHeaderValue
(
"Location"
),
rsp2
.
getResponseHeaderValue
(
"Location"
));
p
.
makeDisabled
(
true
);
try
{
wc
.
getPage
(
j
.
getURL
()
+
p
.
getUrl
()
+
"build"
);
fail
();
}
catch
(
FailingHttpStatusCodeException
e
)
{
// request should fail
}
WebResponse
rsp3
=
wc
.
goTo
(
p
.
getUrl
()
+
"build"
,
null
).
getWebResponse
();
assertEquals
(
HttpURLConnection
.
HTTP_CONFLICT
,
rsp3
.
getStatusCode
());
}
/**
...
...
test/src/test/java/hudson/model/ApiTest.java
浏览文件 @
af09aaea
...
...
@@ -35,9 +35,10 @@ import org.jvnet.hudson.test.JenkinsRule;
import
java.io.File
;
import
java.net.HttpURLConnection
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
/**
* @author Kohsuke Kawaguchi
...
...
@@ -83,17 +84,13 @@ public class ApiTest {
@Issue
(
"SECURITY-165"
)
@Test
public
void
xPathDocumentFunction
()
throws
Exception
{
File
f
=
new
File
(
j
.
jenkins
.
getRootDir
(),
"queue.xml"
);
JenkinsRule
.
WebClient
client
=
j
.
createWebClient
();
try
{
client
.
goTo
(
"api/xml?xpath=document(\""
+
f
.
getAbsolutePath
()
+
"\")"
,
"application/xml"
);
fail
(
"Should become 500 error"
);
}
catch
(
com
.
gargoylesoftware
.
htmlunit
.
FailingHttpStatusCodeException
e
)
{
String
contentAsString
=
e
.
getResponse
().
getContentAsString
();
j
.
assertStringContains
(
contentAsString
,
"Illegal function: document"
);
}
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
// could expect application/xml but as an error occurred it's a text/html that is returned
Page
page
=
wc
.
goTo
(
"api/xml?xpath=document(\""
+
f
.
getAbsolutePath
()
+
"\")"
,
null
);
assertEquals
(
HttpURLConnection
.
HTTP_INTERNAL_ERROR
,
page
.
getWebResponse
().
getStatusCode
());
assertThat
(
page
.
getWebResponse
().
getContentAsString
(),
containsString
(
"Illegal function: document"
));
}
@Test
...
...
test/src/test/java/hudson/model/AsynchPeopleTest.java
浏览文件 @
af09aaea
...
...
@@ -24,7 +24,6 @@
package
hudson.model
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.html.DomElement
;
import
com.gargoylesoftware.htmlunit.html.HtmlPage
;
import
static
org
.
junit
.
Assert
.*;
...
...
@@ -41,16 +40,10 @@ public class AsynchPeopleTest {
@Issue
(
"JENKINS-18641"
)
@Test
public
void
display
()
throws
Exception
{
User
.
get
(
"bob"
);
User
.
get
ById
(
"bob"
,
true
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
();
HtmlPage
page
;
try
{
page
=
wc
.
goTo
(
"asynchPeople"
);
}
catch
(
FailingHttpStatusCodeException
x
)
{
System
.
err
.
println
(
x
.
getResponse
().
getResponseHeaders
());
System
.
err
.
println
(
x
.
getResponse
().
getContentAsString
());
throw
x
;
}
HtmlPage
page
=
wc
.
goTo
(
"asynchPeople"
);
assertEquals
(
0
,
wc
.
waitForBackgroundJavaScript
(
120000
));
boolean
found
=
false
;
for
(
DomElement
table
:
page
.
getElementsByTagName
(
"table"
))
{
...
...
test/src/test/java/hudson/model/ComputerTest.java
浏览文件 @
af09aaea
...
...
@@ -25,15 +25,16 @@ package hudson.model;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.*;
import
com.gargoylesoftware.htmlunit.
FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.
Page
;
import
com.gargoylesoftware.htmlunit.html.HtmlForm
;
import
com.gargoylesoftware.htmlunit.xml.XmlPage
;
import
java.io.File
;
import
java.net.HttpURLConnection
;
import
java.nio.charset.StandardCharsets
;
import
jenkins.model.Jenkins
;
import
hudson.slaves.DumbSlave
;
...
...
@@ -79,18 +80,15 @@ public class ComputerTest {
Node
nodeA
=
j
.
createSlave
(
"nodeA"
,
null
,
null
);
Node
nodeB
=
j
.
createSlave
(
"nodeB"
,
null
,
null
);
WebClient
wc
=
j
.
createWebClient
();
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
HtmlForm
form
=
wc
.
getPage
(
nodeB
,
"configure"
).
getFormByName
(
"config"
);
form
.
getInputByName
(
"_.name"
).
setValueAttribute
(
"nodeA"
);
try
{
j
.
submit
(
form
);
fail
(
NOTE
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertThat
(
NOTE
,
e
.
getStatusCode
(),
equalTo
(
400
));
assertThat
(
NOTE
,
e
.
getResponse
().
getContentAsString
(),
containsString
(
"Agent called ‘nodeA’ already exists"
));
}
Page
page
=
j
.
submit
(
form
);
assertEquals
(
NOTE
,
HttpURLConnection
.
HTTP_BAD_REQUEST
,
page
.
getWebResponse
().
getStatusCode
());
assertThat
(
NOTE
,
page
.
getWebResponse
().
getContentAsString
(),
containsString
(
"Agent called ‘nodeA’ already exists"
));
}
@Test
...
...
@@ -109,7 +107,7 @@ public class ComputerTest {
private
void
verifyOfflineCause
(
Computer
computer
)
throws
Exception
{
XmlPage
page
=
j
.
createWebClient
().
goToXml
(
"computer/"
+
computer
.
getName
()
+
"/config.xml"
);
String
content
=
page
.
getWebResponse
().
getContentAsString
(
"UTF-8"
);
String
content
=
page
.
getWebResponse
().
getContentAsString
(
StandardCharsets
.
UTF_8
);
assertThat
(
content
,
containsString
(
"temporaryOfflineCause"
));
assertThat
(
content
,
containsString
(
"<userId>username</userId>"
));
assertThat
(
content
,
not
(
containsString
(
"ApiTokenProperty"
)));
...
...
test/src/test/java/hudson/model/DirectlyModifiableViewTest.java
浏览文件 @
af09aaea
...
...
@@ -184,8 +184,8 @@ public class DirectlyModifiableViewTest {
}
private
Page
doPost
(
View
view
,
String
path
)
throws
Exception
{
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebRequest
req
=
new
WebRequest
(
new
URL
(
j
.
jenkins
.
getRootUrl
()
+
view
.
getUrl
()
+
path
),
HttpMethod
.
POST
...
...
test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java
浏览文件 @
af09aaea
...
...
@@ -23,7 +23,6 @@
*/
package
hudson.model
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
...
...
@@ -243,13 +242,8 @@ public class DirectoryBrowserSupportTest {
p
.
getPublishersList
().
add
(
new
ArtifactArchiver
(
"f"
));
j
.
buildAndAssertSuccess
(
p
);
HtmlPage
page
=
j
.
createWebClient
().
goTo
(
"job/"
+
p
.
getName
()
+
"/lastSuccessfulBuild/artifact/"
);
try
{
Page
download
=
page
.
getAnchorByText
(
"f"
).
click
();
assertEquals
(
"Hello world!"
,
download
.
getWebResponse
().
getContentAsString
());
}
catch
(
FailingHttpStatusCodeException
x
)
{
IOUtils
.
copy
(
x
.
getResponse
().
getContentAsStream
(),
System
.
err
);
throw
x
;
}
Page
download
=
page
.
getAnchorByText
(
"f"
).
click
();
assertEquals
(
"Hello world!"
,
download
.
getWebResponse
().
getContentAsString
());
}
/** Simulation of a storage service with URLs unrelated to {@link Run#doArtifact}. */
@TestExtension
(
"externalURLDownload"
)
...
...
test/src/test/java/hudson/model/HudsonTest.java
浏览文件 @
af09aaea
...
...
@@ -25,7 +25,6 @@ package hudson.model;
import
static
org
.
junit
.
Assert
.*;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
...
...
@@ -169,20 +168,19 @@ public class HudsonTest {
public
void
deleteHudsonComputer
()
throws
Exception
{
WebClient
wc
=
j
.
createWebClient
();
HtmlPage
page
=
wc
.
goTo
(
"computer/(master)/"
);
for
(
HtmlAnchor
a
:
page
.
getAnchors
())
assertFalse
(
a
.
getHrefAttribute
(),
a
.
getHrefAttribute
().
endsWith
(
"delete"
));
for
(
HtmlAnchor
a
:
page
.
getAnchors
())
{
assertFalse
(
a
.
getHrefAttribute
(),
a
.
getHrefAttribute
().
endsWith
(
"delete"
));
}
wc
.
setThrowExceptionOnFailingStatusCode
(
false
);
// try to delete it by hitting the final URL directly
WebRequest
req
=
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()+
"computer/(master)/doDelete"
),
HttpMethod
.
POST
);
try
{
wc
.
getPage
(
wc
.
addCrumb
(
req
));
fail
(
"Error code expected"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
HttpURLConnection
.
HTTP_BAD_REQUEST
,
e
.
getStatusCode
());
}
page
=
wc
.
getPage
(
wc
.
addCrumb
(
req
));
assertEquals
(
HttpURLConnection
.
HTTP_BAD_REQUEST
,
page
.
getWebResponse
().
getStatusCode
());
// the master computer object should be still here
wc
.
goTo
(
"computer/(master)/"
);
page
=
wc
.
goTo
(
"computer/(master)/"
);
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
page
.
getWebResponse
().
getStatusCode
());
}
/**
...
...
test/src/test/java/hudson/model/ItemsTest.java
浏览文件 @
af09aaea
...
...
@@ -191,9 +191,10 @@ public class ItemsTest {
/** Use the REST command to create an empty project (normally used only from the UI in the New Item dialog). */
REST_EMPTY
{
@Override
void
run
(
JenkinsRule
r
,
String
target
)
throws
Exception
{
JenkinsRule
.
WebClient
wc
=
wc
(
r
);
wc
.
getOptions
().
setRedirectEnabled
(
false
);
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
false
);
// redirect perversely counts as a failure
JenkinsRule
.
WebClient
wc
=
wc
(
r
)
// redirect perversely counts as a failure
.
withRedirectEnabled
(
false
)
.
withThrowExceptionOnFailingStatusCode
(
false
);
WebResponse
webResponse
=
wc
.
getPage
(
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
"createItem?name="
+
target
+
"&mode=hudson.model.FreeStyleProject"
),
HttpMethod
.
POST
)).
getWebResponse
();
if
(
webResponse
.
getStatusCode
()
!=
HttpStatus
.
SC_MOVED_TEMPORARILY
)
{
throw
new
FailingHttpStatusCodeException
(
webResponse
);
...
...
@@ -204,9 +205,9 @@ public class ItemsTest {
REST_COPY
{
@Override
void
run
(
JenkinsRule
r
,
String
target
)
throws
Exception
{
r
.
createFreeStyleProject
(
"dupe"
);
JenkinsRule
.
WebClient
wc
=
wc
(
r
)
;
wc
.
getOptions
().
setRedirectEnabled
(
false
);
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
wc
(
r
)
.
withRedirectEnabled
(
false
)
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebResponse
webResponse
=
wc
.
getPage
(
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
"createItem?name="
+
target
+
"&mode=copy&from=dupe"
),
HttpMethod
.
POST
)).
getWebResponse
();
r
.
jenkins
.
getItem
(
"dupe"
).
delete
();
if
(
webResponse
.
getStatusCode
()
!=
HttpStatus
.
SC_MOVED_TEMPORARILY
)
{
...
...
@@ -228,9 +229,9 @@ public class ItemsTest {
REST_RENAME
{
@Override
void
run
(
JenkinsRule
r
,
String
target
)
throws
Exception
{
r
.
createFreeStyleProject
(
"dupe"
);
JenkinsRule
.
WebClient
wc
=
wc
(
r
)
;
wc
.
getOptions
().
setRedirectEnabled
(
false
);
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
wc
(
r
)
.
withRedirectEnabled
(
false
)
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebResponse
webResponse
=
wc
.
getPage
(
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
"job/dupe/doRename?newName="
+
target
),
HttpMethod
.
POST
)).
getWebResponse
();
if
(
webResponse
.
getStatusCode
()
!=
HttpStatus
.
SC_MOVED_TEMPORARILY
)
{
r
.
jenkins
.
getItem
(
"dupe"
).
delete
();
...
...
test/src/test/java/hudson/model/JobTest.java
浏览文件 @
af09aaea
...
...
@@ -24,7 +24,7 @@
*/
package
hudson.model
;
import
com.gargoylesoftware.htmlunit.
FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.
Page
;
import
com.gargoylesoftware.htmlunit.WebAssert
;
import
com.gargoylesoftware.htmlunit.html.HtmlForm
;
import
com.gargoylesoftware.htmlunit.html.HtmlFormUtil
;
...
...
@@ -52,7 +52,6 @@ import java.util.concurrent.CountDownLatch;
import
jenkins.model.ProjectNamingStrategy
;
import
jenkins.security.apitoken.ApiTokenPropertyConfiguration
;
import
jenkins.security.apitoken.ApiTokenTestHelper
;
import
org.hamcrest.Matchers
;
import
org.junit.Rule
;
...
...
@@ -221,14 +220,19 @@ public class JobTest {
try
{
wc
.
assertFails
(
"job/testJob/config.xml"
,
HttpURLConnection
.
HTTP_FORBIDDEN
);
wc
.
withBasicApiToken
(
User
.
getById
(
"alice"
,
true
));
// Has CONFIGURE and EXTENDED_READ permission
tryConfigDotXml
(
wc
,
500
,
"Both perms; should get 500"
);
wc
.
setThrowExceptionOnFailingStatusCode
(
false
);
// Has CONFIGURE and EXTENDED_READ permission
wc
.
withBasicApiToken
(
User
.
getById
(
"alice"
,
true
));
tryConfigDotXml
(
wc
,
HttpURLConnection
.
HTTP_INTERNAL_ERROR
,
"Both perms; should get 500"
);
wc
.
withBasicApiToken
(
User
.
getById
(
"bob"
,
true
));
// Has only CONFIGURE permission (this should imply EXTENDED_READ)
tryConfigDotXml
(
wc
,
500
,
"Config perm should imply EXTENDED_READ"
);
// Has only CONFIGURE permission (this should imply EXTENDED_READ)
wc
.
withBasicApiToken
(
User
.
getById
(
"bob"
,
true
));
tryConfigDotXml
(
wc
,
HttpURLConnection
.
HTTP_INTERNAL_ERROR
,
"Config perm should imply EXTENDED_READ"
);
wc
.
withBasicApiToken
(
User
.
getById
(
"charlie"
,
true
));
// Has only EXTENDED_READ permission
tryConfigDotXml
(
wc
,
403
,
"No permission, should get 403"
);
// Has only EXTENDED_READ permission
wc
.
withBasicApiToken
(
User
.
getById
(
"charlie"
,
true
));
tryConfigDotXml
(
wc
,
HttpURLConnection
.
HTTP_FORBIDDEN
,
"No permission, should get 403"
);
}
finally
{
Item
.
EXTENDED_READ
.
setEnabled
(
saveEnabled
);
}
...
...
@@ -236,17 +240,17 @@ public class JobTest {
private
static
void
tryConfigDotXml
(
JenkinsRule
.
WebClient
wc
,
int
status
,
String
msg
)
throws
Exception
{
// Verify we can GET the config.xml:
wc
.
goTo
(
"job/testJob/config.xml"
,
"application/xml"
);
Page
p
=
wc
.
goTo
(
"job/testJob/config.xml"
,
"application/xml"
);
assertEquals
(
"Retrieving config.xml should be ok"
,
HttpURLConnection
.
HTTP_OK
,
p
.
getWebResponse
().
getStatusCode
());
// This page is a simple form to POST to /job/testJob/config.xml
// But it posts invalid data so we expect 500 if we have permission, 403 if not
HtmlPage
page
=
wc
.
goTo
(
"userContent/post.html"
);
try
{
HtmlFormUtil
.
submit
(
page
.
getForms
().
get
(
0
));
fail
(
"Expected exception: "
+
msg
);
}
catch
(
FailingHttpStatusCodeException
expected
)
{
assertEquals
(
msg
,
status
,
expected
.
getStatusCode
());
}
wc
.
goTo
(
"logout"
);
p
=
HtmlFormUtil
.
submit
(
page
.
getForms
().
get
(
0
));
assertEquals
(
msg
,
status
,
p
.
getWebResponse
().
getStatusCode
());
p
=
wc
.
goTo
(
"logout"
);
assertEquals
(
"To logout should be ok"
,
HttpURLConnection
.
HTTP_OK
,
p
.
getWebResponse
().
getStatusCode
());
}
@LocalData
@Issue
(
"JENKINS-6371"
)
...
...
test/src/test/java/hudson/model/NodeTest.java
浏览文件 @
af09aaea
...
...
@@ -23,7 +23,6 @@
*/
package
hudson.model
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
...
...
@@ -448,12 +447,10 @@ public class NodeTest {
WebRequest
settings
=
new
WebRequest
(
wc
.
createCrumbedUrl
(
"computer/(master)/config.xml"
));
settings
.
setHttpMethod
(
HttpMethod
.
POST
);
settings
.
setRequestBody
(
"<hudson/>"
);
try
{
Page
page
=
wc
.
getPage
(
settings
);
fail
(
page
.
getWebResponse
().
getContentAsString
());
}
catch
(
FailingHttpStatusCodeException
x
)
{
assertEquals
(
HttpURLConnection
.
HTTP_BAD_REQUEST
,
x
.
getStatusCode
());
}
wc
.
setThrowExceptionOnFailingStatusCode
(
false
);
Page
page
=
wc
.
getPage
(
settings
);
assertEquals
(
HttpURLConnection
.
HTTP_BAD_REQUEST
,
page
.
getWebResponse
().
getStatusCode
());
}
/**
...
...
test/src/test/java/hudson/model/ParametersTest.java
浏览文件 @
af09aaea
...
...
@@ -51,22 +51,22 @@ public class ParametersTest {
CaptureEnvironmentBuilder
builder
=
new
CaptureEnvironmentBuilder
();
project
.
getBuildersList
().
add
(
builder
);
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
page
=
wc
.
goTo
(
"job/"
+
project
.
getName
()
+
"/build?delay=0sec"
);
HtmlForm
form
=
page
.
getFormByName
(
"parameters"
);
HtmlElement
element
=
(
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
form
,
"//tr[td/div/input/@value='string']"
);
HtmlElement
element
=
DomNodeUtil
.
selectSingleNode
(
form
,
"//tr[td/div/input/@value='string']"
);
assertNotNull
(
element
);
assertEquals
(
"string description"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
.
getNextSibling
().
getNextSibling
(),
"td[@class='setting-description']"
)).
getTextContent
());
HtmlTextInput
stringParameterInput
=
(
HtmlTextInput
)
DomNodeUtil
.
selectSingleNode
(
element
,
".//input[@name='value']"
);
HtmlTextInput
stringParameterInput
=
DomNodeUtil
.
selectSingleNode
(
element
,
".//input[@name='value']"
);
assertEquals
(
"defaultValue"
,
stringParameterInput
.
getAttribute
(
"value"
));
assertEquals
(
"string"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
,
"td[@class='setting-name']"
)).
getTextContent
());
stringParameterInput
.
setAttribute
(
"value"
,
"newValue"
);
element
=
(
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
form
,
"//tr[td/div/input/@value='boolean']"
);
element
=
DomNodeUtil
.
selectSingleNode
(
form
,
"//tr[td/div/input/@value='boolean']"
);
assertNotNull
(
element
);
assertEquals
(
"boolean description"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
.
getNextSibling
().
getNextSibling
(),
"td[@class='setting-description']"
)).
getTextContent
());
Object
o
=
DomNodeUtil
.
selectSingleNode
(
element
,
".//input[@name='value']"
);
...
...
@@ -75,12 +75,12 @@ public class ParametersTest {
assertEquals
(
true
,
booleanParameterInput
.
isChecked
());
assertEquals
(
"boolean"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
,
"td[@class='setting-name']"
)).
getTextContent
());
element
=
(
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
form
,
".//tr[td/div/input/@value='choice']"
);
element
=
DomNodeUtil
.
selectSingleNode
(
form
,
".//tr[td/div/input/@value='choice']"
);
assertNotNull
(
element
);
assertEquals
(
"choice description"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
.
getNextSibling
().
getNextSibling
(),
"td[@class='setting-description']"
)).
getTextContent
());
assertEquals
(
"choice"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
,
"td[@class='setting-name']"
)).
getTextContent
());
element
=
(
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
form
,
".//tr[td/div/input/@value='run']"
);
element
=
DomNodeUtil
.
selectSingleNode
(
form
,
".//tr[td/div/input/@value='run']"
);
assertNotNull
(
element
);
assertEquals
(
"run description"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
.
getNextSibling
().
getNextSibling
(),
"td[@class='setting-description']"
)).
getTextContent
());
assertEquals
(
"run"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
,
"td[@class='setting-name']"
)).
getTextContent
());
...
...
@@ -105,16 +105,16 @@ public class ParametersTest {
CaptureEnvironmentBuilder
builder
=
new
CaptureEnvironmentBuilder
();
project
.
getBuildersList
().
add
(
builder
);
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
page
=
wc
.
goTo
(
"job/"
+
project
.
getName
()
+
"/build?delay=0sec"
);
HtmlForm
form
=
page
.
getFormByName
(
"parameters"
);
HtmlElement
element
=
(
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
form
,
".//tr[td/div/input/@value='choice']"
);
HtmlElement
element
=
DomNodeUtil
.
selectSingleNode
(
form
,
".//tr[td/div/input/@value='choice']"
);
assertNotNull
(
element
);
assertEquals
(
"choice description"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
.
getNextSibling
().
getNextSibling
(),
"td[@class='setting-description']"
)).
getTextContent
());
assertEquals
(
"choice"
,
((
HtmlElement
)
DomNodeUtil
.
selectSingleNode
(
element
,
"td[@class='setting-name']"
)).
getTextContent
());
HtmlOption
opt
=
(
HtmlOption
)
DomNodeUtil
.
selectSingleNode
(
element
,
"td/div/select/option[@value='Choice <2>']"
);
HtmlOption
opt
=
DomNodeUtil
.
selectSingleNode
(
element
,
"td/div/select/option[@value='Choice <2>']"
);
assertNotNull
(
opt
);
assertEquals
(
"Choice <2>"
,
opt
.
asText
());
opt
.
setSelected
(
true
);
...
...
@@ -192,8 +192,8 @@ public class ParametersTest {
new
FileParameterDefinition
(
"filename"
,
"description"
));
project
.
addProperty
(
pdp
);
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
page
=
wc
.
goTo
(
"job/"
+
project
.
getName
()
+
"/build?delay=0sec"
);
HtmlForm
form
=
page
.
getFormByName
(
"parameters"
);
...
...
@@ -215,12 +215,13 @@ public class ParametersTest {
);
p
.
addProperty
(
pdb
);
WebClient
wc
=
j
.
createWebClient
();
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
false
);
// Ignore 405
WebClient
wc
=
j
.
createWebClient
()
// Ignore 405
.
withThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
page
=
wc
.
getPage
(
p
,
"build"
);
// java.lang.IllegalArgumentException: No such parameter definition: <gibberish>.
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
true
);
wc
.
setThrowExceptionOnFailingStatusCode
(
true
);
final
HtmlForm
form
=
page
.
getFormByName
(
"parameters"
);
HtmlFormUtil
.
submit
(
form
,
HtmlFormUtil
.
getButtonByCaption
(
form
,
"Build"
));
}
...
...
@@ -233,8 +234,8 @@ public class ParametersTest {
StringParameterDefinition
param
=
new
StringParameterDefinition
(
"<param name>"
,
"<param default>"
,
"<param description>"
);
assertEquals
(
"<b>[</b>param description<b>]</b>"
,
param
.
getFormattedDescription
());
p
.
addProperty
(
new
ParametersDefinitionProperty
(
param
));
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
page
=
wc
.
getPage
(
p
,
"build?delay=0sec"
);
collector
.
checkThat
(
page
.
getWebResponse
().
getStatusCode
(),
is
(
HttpStatus
.
SC_METHOD_NOT_ALLOWED
));
// 405 to dissuade scripts from thinking this triggered the build
String
text
=
page
.
getWebResponse
().
getContentAsString
();
...
...
test/src/test/java/hudson/model/PasswordParameterDefinitionTest.java
浏览文件 @
af09aaea
...
...
@@ -71,8 +71,9 @@ public class PasswordParameterDefinitionTest {
User
admin
=
User
.
getById
(
"admin"
,
true
);
User
dev
=
User
.
getById
(
"dev"
,
true
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
();
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
false
);
// ParametersDefinitionProperty/index.jelly sends a 405 but really it is OK
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
// ParametersDefinitionProperty/index.jelly sends a 405 but really it is OK
.
withThrowExceptionOnFailingStatusCode
(
false
);
// Control case: admin can use default value.
j
.
submit
(
wc
.
withBasicApiToken
(
admin
).
getPage
(
p
,
"build?delay=0sec"
).
getFormByName
(
"parameters"
));
j
.
waitUntilNoActivity
();
...
...
test/src/test/java/hudson/model/ProjectTest.java
浏览文件 @
af09aaea
...
...
@@ -25,6 +25,7 @@ package hudson.model;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
import
com.gargoylesoftware.htmlunit.javascript.host.event.Event
;
import
hudson.*
;
import
hudson.model.queue.QueueTaskFuture
;
import
hudson.security.AccessDeniedException2
;
...
...
@@ -252,7 +253,8 @@ public class ProjectTest {
assertEquals
(
"Scm retry count should be the same as global scm retry count."
,
6
,
p
.
getScmCheckoutRetryCount
());
HtmlForm
form
=
j
.
createWebClient
().
goTo
(
p
.
getUrl
()
+
"/configure"
).
getFormByName
(
"config"
);
((
HtmlElement
)
form
.
getByXPath
(
"//div[@class='advancedLink']//button"
).
get
(
0
)).
click
();
form
.
getInputByName
(
"hasCustomScmCheckoutRetryCount"
).
click
();
// required due to the new default behavior of click
form
.
getInputByName
(
"hasCustomScmCheckoutRetryCount"
).
click
(
new
Event
(),
true
);
form
.
getInputByName
(
"scmCheckoutRetryCount"
).
setValueAttribute
(
"7"
);
j
.
submit
(
form
);
assertEquals
(
"Scm retry count was set."
,
7
,
p
.
getScmCheckoutRetryCount
());
...
...
test/src/test/java/hudson/model/QueueSEC891Test.java
浏览文件 @
af09aaea
...
...
@@ -59,9 +59,9 @@ public class QueueSEC891Test {
WebRequest
request
=
new
WebRequest
(
new
URL
(
r
.
getURL
()
+
urlProvider
.
apply
(
currentOne
)),
HttpMethod
.
POST
);
{
// user without right cannot cancel
JenkinsRule
.
WebClient
wc
=
r
.
createWebClient
()
;
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
false
);
wc
.
getOptions
().
setRedirectEnabled
(
false
);
JenkinsRule
.
WebClient
wc
=
r
.
createWebClient
()
.
withRedirectEnabled
(
false
)
.
withThrowExceptionOnFailingStatusCode
(
false
);
wc
.
login
(
"user"
);
Page
p
=
wc
.
getPage
(
request
);
// currently the endpoint return a redirection to the previously visited page, none in our case
...
...
@@ -71,9 +71,9 @@ public class QueueSEC891Test {
assertFalse
(
currentOne
.
getFuture
().
isCancelled
());
}
{
// user with right can
JenkinsRule
.
WebClient
wc
=
r
.
createWebClient
()
;
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
false
);
wc
.
getOptions
().
setRedirectEnabled
(
false
);
JenkinsRule
.
WebClient
wc
=
r
.
createWebClient
()
.
withRedirectEnabled
(
false
)
.
withThrowExceptionOnFailingStatusCode
(
false
);
wc
.
login
(
"admin"
);
Page
p
=
wc
.
getPage
(
request
);
assertThat
(
p
.
getWebResponse
().
getStatusCode
(),
lessThan
(
400
));
...
...
test/src/test/java/hudson/model/UserRestartSEC897Test.java
浏览文件 @
af09aaea
...
...
@@ -32,16 +32,16 @@ public class UserRestartSEC897Test {
User
.
getById
(
"admin"
,
true
).
save
();
{
// attempt with ".."
JenkinsRule
.
WebClient
wc
=
rr
.
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
rr
.
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebRequest
request
=
new
WebRequest
(
new
URL
(
rr
.
j
.
jenkins
.
getRootUrl
()
+
"whoAmI/api/xml"
));
request
.
setAdditionalHeader
(
"Authorization"
,
base64
(
".."
,
"any-password"
));
wc
.
getPage
(
request
);
}
{
// attempt with "../users/.."
JenkinsRule
.
WebClient
wc
=
rr
.
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
rr
.
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebRequest
request
=
new
WebRequest
(
new
URL
(
rr
.
j
.
jenkins
.
getRootUrl
()
+
"whoAmI/api/xml"
));
request
.
setAdditionalHeader
(
"Authorization"
,
base64
(
"../users/.."
,
"any-password"
));
...
...
test/src/test/java/hudson/model/ViewTest.java
浏览文件 @
af09aaea
...
...
@@ -24,6 +24,7 @@
package
hudson.model
;
import
com.cloudbees.hudson.plugins.folder.Folder
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
import
com.gargoylesoftware.htmlunit.html.DomNodeUtil
;
import
com.gargoylesoftware.htmlunit.util.NameValuePair
;
...
...
@@ -31,7 +32,6 @@ import jenkins.model.Jenkins;
import
org.jenkins.ui.icon.Icon
;
import
org.jenkins.ui.icon.IconSet
;
import
org.jvnet.hudson.test.Issue
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.html.HtmlAnchor
;
import
com.gargoylesoftware.htmlunit.html.HtmlForm
;
...
...
@@ -56,6 +56,7 @@ import hudson.util.FormValidation;
import
hudson.util.HudsonIsLoading
;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.HttpURLConnection
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.List
;
...
...
@@ -120,19 +121,19 @@ public class ViewTest {
@Test
public
void
conflictingName
()
throws
Exception
{
assertNull
(
j
.
jenkins
.
getView
(
"foo"
));
HtmlForm
form
=
j
.
createWebClient
().
goTo
(
"newView"
).
getFormByName
(
"createItem"
);
WebClient
wc
=
j
.
createWebClient
();
HtmlForm
form
=
wc
.
goTo
(
"newView"
).
getFormByName
(
"createItem"
);
form
.
getInputByName
(
"name"
).
setValueAttribute
(
"foo"
);
form
.
getRadioButtonsByName
(
"mode"
).
get
(
0
).
setChecked
(
true
);
j
.
submit
(
form
);
assertNotNull
(
j
.
jenkins
.
getView
(
"foo"
));
wc
.
setThrowExceptionOnFailingStatusCode
(
false
);
// do it again and verify an error
try
{
j
.
submit
(
form
);
fail
(
"shouldn't be allowed to create two views of the same name."
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
400
,
e
.
getStatusCode
());
}
Page
page
=
j
.
submit
(
form
);
assertEquals
(
"shouldn't be allowed to create two views of the same name."
,
HttpURLConnection
.
HTTP_BAD_REQUEST
,
page
.
getWebResponse
().
getStatusCode
());
}
@Test
public
void
privateView
()
throws
Exception
{
...
...
@@ -209,23 +210,24 @@ public class ViewTest {
IconSet
.
icons
.
addIcon
(
new
Icon
(
"icon-folder icon-md"
,
"24x24/folder.gif"
,
"width: 24px; height: 24px;"
));
}
WebClient
webClient
=
j
.
createWebClient
();
WebClient
webClient
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
webClient
.
getOptions
().
setJavaScriptEnabled
(
false
);
j
.
assertAllImageLoadSuccessfully
(
webClient
.
goTo
(
"asynchPeople"
));
}
@Issue
(
"JENKINS-16608"
)
@Test
public
void
notAllowedName
()
throws
Exception
{
HtmlForm
form
=
j
.
createWebClient
().
goTo
(
"newView"
).
getFormByName
(
"createItem"
);
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
HtmlForm
form
=
wc
.
goTo
(
"newView"
).
getFormByName
(
"createItem"
);
form
.
getInputByName
(
"name"
).
setValueAttribute
(
".."
);
form
.
getRadioButtonsByName
(
"mode"
).
get
(
0
).
setChecked
(
true
);
try
{
j
.
submit
(
form
);
fail
(
"\"..\" should not be allowed."
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
400
,
e
.
getStatusCode
());
}
HtmlPage
page
=
j
.
submit
(
form
);
assertEquals
(
"\"..\" should not be allowed."
,
HttpURLConnection
.
HTTP_BAD_REQUEST
,
page
.
getWebResponse
().
getStatusCode
());
}
@Ignore
(
"verified manually in Winstone but org.mortbay.JettyResponse.sendRedirect (6.1.26) seems to mangle the location"
)
...
...
@@ -246,7 +248,7 @@ public class ViewTest {
ListView
view
=
listView
(
"v"
);
view
.
description
=
"one"
;
WebClient
wc
=
j
.
createWebClient
();
String
xml
=
wc
.
goToXml
(
"view/v/config.xml"
).
get
Content
();
String
xml
=
wc
.
goToXml
(
"view/v/config.xml"
).
get
WebResponse
().
getContentAsString
();
assertTrue
(
xml
,
xml
.
contains
(
"<description>one</description>"
));
xml
=
xml
.
replace
(
"<description>one</description>"
,
"<description>two</description>"
);
WebRequest
req
=
new
WebRequest
(
wc
.
createCrumbedUrl
(
"view/v/config.xml"
),
HttpMethod
.
POST
);
...
...
test/src/test/java/hudson/search/SearchTest.java
浏览文件 @
af09aaea
...
...
@@ -27,12 +27,13 @@ import static org.junit.Assert.assertEquals;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
fail
;
import
com.gargoylesoftware.htmlunit.html.HtmlPage
;
import
hudson.model.FreeStyleProject
;
import
hudson.model.ListView
;
import
java.io.IOException
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.util.ArrayList
;
...
...
@@ -43,7 +44,6 @@ import hudson.model.User;
import
hudson.model.View
;
import
hudson.security.ACL
;
import
hudson.security.ACLContext
;
import
hudson.security.AuthorizationStrategy
;
import
hudson.security.GlobalMatrixAuthorizationStrategy
;
import
jenkins.model.Jenkins
;
import
net.sf.json.JSONArray
;
...
...
@@ -58,8 +58,6 @@ import org.jvnet.hudson.test.JenkinsRule.WebClient;
import
org.jvnet.hudson.test.MockAuthorizationStrategy
;
import
org.jvnet.hudson.test.MockFolder
;
import
com.gargoylesoftware.htmlunit.AlertHandler
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.Page
;
/**
...
...
@@ -74,12 +72,10 @@ public class SearchTest {
*/
@Test
public
void
testFailure
()
throws
Exception
{
try
{
j
.
search
(
"no-such-thing"
);
fail
(
"404 expected"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
404
,
e
.
getResponse
().
getStatusCode
());
}
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
resultPage
=
wc
.
search
(
"no-such-thing"
);
assertEquals
(
HttpURLConnection
.
HTTP_NOT_FOUND
,
resultPage
.
getWebResponse
().
getStatusCode
());
}
/**
...
...
@@ -88,18 +84,13 @@ public class SearchTest {
@Issue
(
"JENKINS-3415"
)
@Test
public
void
testXSS
()
throws
Exception
{
try
{
WebClient
wc
=
j
.
createWebClient
();
wc
.
setAlertHandler
(
new
AlertHandler
()
{
public
void
handleAlert
(
Page
page
,
String
message
)
{
throw
new
AssertionError
();
}
});
wc
.
search
(
"<script>alert('script');</script>"
);
fail
(
"404 expected"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
404
,
e
.
getResponse
().
getStatusCode
());
}
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
wc
.
setAlertHandler
((
page
,
message
)
->
{
throw
new
AssertionError
();
});
HtmlPage
resultPage
=
wc
.
search
(
"<script>alert('script');</script>"
);
assertEquals
(
HttpURLConnection
.
HTTP_NOT_FOUND
,
resultPage
.
getWebResponse
().
getStatusCode
());
}
@Test
...
...
test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java
浏览文件 @
af09aaea
...
...
@@ -6,10 +6,8 @@
package
hudson.security.csrf
;
import
com.gargoylesoftware.htmlunit.
FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.
Page
;
import
com.gargoylesoftware.htmlunit.html.HtmlPage
;
import
jenkins.model.Jenkins
;
import
junit.framework.Assert
;
import
net.sf.json.JSONObject
;
import
org.junit.Before
;
import
org.junit.Rule
;
...
...
@@ -60,13 +58,11 @@ public class DefaultCrumbIssuerTest {
HtmlPage
p
=
wc
.
goTo
(
"configure"
);
wc
.
removeRequestHeader
(
HEADER_NAME
);
try
{
// The crumb should no longer match if we remove the proxy info
r
.
submit
(
p
.
getFormByName
(
"config"
));
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
403
,
e
.
getStatusCode
());
}
wc
.
setThrowExceptionOnFailingStatusCode
(
false
);
// The crumb should no longer match if we remove the proxy info
Page
page
=
r
.
submit
(
p
.
getFormByName
(
"config"
));
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
page
.
getWebResponse
().
getStatusCode
());
}
@Issue
(
"JENKINS-3854"
)
...
...
@@ -139,17 +135,19 @@ public class DefaultCrumbIssuerTest {
@Issue
(
"JENKINS-34254"
)
@Test
public
void
testRequirePostErrorPageCrumb
()
throws
Exception
{
Jenkins
.
getInstance
().
setCrumbIssuer
(
new
DefaultCrumbIssuer
(
false
));
WebClient
wc
=
r
.
createWebClient
();
try
{
wc
.
goTo
(
"quietDown"
);
fail
(
"expected failure"
);
}
catch
(
FailingHttpStatusCodeException
ex
)
{
Assert
.
assertEquals
(
"expect HTTP 405 method not allowed"
,
405
,
ex
.
getStatusCode
());
}
r
.
jenkins
.
setCrumbIssuer
(
new
DefaultCrumbIssuer
(
false
));
WebClient
wc
=
r
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
Page
page
=
wc
.
goTo
(
"quietDown"
);
assertEquals
(
"expect HTTP 405 method not allowed"
,
HttpURLConnection
.
HTTP_BAD_METHOD
,
page
.
getWebResponse
().
getStatusCode
());
HtmlPage
retry
=
(
HtmlPage
)
wc
.
getCurrentWindow
().
getEnclosedPage
();
HtmlPage
success
=
r
.
submit
(
retry
.
getFormByName
(
"retry"
));
Assert
.
assertTrue
(
"quieting down"
,
r
.
jenkins
.
isQuietingDown
());
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
success
.
getWebResponse
().
getStatusCode
());
assertTrue
(
"quieting down"
,
r
.
jenkins
.
isQuietingDown
());
}
}
test/src/test/java/hudson/tools/ZipExtractionInstallerTest.java
浏览文件 @
af09aaea
...
...
@@ -24,7 +24,6 @@
package
hudson.tools
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.InteractivePage
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
import
com.gargoylesoftware.htmlunit.html.HtmlPage
;
import
com.gargoylesoftware.htmlunit.html.HtmlTextInput
;
...
...
@@ -46,6 +45,7 @@ import org.jvnet.hudson.test.MockAuthorizationStrategy;
import
javax.annotation.Nonnull
;
import
javax.annotation.Nullable
;
import
java.lang.reflect.Field
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.net.URLDecoder
;
import
java.net.URLEncoder
;
...
...
@@ -88,12 +88,12 @@ public class ZipExtractionInstallerTest {
JenkinsRule
.
WebClient
adminWc
=
j
.
createWebClient
();
adminWc
.
login
(
ADMIN
);
assertEquals
(
200
,
adminWc
.
getPage
(
request
).
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
adminWc
.
getPage
(
request
).
getWebResponse
().
getStatusCode
());
JenkinsRule
.
WebClient
userWc
=
j
.
createWebClient
()
;
userWc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
userWc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
userWc
.
login
(
USER
);
assertEquals
(
403
,
userWc
.
getPage
(
request
).
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
userWc
.
getPage
(
request
).
getWebResponse
().
getStatusCode
());
}
@Test
...
...
@@ -148,7 +148,7 @@ public class ZipExtractionInstallerTest {
}
@Override
public
Object
callFunction
(
Interactive
Page
page
,
Function
function
,
Scriptable
scope
,
Scriptable
thisObject
,
Object
[]
args
)
{
public
Object
callFunction
(
Html
Page
page
,
Function
function
,
Scriptable
scope
,
Scriptable
thisObject
,
Object
[]
args
)
{
if
(
thisObject
instanceof
XMLHttpRequest
)
{
try
{
WebRequest
request
=
getPrivateWebRequestField
((
XMLHttpRequest
)
thisObject
);
...
...
test/src/test/java/hudson/util/RobustReflectionConverterTest.java
浏览文件 @
af09aaea
...
...
@@ -24,6 +24,7 @@
package
hudson.util
;
import
com.gargoylesoftware.htmlunit.Page
;
import
hudson.cli.CLICommandInvoker
;
import
hudson.diagnosis.OldDataMonitor
;
import
hudson.model.AbstractDescribableImpl
;
...
...
@@ -38,6 +39,7 @@ import hudson.model.User;
import
hudson.security.ACL
;
import
java.io.ByteArrayInputStream
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.util.Collections
;
import
java.util.Map
;
...
...
@@ -45,7 +47,6 @@ import java.util.Map;
import
jenkins.model.Jenkins
;
import
static
org
.
junit
.
Assert
.*;
import
jenkins.security.apitoken.ApiTokenPropertyConfiguration
;
import
jenkins.security.apitoken.ApiTokenTestHelper
;
import
net.sf.json.JSONObject
;
...
...
@@ -59,7 +60,6 @@ import org.jvnet.hudson.test.recipes.LocalData;
import
org.kohsuke.stapler.DataBoundConstructor
;
import
org.kohsuke.stapler.StaplerRequest
;
import
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.WebRequest
;
...
...
@@ -236,18 +236,17 @@ public class RobustReflectionConverterTest {
// Configure a bad keyword via REST.
r
.
jenkins
.
setSecurityRealm
(
r
.
createDummySecurityRealm
());
WebClient
wc
=
r
.
createWebClient
();
WebClient
wc
=
r
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
);
wc
.
withBasicApiToken
(
test
);
WebRequest
req
=
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
String
.
format
(
"%s/config.xml"
,
p
.
getUrl
())),
HttpMethod
.
POST
);
req
.
setEncodingType
(
null
);
req
.
setRequestBody
(
String
.
format
(
CONFIGURATION_TEMPLATE
,
AcceptOnlySpecificKeyword
.
ACCEPT_KEYWORD
,
"badvalue"
));
try
{
wc
.
getPage
(
req
);
fail
(
"Submitting unacceptable configuration via REST should fail."
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
// pass
}
Page
page
=
wc
.
getPage
(
req
);
assertEquals
(
"Submitting unacceptable configuration via REST should fail."
,
HttpURLConnection
.
HTTP_INTERNAL_ERROR
,
page
.
getWebResponse
().
getStatusCode
());
// Configuration should not be updated for a failure of the critical field,
assertNotEquals
(
"badvalue"
,
p
.
getProperty
(
KeywordProperty
.
class
).
getCriticalField
().
getKeyword
());
...
...
test/src/test/java/jenkins/bugs/Jenkins19124Test.java
浏览文件 @
af09aaea
...
...
@@ -41,7 +41,10 @@ public class Jenkins19124Test {
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
();
HtmlPage
c
=
wc
.
getPage
(
p
,
"configure"
);
HtmlTextInput
alpha
=
c
.
getElementByName
(
"_.alpha"
);
// the fireEvent is required as setValueAttribute's new behavior is not triggering the onChange event anymore
alpha
.
setValueAttribute
(
"hello"
);
alpha
.
fireEvent
(
"change"
);
WebClientUtil
.
waitForJSExec
(
wc
);
assertEquals
(
"hello"
,
d
.
alpha
);
assertEquals
(
"2"
,
d
.
bravo
);
...
...
test/src/test/java/jenkins/model/JenkinsTest.java
浏览文件 @
af09aaea
...
...
@@ -337,33 +337,30 @@ public class JenkinsTest {
grant
(
Jenkins
.
READ
).
everywhere
().
to
(
"bob"
).
grantWithoutImplication
(
Jenkins
.
ADMINISTER
,
Jenkins
.
READ
).
everywhere
().
to
(
"charlie"
));
WebClient
wc
=
j
.
createWebClient
();
WebClient
wc
=
j
.
createWebClient
()
.
withThrowExceptionOnFailingStatusCode
(
false
)
.
withBasicApiToken
(
User
.
getById
(
"alice"
,
true
));
wc
.
withBasicApiToken
(
User
.
getById
(
"alice"
,
true
));
wc
.
assertFails
(
"eval"
,
HttpURLConnection
.
HTTP_BAD_METHOD
);
assertEquals
(
"3"
,
eval
(
wc
));
assertEquals
(
"3"
,
eval
(
wc
)
.
getWebResponse
().
getContentAsString
()
);
wc
.
withBasicApiToken
(
User
.
getById
(
"bob"
,
true
));
try
{
eval
(
wc
);
fail
(
"bob has only READ"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
e
.
getStatusCode
());
}
Page
page
=
eval
(
wc
);
assertEquals
(
"bob has only READ"
,
HttpURLConnection
.
HTTP_FORBIDDEN
,
page
.
getWebResponse
().
getStatusCode
());
wc
.
withBasicApiToken
(
User
.
getById
(
"charlie"
,
true
));
try
{
eval
(
wc
);
fail
(
"charlie has ADMINISTER but not RUN_SCRIPTS"
);
}
catch
(
FailingHttpStatusCodeException
e
)
{
assertEquals
(
HttpURLConnection
.
HTTP_FORBIDDEN
,
e
.
getStatusCode
());
}
page
=
eval
(
wc
);
assertEquals
(
"charlie has ADMINISTER but not RUN_SCRIPTS"
,
HttpURLConnection
.
HTTP_FORBIDDEN
,
page
.
getWebResponse
().
getStatusCode
());
}
private
String
eval
(
WebClient
wc
)
throws
Exception
{
private
Page
eval
(
WebClient
wc
)
throws
Exception
{
WebRequest
req
=
new
WebRequest
(
new
URL
(
wc
.
getContextPath
()
+
"eval"
),
HttpMethod
.
POST
);
req
.
setEncodingType
(
null
);
req
.
setRequestBody
(
"<j:jelly xmlns:j='jelly:core'>${1+2}</j:jelly>"
);
return
wc
.
getPage
(
req
)
.
getWebResponse
().
getContentAsString
()
;
return
wc
.
getPage
(
req
);
}
@TestExtension
(
"testUnprotectedRootAction"
)
...
...
@@ -411,13 +408,13 @@ public class JenkinsTest {
j
.
jenkins
.
setAuthorizationStrategy
(
auth
);
// no anonymous read access
assertTrue
(!
Jenkins
.
get
Instance
().
hasPermission
(
Jenkins
.
ANONYMOUS
,
Jenkins
.
READ
));
assertTrue
(!
Jenkins
.
get
().
hasPermission
(
Jenkins
.
ANONYMOUS
,
Jenkins
.
READ
));
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"error/reportError"
);
assertEquals
(
p
.
asText
(),
400
,
p
.
getWebResponse
().
getStatusCode
());
// not 403 forbidden
assertEquals
(
p
.
asText
(),
HttpURLConnection
.
HTTP_BAD_REQUEST
,
p
.
getWebResponse
().
getStatusCode
());
// not 403 forbidden
assertTrue
(
p
.
getWebResponse
().
getContentAsString
().
contains
(
"My car is black"
));
}
...
...
@@ -462,8 +459,8 @@ public class JenkinsTest {
URL
url
=
new
URL
(
j
.
getURL
(),
"computer/"
+
slave
.
getNodeName
()
+
"/scriptText?script=println(42)"
);
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebRequest
req
=
new
WebRequest
(
url
,
HttpMethod
.
POST
);
Page
page
=
wc
.
getPage
(
wc
.
addCrumb
(
req
));
...
...
test/src/test/java/jenkins/security/ApiTokenPropertyTest.java
浏览文件 @
af09aaea
...
...
@@ -24,6 +24,8 @@ import hudson.model.FreeStyleProject;
import
hudson.model.User
;
import
hudson.security.ACL
;
import
hudson.security.ACLContext
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
jenkins.model.Jenkins
;
...
...
@@ -139,12 +141,14 @@ public class ApiTokenPropertyTest {
final
ApiTokenProperty
.
DescriptorImpl
descriptor
=
(
ApiTokenProperty
.
DescriptorImpl
)
t
.
getDescriptor
();
// Make sure that Admin can reset a token of another user
WebClient
wc
=
createClientForUser
(
"bar"
)
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
createClientForUser
(
"bar"
)
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
requirePOST
=
wc
.
goTo
(
foo
.
getUrl
()
+
"/"
+
descriptor
.
getDescriptorUrl
()+
"/changeToken"
);
assertEquals
(
"method should not be allowed"
,
405
,
requirePOST
.
getWebResponse
().
getStatusCode
());
assertEquals
(
"method should not be allowed"
,
HttpURLConnection
.
HTTP_BAD_METHOD
,
requirePOST
.
getWebResponse
().
getStatusCode
());
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
true
);
wc
.
setThrowExceptionOnFailingStatusCode
(
true
);
WebRequest
request
=
new
WebRequest
(
new
URL
(
j
.
getURL
().
toString
()
+
foo
.
getUrl
()
+
"/"
+
descriptor
.
getDescriptorUrl
()+
"/changeToken"
),
HttpMethod
.
POST
);
HtmlPage
res
=
wc
.
getPage
(
request
);
...
...
@@ -163,7 +167,7 @@ public class ApiTokenPropertyTest {
WebClient
wc
=
createClientForUser
(
"foo"
);
WebRequest
wr
=
new
WebRequest
(
new
URL
(
j
.
getURL
(),
"job/bar/build"
),
HttpMethod
.
POST
);
assertEquals
(
201
,
wc
.
getPage
(
wr
).
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_CREATED
,
wc
.
getPage
(
wr
).
getWebResponse
().
getStatusCode
());
j
.
waitUntilNoActivity
();
...
...
test/src/test/java/jenkins/security/RekeySecretAdminMonitorTest.java
浏览文件 @
af09aaea
...
...
@@ -11,7 +11,6 @@ import hudson.Util;
import
hudson.util.Secret
;
import
hudson.util.SecretHelper
;
import
org.apache.commons.io.FileUtils
;
import
org.hamcrest.CoreMatchers
;
import
org.jvnet.hudson.test.HudsonTestCase
;
import
org.jvnet.hudson.test.recipes.Recipe.Runner
;
import
org.xml.sax.SAXException
;
...
...
@@ -22,8 +21,7 @@ import java.io.File;
import
java.io.IOException
;
import
java.lang.annotation.Annotation
;
import
java.util.regex.Pattern
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
java.util.stream.Stream
;
/**
* @author Kohsuke Kawaguchi
...
...
@@ -132,7 +130,18 @@ public class RekeySecretAdminMonitorTest extends HudsonTestCase {
}
private
HtmlButton
getButton
(
HtmlForm
form
,
int
index
)
{
return
form
.<
HtmlButton
>
getHtmlElementsByTagName
(
"button"
).
get
(
index
);
// due to the removal of method HtmlElement.getHtmlElementsByTagName
Stream
<
HtmlButton
>
buttonStream
=
form
.
getElementsByTagName
(
"button"
).
stream
()
.
filter
(
HtmlButton
.
class
::
isInstance
)
.
map
(
HtmlButton
.
class
::
cast
);
if
(
index
>
0
)
{
buttonStream
=
buttonStream
.
skip
(
index
-
1
);
}
return
buttonStream
.
findFirst
()
.
orElse
(
null
);
}
public
void
testScanOnBoot
()
throws
Exception
{
...
...
test/src/test/java/jenkins/security/Security177Test.java
浏览文件 @
af09aaea
...
...
@@ -19,8 +19,8 @@ public class Security177Test {
@Test
public
void
nosniff
()
throws
Exception
{
WebClient
wc
=
jenkins
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
jenkins
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
URL
u
=
jenkins
.
getURL
();
verifyNoSniff
(
wc
.
getPage
(
new
URL
(
u
,
"adjuncts/507db12b/nosuch/adjunct.js"
)));
...
...
test/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java
浏览文件 @
af09aaea
...
...
@@ -67,8 +67,9 @@ public class ApiTokenStatsTest {
assertNotNull
(
t
.
getTokenStats
());
// test the authentication via Token
WebClient
wc
=
j
.
createWebClient
().
withBasicCredentials
(
u
.
getId
());
wc
.
getOptions
().
setThrowExceptionOnFailingStatusCode
(
false
);
WebClient
wc
=
j
.
createWebClient
()
.
withBasicCredentials
(
u
.
getId
())
.
withThrowExceptionOnFailingStatusCode
(
false
);
final
String
TOKEN_NAME
=
"New Token Name"
;
...
...
test/src/test/java/jenkins/security/stapler/Security914Test.java
浏览文件 @
af09aaea
...
...
@@ -33,6 +33,7 @@ import org.jvnet.hudson.test.Issue;
import
org.jvnet.hudson.test.JenkinsRule
;
import
org.jvnet.hudson.test.TestPluginManager
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
...
...
@@ -53,8 +54,8 @@ public class Security914Test {
}
j
.
createWebClient
().
goTo
(
"plugin/credentials/images/24x24/credentials.png"
,
"image/png"
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebRequest
request
=
new
WebRequest
(
new
URL
(
j
.
getURL
()
+
"plugin/credentials/.xml"
));
// plugin deployed in: test\target\jenkins7375296945862059919tmp
// rootDir is in : test\target\jenkinsTests.tmp\jenkins1274934531848159942test
...
...
@@ -62,7 +63,7 @@ public class Security914Test {
request
.
setAdditionalHeader
(
"Accept-Language"
,
"../../../../jenkinsTests.tmp/"
+
j
.
jenkins
.
getRootDir
().
getName
()
+
"/config"
);
Page
p
=
wc
.
getPage
(
request
);
assertEquals
(
p
.
getWebResponse
().
getStatusCode
(),
404
);
assertEquals
(
HttpURLConnection
.
HTTP_NOT_FOUND
,
p
.
getWebResponse
().
getStatusCode
()
);
assertNotEquals
(
p
.
getWebResponse
().
getContentType
(),
"application/xml"
);
}
...
...
@@ -75,14 +76,14 @@ public class Security914Test {
}
j
.
createWebClient
().
goTo
(
"plugin/credentials/images/24x24/credentials.png"
,
"image/png"
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
WebRequest
request
=
new
WebRequest
(
new
URL
(
j
.
getURL
()
+
"plugin/credentials/.ini"
));
// ../ can be multiply to infinity, no impact, we just need to have enough to reach the root
request
.
setAdditionalHeader
(
"Accept-Language"
,
"../../../../../../../../../../../../windows/win"
);
Page
p
=
wc
.
getPage
(
request
);
assertEquals
(
p
.
getWebResponse
().
getStatusCode
(),
404
);
assertEquals
(
HttpURLConnection
.
HTTP_NOT_FOUND
,
p
.
getWebResponse
().
getStatusCode
()
);
assertEquals
(
p
.
getWebResponse
().
getContentType
(),
"text/html"
);
}
}
test/src/test/java/lib/form/ExpandableTextboxTest.java
浏览文件 @
af09aaea
...
...
@@ -99,8 +99,8 @@ public class ExpandableTextboxTest {
private
void
checkRegularCase
(
TestRootAction
testParams
)
throws
Exception
{
testParams
.
paramName
=
"testName"
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
HtmlElementUtil
.
click
(
getExpandButton
(
p
));
...
...
@@ -110,8 +110,8 @@ public class ExpandableTextboxTest {
private
void
checkInjectionInName
(
TestRootAction
testParams
)
throws
Exception
{
testParams
.
paramName
=
"testName',document.title='hacked'+'"
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
HtmlElementUtil
.
click
(
getExpandButton
(
p
));
...
...
test/src/test/java/lib/form/PasswordTest.java
浏览文件 @
af09aaea
...
...
@@ -148,7 +148,7 @@ public class PasswordTest {
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
String
pName
=
p
.
getFullName
();
getJobCommand
.
main
(
Collections
.
singletonList
(
pName
),
Locale
.
ENGLISH
,
System
.
in
,
new
PrintStream
(
baos
),
System
.
err
);
assertEquals
(
xmlAdmin
,
baos
.
toString
(
configXml
.
getWebResponse
().
getContentCharset
()));
assertEquals
(
xmlAdmin
,
baos
.
toString
(
configXml
.
getWebResponse
().
getContentCharset
()
.
name
()
));
CopyJobCommand
copyJobCommand
=
new
CopyJobCommand
();
copyJobCommand
.
setTransportAuth
(
adminAuth
);
String
pAdminName
=
pName
+
"-admin"
;
...
...
@@ -171,7 +171,7 @@ public class PasswordTest {
getJobCommand
.
setTransportAuth
(
devAuth
);
baos
=
new
ByteArrayOutputStream
();
getJobCommand
.
main
(
Collections
.
singletonList
(
pName
),
Locale
.
ENGLISH
,
System
.
in
,
new
PrintStream
(
baos
),
System
.
err
);
assertEquals
(
xmlDev
,
baos
.
toString
(
configXml
.
getWebResponse
().
getContentCharset
()));
assertEquals
(
xmlDev
,
baos
.
toString
(
configXml
.
getWebResponse
().
getContentCharset
()
.
name
()
));
copyJobCommand
=
new
CopyJobCommand
();
copyJobCommand
.
setTransportAuth
(
devAuth
);
String
pDevName
=
pName
+
"-dev"
;
...
...
@@ -194,7 +194,9 @@ public class PasswordTest {
}
VulnerableProperty
.
DescriptorImpl
.
incomingURL
=
null
;
String
secret
=
"s3cr3t"
;
// the fireEvent is required as setText's new behavior is not triggering the onChange event anymore
field
.
setText
(
secret
);
field
.
fireEvent
(
"change"
);
while
(
VulnerableProperty
.
DescriptorImpl
.
incomingURL
==
null
)
{
Thread
.
sleep
(
100
);
// form validation of edited value
}
...
...
test/src/test/java/lib/form/ValidateButtonTest.java
浏览文件 @
af09aaea
...
...
@@ -128,8 +128,8 @@ public class ValidateButtonTest {
descriptor
.
paramMethod
=
"validateInjection"
;
descriptor
.
paramWith
=
"a,b"
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
descriptor
.
wasCalled
=
false
;
...
...
@@ -142,8 +142,8 @@ public class ValidateButtonTest {
descriptor
.
paramMethod
=
"validateInjection',document.title='hacked'+'"
;
descriptor
.
paramWith
=
"a,b"
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
// no check on wasCalled because the button that is expected by the method is not passed (arguments are shifted due to the injection)
...
...
@@ -156,8 +156,8 @@ public class ValidateButtonTest {
descriptor
.
paramMethod
=
"validateInjection"
;
descriptor
.
paramWith
=
"a,b',document.title='hacked'+'"
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
descriptor
.
wasCalled
=
false
;
...
...
test/src/test/java/lib/layout/ConfirmationLinkTest.java
浏览文件 @
af09aaea
...
...
@@ -41,6 +41,8 @@ import org.kohsuke.stapler.WebMethod;
import
javax.annotation.CheckForNull
;
import
java.net.HttpURLConnection
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
...
...
@@ -111,8 +113,8 @@ public class ConfirmationLinkTest {
}
private
Page
getPageAfterClick
()
throws
Exception
{
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
return
HtmlElementUtil
.
click
(
getClickableLink
(
p
));
...
...
@@ -124,15 +126,15 @@ public class ConfirmationLinkTest {
testParams
.
paramClass
=
null
;
testParams
.
paramPost
=
null
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
Page
pageAfterClick
=
HtmlElementUtil
.
click
(
getClickableLink
(
p
));
assertNotEquals
(
"hacked"
,
p
.
getTitleText
());
assertTrue
(
p
.
getWebResponse
().
getContentAsString
().
contains
(
"Message to confirm the click"
));
// the url it clicks on is escaped and so does not exist
assertEquals
(
404
,
pageAfterClick
.
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_NOT_FOUND
,
pageAfterClick
.
getWebResponse
().
getStatusCode
());
}
private
void
checkInjectionInMessage
(
TestRootAction
testParams
)
throws
Exception
{
...
...
@@ -141,14 +143,14 @@ public class ConfirmationLinkTest {
testParams
.
paramClass
=
null
;
testParams
.
paramPost
=
null
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
Page
pageAfterClick
=
HtmlElementUtil
.
click
(
getClickableLink
(
p
));
assertNotEquals
(
"hacked"
,
p
.
getTitleText
());
// the url is normally the same page so it's ok
assertEquals
(
200
,
pageAfterClick
.
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
pageAfterClick
.
getWebResponse
().
getStatusCode
());
}
private
void
checkInjectionInPost
(
TestRootAction
testParams
)
throws
Exception
{
...
...
@@ -157,15 +159,15 @@ public class ConfirmationLinkTest {
testParams
.
paramClass
=
null
;
testParams
.
paramPost
=
postPayload
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
Page
pageAfterClick
=
HtmlElementUtil
.
click
(
getClickableLink
(
p
));
assertNotEquals
(
"hacked"
,
p
.
getTitleText
());
assertTrue
(
p
.
getWebResponse
().
getContentAsString
().
contains
(
"Message to confirm the click"
));
// the url is normally the same page so it's ok
assertEquals
(
200
,
pageAfterClick
.
getWebResponse
().
getStatusCode
());
assertEquals
(
HttpURLConnection
.
HTTP_OK
,
pageAfterClick
.
getWebResponse
().
getStatusCode
());
}
private
HtmlAnchor
getClickableLink
(
HtmlPage
page
){
...
...
test/src/test/java/lib/layout/StopButtonTest.java
浏览文件 @
af09aaea
...
...
@@ -77,8 +77,8 @@ public class StopButtonTest {
testParams
.
paramAlt
=
"Alternative text for icon"
;
testParams
.
paramConfirm
=
null
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
HtmlElementUtil
.
click
(
getStopLink
(
p
));
...
...
@@ -91,8 +91,8 @@ public class StopButtonTest {
testParams
.
paramAlt
=
"Alternative text for icon"
;
testParams
.
paramConfirm
=
"Confirm message"
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
HtmlElementUtil
.
click
(
getStopLink
(
p
));
...
...
@@ -105,8 +105,8 @@ public class StopButtonTest {
testParams
.
paramAlt
=
"Alternative text for icon"
;
testParams
.
paramConfirm
=
postPayload
;
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
;
wc
.
getOptions
().
set
ThrowExceptionOnFailingStatusCode
(
false
);
JenkinsRule
.
WebClient
wc
=
j
.
createWebClient
()
.
with
ThrowExceptionOnFailingStatusCode
(
false
);
HtmlPage
p
=
wc
.
goTo
(
"test"
);
HtmlElementUtil
.
click
(
getStopLink
(
p
));
...
...
war/pom.xml
浏览文件 @
af09aaea
...
...
@@ -49,7 +49,7 @@ THE SOFTWARE.
<dependency>
<groupId>
org.jenkins-ci
</groupId>
<artifactId>
executable-war
</artifactId>
<version>
1.4
4
</version>
<version>
1.4
5
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
...
...
@@ -130,7 +130,7 @@ THE SOFTWARE.
<dependency>
<groupId>
org.jenkins-ci.modules
</groupId>
<artifactId>
sshd
</artifactId>
<version>
2.
5
</version>
<version>
2.
6
</version>
</dependency>
<dependency>
<groupId>
org.jenkins-ci.ui
</groupId>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录