提交 f1086984 编写于 作者: K Kohsuke Kawaguchi

Added an extension point to support markup in description.

上级 b4e0c797
/*
* The MIT License
*
* Copyright (c) 2010, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.markup;
import hudson.ExtensionPoint;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Hudson;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
/**
* Generalization of a function that takes text with some markup and converts that to HTML.
* Such markup is often associated with Wiki.
*
* <p>
* Use of markup, as opposed to using raw HTML, ensures certain degree of security.
*
* <p>
* This is an extension point in Hudson, allowing plugins to implement different markup formatters.
*
* <h2>Views</h2>
* <p>
* This extension point must have a valid <tt>config.jelly</tt> that feeds the constructor.
*
* @author Kohsuke Kawaguchi
* @since 1.391
* @see Hudson#getMarkupFormatter()
*/
public abstract class MarkupFormatter extends AbstractDescribableImpl<MarkupFormatter> implements ExtensionPoint {
/**
* Given the text, converts that to HTML according to whatever markup rules implicit in the implementation class.
*/
public abstract void translate(String markup, Writer output) throws IOException;
public final String translate(String markup) throws IOException {
StringWriter w = new StringWriter();
translate(markup,w);
return w.toString();
}
@Override
public MarkupFormatterDescriptor getDescriptor() {
return (MarkupFormatterDescriptor)super.getDescriptor();
}
}
/*
* The MIT License
*
* Copyright (c) 2010, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.markup;
import hudson.DescriptorExtensionList;
import hudson.model.Descriptor;
import hudson.model.Hudson;
/**
* {@link Descriptor} for {@link MarkupFormatter}.
*
* @author Kohsuke Kawaguchi
* @since 1.391
*/
public abstract class MarkupFormatterDescriptor extends Descriptor<MarkupFormatter> {
/**
* Returns all the registered {@link MarkupFormatterDescriptor}s.
*/
public static DescriptorExtensionList<MarkupFormatter,MarkupFormatterDescriptor> all() {
return Hudson.getInstance().getDescriptorList(MarkupFormatter.class);
}
}
package hudson.markup;
import hudson.Extension;
import org.kohsuke.stapler.DataBoundConstructor;
import java.io.IOException;
import java.io.Writer;
/**
* {@link MarkupFormatter} that treats the input as the raw html.
* This is the backward compatible behaviour.
*
* @author Kohsuke Kawaguchi
*/
public class RawHtmlMarkupFormatter extends MarkupFormatter {
@DataBoundConstructor
public RawHtmlMarkupFormatter() {
}
@Override
public void translate(String markup, Writer output) throws IOException {
output.write(markup);
}
@Extension
public static class DescriptorImpl extends MarkupFormatterDescriptor {
@Override
public String getDisplayName() {
return "Raw HTML";
}
}
public static MarkupFormatter INSTANCE = new RawHtmlMarkupFormatter();
}
......@@ -194,6 +194,13 @@ public abstract class Descriptor<T extends Describable<T>> implements Saveable {
public Descriptor getItemTypeDescriptorOrDie() {
return Hudson.getInstance().getDescriptorOrDie(getItemType());
}
/**
* Returns all the descriptors that produce types assignable to the item type.
*/
public List<? extends Descriptor> getApplicableDescriptors() {
return Hudson.getInstance().getDescriptorList(clazz);
}
}
protected Descriptor(Class<? extends T> clazz) {
......
/*
/*
* The MIT License
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
......@@ -40,6 +40,7 @@ import hudson.Launcher;
import hudson.Launcher.LocalLauncher;
import hudson.LocalPluginManager;
import hudson.Lookup;
import hudson.markup.MarkupFormatter;
import hudson.Plugin;
import hudson.PluginManager;
import hudson.PluginWrapper;
......@@ -63,6 +64,7 @@ import hudson.init.InitStrategy;
import hudson.lifecycle.Lifecycle;
import hudson.logging.LogRecorderManager;
import hudson.lifecycle.RestartNotSupportedException;
import hudson.markup.RawHtmlMarkupFormatter;
import hudson.model.Descriptor.FormException;
import hudson.model.labels.LabelAtom;
import hudson.model.listeners.ItemListener;
......@@ -314,6 +316,8 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
*/
private String systemMessage;
private MarkupFormatter markupFormatter;
/**
* Root directory of the system.
*/
......@@ -1066,6 +1070,26 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
return systemMessage;
}
/**
* Gets the markup formatter used in the system.
*
* @return
* never null.
* @since 1.391
*/
public MarkupFormatter getMarkupFormatter() {
return markupFormatter!=null ? markupFormatter : RawHtmlMarkupFormatter.INSTANCE;
}
/**
* Sets the markup formatter used in the system globally.
*
* @since 1.391
*/
public void setMarkupFormatter(MarkupFormatter f) {
this.markupFormatter = f;
}
/**
* Sets the system message.
*/
......@@ -2366,10 +2390,17 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
JSONObject security = json.getJSONObject("use_security");
setSecurityRealm(SecurityRealm.all().newInstanceFromRadioList(security,"realm"));
setAuthorizationStrategy(AuthorizationStrategy.all().newInstanceFromRadioList(security, "authorization"));
if (security.has("markupFormatter")) {
markupFormatter = req.bindJSON(MarkupFormatter.class,security.getJSONObject("markupFormatter"));
} else {
markupFormatter = null;
}
} else {
useSecurity = null;
setSecurityRealm(SecurityRealm.NO_AUTHENTICATION);
authorizationStrategy = AuthorizationStrategy.UNSECURED;
markupFormatter = null;
}
if (json.has("csrf")) {
......@@ -2392,7 +2423,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
}
primaryView = json.has("primaryView") ? json.getString("primaryView") : getViews().iterator().next().getViewName();
noUsageStatistics = json.has("usageStatisticsCollected") ? null : true;
{
......
<!-- no config -->
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:description>
${%blurb}
</f:description>
</j:jelly>
blurb=Treat the text as HTML and use it as is without any translation
\ No newline at end of file
......@@ -121,6 +121,8 @@ THE SOFTWARE.
<label for="sat.disabled">${%Disable}</label>
</f:entry>
<f:dropdownDescriptorSelector title="${%Markup Formatter}" field="markupFormatter" />
<f:entry title="${%Access Control}">
<table style="width:100%">
<f:descriptorRadioList title="${%Security Realm}" varName="realm"
......
<div>
In such places as project description, user description, view description, and build description,
Hudson allows users to enter some free-form text that describes something.
This configuration determines how such free-form text is converted to HTML. By default, Hudson treats
the text as HTML and use it as-is unmodified (and this is default mainly because of the backward compatibility.)
<p>
While this is convenient and people often use it to load &lt;iframe>, &lt;script>. and so on to
mash up data from other sources, this capability enables malicious users to mount
<a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS attacks</a>.
If the risk outweighs the benefit, install additional markup formatter plugins and use them.
</div>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册