Skip to content
This repository
Browse code

API CHANGE Moved SapphireSoapServer and SOAPModelAccess into its own …

  • Loading branch information...
commit 9e21fb8a4a0770ab753cf826d935d1d7e3cc169d 1 parent cb8b118
Ingo Schommer authored June 04, 2012
249  api/SOAPModelAccess.php
... ...
@@ -1,249 +0,0 @@
1  
-<?php
2  
-/**
3  
- * Basic SOAP Server to access and modify DataObject instances.
4  
- * You can enable SOAP access on a DataObject by setting {@link DataObject::$api_access} to true.
5  
- * This means that you'll also enable a RESTful API through {@link RestfulServer}.
6  
- * 
7  
- * Usage - Getting a record:
8  
- * <code>
9  
- * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
10  
- * echo $c->getXML("MyClassName", 99); // gets record #99 as xml
11  
- * </code>
12  
- *
13  
- * Usage - Updating a record:
14  
- * <code>
15  
- * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
16  
- * $data = array('MyProperty' => 'MyUpdatedValue');
17  
- * echo $c->putXML("MyClassName", 99, null, $data);
18  
- * </code>
19  
- * 
20  
- * Usage - Creating a record:
21  
- * <code>
22  
- * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
23  
- * $data = array('MyProperty' => 'MyValue');
24  
- * echo $c->putXML("MyClassName", null, null, $data);
25  
- * </code>
26  
- *
27  
- * Usage - Creating a record:
28  
- * <code>
29  
- * $c = new SoapClient('http://mysite.com/soap/v1/wsdl');
30  
- * echo $c->deleteXML("MyClassName");
31  
- * </code>
32  
- *
33  
- * @todo Test relation methods
34  
- * 
35  
- * @package framework
36  
- * @subpackage api
37  
- */
38  
-class SOAPModelAccess extends SapphireSoapServer {
39  
-	
40  
-	public static $methods = array(
41  
-		'getXML' => array(
42  
-			'class' => 'string',
43  
-			'id' => 'int',
44  
-			'relation' => 'string',
45  
-			'_returns' => 'string',
46  
-		),
47  
-		'getJSON' => array(
48  
-			'class' => 'string',
49  
-			'id' => 'int',
50  
-			'relation' => 'string',
51  
-			'_returns' => 'string',
52  
-		),
53  
-		'putXML' => array(
54  
-			'class' => 'string',
55  
-			'id' => 'int',
56  
-			'relation' => 'string',
57  
-			'data' => 'string',
58  
-			'username' => 'string',
59  
-			'password' => 'string',
60  
-			'_returns' => 'boolean',
61  
-		),
62  
-		'putJSON' => array(
63  
-			'class' => 'string',
64  
-			'id' => 'int',
65  
-			'relation' => 'string',
66  
-			'_returns' => 'boolean',
67  
-		),
68  
-	);
69  
-	
70  
-	function Link($action = null) {
71  
-		return Controller::join_links("soap/v1/", $action);
72  
-	}
73  
-	
74  
-	/**
75  
-	 * Used to emulate RESTful GET requests with XML data.
76  
-	 * 
77  
-	 * @param string $class
78  
-	 * @param Number $id
79  
-	 * @param string $relation Relation name
80  
-	 * @return string
81  
-	 */
82  
-	function getXML($class, $id, $relation = false, $username = null, $password = null) {
83  
-		$this->authenticate($username, $password);
84  
-		
85  
-		$response = Director::test(
86  
-			$this->buildRestfulURL($class, $id, $relation, 'xml'),
87  
-			null,
88  
-			null,
89  
-			'GET'
90  
-		);
91  
-
92  
-		return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
93  
-	}
94  
-	
95  
-	/**
96  
-	 * Used to emulate RESTful GET requests with JSON data.
97  
-	 * 
98  
-	 * @param string $class
99  
-	 * @param Number $id
100  
-	 * @param string $relation Relation name
101  
-	 * @param string $username
102  
-	 * @param string $password
103  
-	 * @return string
104  
-	 */
105  
-	function getJSON($class, $id, $relation = false, $username = null, $password = null) {
106  
-		$this->authenticate($username, $password);
107  
-		
108  
-		$response = Director::test(
109  
-			$this->buildRestfulURL($class, $id, $relation, 'json'),
110  
-			null,
111  
-			null,
112  
-			'GET'
113  
-		);
114  
-		
115  
-		return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
116  
-	}
117  
-	
118  
-	/**
119  
-	 * Used to emulate RESTful POST and PUT requests with XML data.
120  
-	 * 
121  
-	 * @param string $class
122  
-	 * @param Number $id
123  
-	 * @param string $relation Relation name
124  
-	 * @param array $data 
125  
- 	 * @param string $username
126  
-	 * @param string $password
127  
-	 * @return string
128  
-	 */
129  
-	function putXML($class, $id = false, $relation = false, $data, $username = null, $password = null) {
130  
-		$this->authenticate($username, $password);
131  
-
132  
-		$response = Director::test(
133  
-			$this->buildRestfulURL($class, $id, $relation, 'xml'),
134  
-			array(),
135  
-			null,
136  
-			($id) ? 'PUT' : 'POST',
137  
-			$data
138  
-		);
139  
-
140  
-		return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
141  
-	}
142  
-	
143  
-	/**
144  
-	 * Used to emulate RESTful POST and PUT requests with JSON data.
145  
-	 * 
146  
-	 * @param string $class
147  
-	 * @param Number $id
148  
-	 * @param string $relation Relation name
149  
-	 * @param array $data
150  
-	 * @param string $username
151  
-	 * @param string $password
152  
-	 * @return string
153  
-	 */
154  
-	function putJSON($class = false, $id = false, $relation = false, $data, $username = null, $password = null) {
155  
-		$this->authenticate($username, $password);
156  
-		
157  
-		$response = Director::test(
158  
-			$this->buildRestfulURL($class, $id, $relation, 'json'),
159  
-			array(),
160  
-			null,
161  
-			($id) ? 'PUT' : 'POST',
162  
-			$data
163  
-		);
164  
-		
165  
-		return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
166  
-	}
167  
-	
168  
-	/**
169  
-	 * Used to emulate RESTful DELETE requests.
170  
-	 *
171  
-	 * @param string $class
172  
-	 * @param Number $id
173  
-	 * @param string $relation Relation name
174  
-	 * @param string $username
175  
-	 * @param string $password
176  
-	 * @return string
177  
-	 */
178  
-	function deleteXML($class, $id, $relation = false, $username = null, $password = null) {
179  
-		$this->authenticate($username, $password);
180  
-		
181  
-		$response = Director::test(
182  
-			$this->buildRestfulURL($class, $id, $relation, 'xml'),
183  
-			null,
184  
-			null,
185  
-			'DELETE'
186  
-		);
187  
-		
188  
-		return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
189  
-	}
190  
-	
191  
-	/**
192  
-	 * Used to emulate RESTful DELETE requests.
193  
-	 *
194  
-	 * @param string $class
195  
-	 * @param Number $id
196  
-	 * @param string $relation Relation name
197  
-	 * @param string $username
198  
-	 * @param string $password
199  
-	 * @return string
200  
-	 */
201  
-	function deleteJSON($class, $id, $relation = false, $username = null, $password = null) {
202  
-		$this->authenticate($username, $password);
203  
-		
204  
-		$response = Director::test(
205  
-			$this->buildRestfulURL($class, $id, $relation, 'json'),
206  
-			null,
207  
-			null,
208  
-			'DELETE'
209  
-		);
210  
-		
211  
-		return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
212  
-	}
213  
-	
214  
-	/**
215  
-	 * Faking an HTTP Basicauth login in the PHP environment
216  
-	 * that RestfulServer can pick up. 
217  
-	 *
218  
-	 * @param string $username Username
219  
-	 * @param string $password Plaintext password
220  
-	 */
221  
-	protected function authenticate($username, $password) {
222  
-		if(is_string($username)) $_SERVER['PHP_AUTH_USER'] = $username;
223  
-		if(is_string($password)) $_SERVER['PHP_AUTH_PW'] = $password;
224  
-	}
225  
-	
226  
-	/**
227  
-	 * @param string $class
228  
-	 * @param Number $id
229  
-	 * @param string $relation
230  
-	 * @param string $extension
231  
-	 * @return string
232  
-	 */
233  
-	protected function buildRestfulURL($class, $id, $relation, $extension) {
234  
-	   $url = "api/v1/{$class}";
235  
-	   if($id) $url .= "/{$id}";
236  
-	   if($relation) $url .= "/{$relation}";
237  
-	   if($extension) $url .= "/.{$extension}";
238  
-	   return $url;
239  
-	}
240  
-	
241  
-	/**
242  
-	 * @param SS_HTTPResponse $response
243  
-	 * @return string XML string containing the HTTP error message
244  
-	 */
245  
-	protected function getErrorMessage($response) {
246  
-		return "<error type=\"authentication\" code=\"" . $response->getStatusCode() . "\">" . $response->getStatusDescription() . "</error>";
247  
-	}
248  
-}
249  
-
103  api/SapphireSoapServer.php
... ...
@@ -1,103 +0,0 @@
1  
-<?php
2  
-/**
3  
- * Soap server class which auto-generates a WSDL
4  
- * file to initialize PHPs integrated {@link SoapServer} class.
5  
- * 
6  
- * See {@link SOAPModelAccess} for an auto-generated SOAP API for your models.
7  
- * 
8  
- * @todo Improve documentation
9  
- * @package framework
10  
- * @subpackage integration
11  
- */
12  
-class SapphireSoapServer extends Controller {
13  
-	
14  
-	/**
15  
-	 * @var array Map of method name to arguments.
16  
-	 */
17  
-	static $methods = array();
18  
-	
19  
-	/**
20  
-	 * @var array
21  
-	 */
22  
-	static $xsd_types = array(
23  
-		'int' => 'xsd:int',
24  
-		'boolean' => 'xsd:boolean',
25  
-		'string' => 'xsd:string',
26  
-		'binary' => 'xsd:base64Binary',
27  
-	);
28  
-	
29  
-	static $allowed_actions = array( 
30  
-		'index',
31  
-		'wsdl'
32  
-	);
33  
-	
34  
-	function wsdl() {
35  
-		$this->getResponse()->addHeader("Content-Type", "text/xml"); 
36  
-		
37  
-		return array();
38  
-	}
39  
-	
40  
-	/**
41  
-	 * @return string
42  
-	 */
43  
-	function getWSDLURL() {
44  
-		return Director::absoluteBaseURLWithAuth() . $this->Link() . "wsdl";
45  
-	}
46  
-	
47  
-	/**
48  
-	 * @return SS_List Collection of ArrayData elements describing
49  
-	 *  the method (keys: 'Name', 'Arguments', 'ReturnType')
50  
-	 */
51  
-	function Methods() {
52  
-		$methods = array();
53  
-		
54  
-		foreach($this->stat('methods') as $methodName => $arguments) {
55  
-			$returnType = $arguments['_returns'];
56  
-			unset($arguments['_returns']);
57  
-			
58  
-			$processedArguments = array();
59  
-			foreach($arguments as $argument => $type) {
60  
-				$processedArguments[] = new ArrayData(array(
61  
-					"Name" => $argument,
62  
-					"Type" => self::$xsd_types[$type],
63  
-				));
64  
-				
65  
-			}
66  
-			$methods[] = new ArrayData(array(
67  
-				"Name" => $methodName,
68  
-				"Arguments" => new ArrayList($processedArguments),
69  
-				"ReturnType" => self::$xsd_types[$returnType],
70  
-			));
71  
-		}
72  
-		
73  
-		return new ArrayList($methods);
74  
-	}
75  
-	
76  
-	/**
77  
-	 * @return string
78  
-	 */
79  
-	function TargetNamespace() {
80  
-		return Director::absoluteBaseURL();
81  
-	}
82  
-	
83  
-	/**
84  
-	 * @return string
85  
-	 */
86  
-	function ServiceURL() {
87  
-		return Director::absoluteBaseURLWithAuth() . $this->class . '/';
88  
-	}
89  
-	
90  
-	function index() {
91  
-		$wsdl = $this->getViewer('wsdl')->process($this);
92  
-		$wsdlFile = TEMP_FOLDER . '/sapphire-wsdl-' . $this->class;
93  
-		$fh = fopen($wsdlFile, 'w');
94  
-		fwrite($fh, $wsdl);
95  
-		fclose($fh);
96  
-
97  
-		$s = new SoapServer($wsdlFile, array('cache_wsdl' => WSDL_CACHE_NONE));
98  
-		$s->setClass($this->class);
99  
-		$s->handle();
100  
-	}
101  
-}
102  
-
103  
-
46  api/SapphireSoapServer_wsdl.ss
... ...
@@ -1,46 +0,0 @@
1  
-<?xml version="1.0"?>
2  
-<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" 
3  
-xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
4  
-xmlns:xsd="http://www.w3.org/2001/XMLSchema"
5  
-xmlns:tns="{$ServiceURL}wsdl"
6  
-targetNamespace="{$ServiceURL}wsdl">
7  
-	<% loop Methods %>
8  
-	<message name="{$Name}Request" targetNamespace="$CurrentPage.TargetNamespace">
9  
-		<% loop Arguments %>
10  
-		<part name="$Name" type="$Type"/>
11  
-		<% end_loop %>
12  
-	</message>
13  
-	<message name="{$Name}Response" targetNamespace="$CurrentPage.TargetNamespace">
14  
-		<part name="{$Name}Return" type="$ReturnType" />
15  
-	</message>
16  
-	<% end_loop %>
17  
-
18  
-	<portType name="SapphireSOAP_methodsPortType">
19  
-		<% loop Methods %>
20  
-		<operation name="$Name">
21  
-			<input message="tns:{$Name}Request"/>
22  
-			<output message="tns:{$Name}Response"/>
23  
-		</operation>
24  
-		<% end_loop %>
25  
-	</portType>
26  
-	<binding name="SapphireSOAP_methodsBinding" type="tns:SapphireSOAP_methodsPortType">
27  
-		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
28  
-		<% loop Methods %>
29  
-		<operation name="$Name">
30  
-			<soap:operation soapAction="$CurrentPage.ServiceURL?method=$Name" style="rpc"/>
31  
-			<input>
32  
-				<soap:body use="encoded" namespace="$CurrentPage.TargetNamespace" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
33  
-			</input>
34  
-			<output>
35  
-				<soap:body use="encoded" namespace="$CurrentPage.TargetNamespace" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
36  
-			</output>
37  
-		</operation>
38  
-		<% end_loop %>
39  
-	</binding>
40  
-	<service name="SapphireSOAP_methods">
41  
-		<port name="SapphireSOAP_methodsPort" binding="tns:SapphireSOAP_methodsBinding">
42  
-			<soap:address location="$CurrentPage.ServiceURL" />
43  
-		</port>
44  
-	</service>
45  
-</definitions>
46  
-
3  docs/en/changelogs/3.0.0.md
Source Rendered
@@ -520,7 +520,8 @@ See [module on github](https://github.com/silverstripe/silverstripe-widgets).
520 520
 
521 521
 ### Moved `RestfulServer` and `SapphireSoapServer` API into new modules###
522 522
 
523  
-See ["restfulserver"] and ["soapserver"] modules on github.
  523
+See ["restfulserver"](https://github.com/silverstripe/silverstripe-restfulserver) 
  524
+and ["soapserver"](https://github.com/silverstripe/silverstripe-soapserver) modules on github.
524 525
 
525 526
 ### Moved `Translatable` extension into new 'translatable' module ###
526 527
 
31  tests/api/SapphireSoapServerTest.php
... ...
@@ -1,31 +0,0 @@
1  
-<?php
2  
-/**
3  
- * @package framework
4  
- * @subpackage tests
5  
- */
6  
-class SapphireSoapServerTest extends FunctionalTest {
7  
-	
8  
-	/**
9  
-	 * @see http://open.silverstripe.com/ticket/4570
10  
-	 */
11  
-	function testWsdl() {
12  
-		$response = $this->get('SapphireSoapServerTest_MyServer/wsdl');
13  
-		
14  
-		$this->assertEquals(
15  
-			$response->getHeader('Content-Type'), 
16  
-			'text/xml',
17  
-			'wsdl request returns with correct XML content type'
18  
-		);
19  
-	}
20  
-}
21  
-
22  
-/**
23  
- * @package framework
24  
- * @subpackage tests
25  
- */
26  
-class SapphireSoapServerTest_MyServer extends SapphireSoapServer {
27  
-	
28  
-	function Link($action = null) {
29  
-		return Controller::join_links('SapphireSoapServerTest_MyServer', $action);
30  
-	}
31  
-}
162  tests/api/SoapModelAccessTest.php
... ...
@@ -1,162 +0,0 @@
1  
-<?php
2  
-/**
3  
- * 
4  
- * @todo Test Relation getters
5  
- * @todo Test filter and limit through GET params
6  
- * @todo Test DELETE verb
7  
- *
8  
- * @package framework
9  
- * @subpackage testing
10  
- */
11  
-class SoapModelAccessTest extends SapphireTest {
12  
-	
13  
-	static $fixture_file = 'SoapModelAccessTest.yml';
14  
-
15  
-	protected $extraDataObjects = array(
16  
-		'SoapModelAccessTest_Comment',
17  
-		'SoapModelAccessTest_Page',
18  
-	);
19  
-
20  
-	public function getTestSoapConnection() {
21  
-		// We can't actually test the SOAP server itself because there's not currently a way of putting it into "test mode"
22  
-		return new SOAPModelAccess();
23  
-		
24  
-		// One day, we should build this facility and then return something more like the item below:
25  
-		// return new SoapClient(Director::absoluteBaseURL() . 'soap/v1/wsdl');
26  
-	}
27  
-
28  
-	public function testApiAccess() {
29  
-		$c = $this->getTestSoapConnection();
30  
-		$soapResponse = $c->getXML(
31  
-			"SoapModelAccessTest_Comment", 
32  
-			1,
33  
-			null,
34  
-			null,
35  
-			'editor@test.com',
36  
-			'editor'
37  
-		);
38  
-
39  
-		$responseArr = Convert::xml2array($soapResponse);
40  
-		$this->assertEquals($responseArr['ID'], 1);
41  
-		$this->assertEquals($responseArr['Name'], 'Joe');
42  
-	}
43  
-	
44  
-	public function testAuthenticatedPUT() {
45  
-		$comment1 = $this->objFromFixture('SoapModelAccessTest_Comment', 'comment1');
46  
-		$comment1ID = $comment1->ID;
47  
-		
48  
-		// test wrong details
49  
-		$c = $this->getTestSoapConnection();
50  
-
51  
-		$updateXML = <<<XML
52  
-<?xml version="1.0" encoding="UTF-8"?>
53  
-		<SoapModelAccessTest_Comment>
54  
-			<ID>$comment1ID</ID>
55  
-			<Name>Jimmy</Name>
56  
-		</SoapModelAccessTest_Comment>			
57  
-XML;
58  
-
59  
-		$soapResponse = $c->putXML(
60  
-			"SoapModelAccessTest_Comment", 
61  
-			$comment1->ID,
62  
-			null,
63  
-			$updateXML,
64  
-			'editor@test.com',
65  
-			'wrongpassword'
66  
-		);
67  
-		$this->assertEquals('<error type="authentication" code="401">Unauthorized</error>', $soapResponse);
68  
-		
69  
-		// Check that the details weren't saved
70  
-		$c = $this->getTestSoapConnection();
71  
-		$soapResponse = $c->getXML("SoapModelAccessTest_Comment", $comment1->ID, null, 'editor@test.com', 'editor');
72  
-		$responseArr = Convert::xml2array($soapResponse);
73  
-		$this->assertEquals($comment1->ID, $responseArr['ID']);
74  
-		$this->assertEquals('Joe', $responseArr['Name']);
75  
-
76  
-		// Now do an update with the right password
77  
-		$soapResponse = $c->putXML(
78  
-			"SoapModelAccessTest_Comment", 
79  
-			$comment1->ID,
80  
-			null,
81  
-			$updateXML,
82  
-			'editor@test.com',
83  
-			'editor'
84  
-		);
85  
-
86  
-		// Check that the details were saved
87  
-		$c = $this->getTestSoapConnection();
88  
-		$soapResponse = $c->getXML("SoapModelAccessTest_Comment", $comment1->ID, null, 'editor@test.com', 'editor');
89  
-		$responseArr = Convert::xml2array($soapResponse);
90  
-		$this->assertEquals($comment1->ID, $responseArr['ID']);
91  
-		$this->assertEquals('Jimmy', $responseArr['Name']);
92  
-	}
93  
-	
94  
-	public function testAuthenticatedPOST() {
95  
-		/*
96  
-		$c = $this->getTestSoapConnection();
97  
-		$soapResponse = $c->getXML(
98  
-			"SoapModelAccessTest_Comment", 
99  
-			null,
100  
-			null,
101  
-			'editor@test.com',
102  
-			'editor'
103  
-		);
104  
-		Debug::message($soapResponse);
105  
-		$responseArr = Convert::xml2array($soapResponse);
106  
-		Debug::show($responseArr);
107  
-		$this->assertEquals($responseArr['Name'], 'Created Name');
108  
-		*/
109  
-	}
110  
-}
111  
-
112  
-/**
113  
- * Everybody can view comments, logged in members in the "users" group can create comments,
114  
- * but only "editors" can edit or delete them.
115  
- *
116  
- */
117  
-class SoapModelAccessTest_Comment extends DataObject implements PermissionProvider,TestOnly {
118  
-	
119  
-	static $api_access = true;
120  
-	
121  
-	static $db = array(
122  
-		"Name" => "Varchar(255)",
123  
-		"Comment" => "Text"
124  
-	);
125  
-	
126  
-	static $has_many = array();
127  
-	
128  
-	public function providePermissions(){
129  
-		return array(
130  
-			'EDIT_Comment' => 'Edit Comment Objects',
131  
-			'CREATE_Comment' => 'Create Comment Objects',
132  
-			'DELETE_Comment' => 'Delete Comment Objects',
133  
-		);
134  
-	}
135  
-	
136  
-	public function canView($member = null) {
137  
-		return true;
138  
-	}
139  
-	
140  
-	public function canEdit($member = null) {
141  
-		return Permission::checkMember($member, 'EDIT_Comment');
142  
-	}
143  
-	
144  
-	public function canDelete($member = null) {
145  
-		return Permission::checkMember($member, 'DELETE_Comment');
146  
-	}
147  
-	
148  
-	public function canCreate($member = null) {
149  
-		return Permission::checkMember($member, 'CREATE_Comment');
150  
-	}
151  
-	
152  
-}
153  
-
154  
-class SoapModelAccessTest_Page extends DataObject implements TestOnly {
155  
-	
156  
-	static $api_access = false;
157  
-	
158  
-	static $db = array(
159  
-		'Title' => 'Text',	
160  
-		'Content' => 'HTMLText',
161  
-	);
162  
-}
38  tests/api/SoapModelAccessTest.yml
... ...
@@ -1,38 +0,0 @@
1  
-SoapModelAccessTest_Comment:
2  
-   comment1:
3  
-      Name: Joe
4  
-      Comment: This is a test comment
5  
-Member:
6  
-   editor:
7  
-      FirstName: Editor
8  
-      Email: editor@test.com
9  
-      Password: editor
10  
-   user:
11  
-      FirstName: User
12  
-      Email: user@test.com
13  
-      Password: user
14  
-Group:
15  
-   editorgroup:
16  
-      Title: Editors
17  
-      Code: editors
18  
-      Members: =>Member.editor
19  
-   usergroup:
20  
-      Title: Users
21  
-      Code: users
22  
-      Members: =>Member.user
23  
-Permission:
24  
-   perm1:
25  
-      Code: CREATE_Comment
26  
-      Group: =>Group.usergroup
27  
-   perm3:
28  
-      Code: EDIT_Comment
29  
-      Group: =>Group.editorgroup
30  
-   perm4:
31  
-      Code: DELETE_Comment
32  
-      Group: =>Group.editorgroup
33  
-   perm5:
34  
-      Code: CREATE_Comment
35  
-      Group: =>Group.editorgroup
36  
-SoapModelAccessTest_Page:
37  
-   page1:
38  
-       Title: Testpage without API Access

0 notes on commit 9e21fb8

Please sign in to comment.
Something went wrong with that request. Please try again.