Skip to content

Commit 1949471

Browse files
committed
Allows define allowed classes per action
1 parent ff61487 commit 1949471

File tree

4 files changed

+158
-3
lines changed

4 files changed

+158
-3
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.struts2.rest.handler;
21+
22+
import java.util.Set;
23+
24+
public interface AllowedClassNames {
25+
Set<String> allowedClassNames();
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.struts2.rest.handler;
21+
22+
import java.util.Set;
23+
24+
public interface AllowedClasses {
25+
Set<Class<?>> allowedClasses();
26+
}

plugins/rest/src/main/java/org/apache/struts2/rest/handler/XStreamHandler.java

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,39 +22,114 @@
2222
package org.apache.struts2.rest.handler;
2323

2424
import com.opensymphony.xwork2.ActionInvocation;
25+
import com.opensymphony.xwork2.ModelDriven;
2526
import com.thoughtworks.xstream.XStream;
27+
import com.thoughtworks.xstream.security.ArrayTypePermission;
28+
import com.thoughtworks.xstream.security.ExplicitTypePermission;
29+
import com.thoughtworks.xstream.security.NoTypePermission;
30+
import com.thoughtworks.xstream.security.NullPermission;
31+
import com.thoughtworks.xstream.security.PrimitiveTypePermission;
32+
import com.thoughtworks.xstream.security.TypePermission;
33+
import org.apache.logging.log4j.LogManager;
34+
import org.apache.logging.log4j.Logger;
2635

2736
import java.io.IOException;
2837
import java.io.Reader;
2938
import java.io.Writer;
39+
import java.util.Collection;
40+
import java.util.Date;
41+
import java.util.Map;
42+
import java.util.Set;
3043

3144
/**
3245
* Handles XML content
3346
*/
3447
public class XStreamHandler extends AbstractContentTypeHandler {
3548

49+
private static final Logger LOG = LogManager.getLogger(XStreamHandler.class);
50+
3651
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
3752
if (obj != null) {
38-
XStream xstream = createXStream();
53+
XStream xstream = createXStream(invocation);
3954
xstream.toXML(obj, out);
4055
}
4156
return null;
4257
}
4358

4459
public void toObject(ActionInvocation invocation, Reader in, Object target) {
45-
XStream xstream = createXStream();
60+
XStream xstream = createXStream(invocation);
4661
xstream.fromXML(in, target);
4762
}
48-
63+
64+
/**
65+
* @deprecated use version with {@link ActionInvocation}
66+
*/
67+
@Deprecated
4968
protected XStream createXStream() {
69+
LOG.warn("You are using a deprecated API!");
5070
return new XStream();
5171
}
5272

73+
protected XStream createXStream(ActionInvocation invocation) {
74+
XStream stream = new XStream();
75+
LOG.debug("Clears existing permissions");
76+
stream.addPermission(NoTypePermission.NONE);
77+
78+
LOG.debug("Adds per action permissions");
79+
addPerActionPermission(invocation, stream);
80+
81+
LOG.debug("Adds default permissions");
82+
addDefaultPermissions(invocation, stream);
83+
return stream;
84+
}
85+
86+
private void addPerActionPermission(ActionInvocation invocation, XStream stream) {
87+
Object action = invocation.getAction();
88+
if (action instanceof AllowedClasses) {
89+
Set<Class<?>> allowedClasses = ((AllowedClasses) action).allowedClasses();
90+
stream.addPermission(new ExplicitTypePermission(allowedClasses.toArray(new Class[allowedClasses.size()])));
91+
}
92+
if (action instanceof AllowedClassNames) {
93+
Set<String> allowedClassNames = ((AllowedClassNames) action).allowedClassNames();
94+
stream.addPermission(new ExplicitTypePermission(allowedClassNames.toArray(new String[allowedClassNames.size()])));
95+
}
96+
if (action instanceof XStreamPermissionProvider) {
97+
Collection<TypePermission> permissions = ((XStreamPermissionProvider) action).getTypePermissions();
98+
for (TypePermission permission : permissions) {
99+
stream.addPermission(permission);
100+
}
101+
}
102+
}
103+
104+
protected void addDefaultPermissions(ActionInvocation invocation, XStream stream) {
105+
stream.addPermission(new ExplicitTypePermission(new Class[]{invocation.getAction().getClass()}));
106+
if (invocation.getAction() instanceof ModelDriven) {
107+
stream.addPermission(new ExplicitTypePermission(new Class[]{((ModelDriven) invocation.getAction()).getModel().getClass()}));
108+
}
109+
stream.addPermission(NullPermission.NULL);
110+
stream.addPermission(PrimitiveTypePermission.PRIMITIVES);
111+
stream.addPermission(ArrayTypePermission.ARRAYS);
112+
stream.addPermission(CollectionTypePermission.COLLECTIONS);
113+
stream.addPermission(new ExplicitTypePermission(new Class[]{Date.class}));
114+
}
115+
53116
public String getContentType() {
54117
return "application/xml";
55118
}
56119

57120
public String getExtension() {
58121
return "xml";
59122
}
123+
124+
private static class CollectionTypePermission implements TypePermission {
125+
126+
private static final TypePermission COLLECTIONS = new CollectionTypePermission();
127+
128+
@Override
129+
public boolean allows(Class type) {
130+
return type != null && type.isInterface() &&
131+
(Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type));
132+
}
133+
134+
}
60135
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.struts2.rest.handler;
21+
22+
import com.thoughtworks.xstream.security.TypePermission;
23+
24+
import java.util.Collection;
25+
26+
public interface XStreamPermissionProvider {
27+
Collection<TypePermission> getTypePermissions();
28+
}

0 commit comments

Comments
 (0)