Commit a83c2de9c6e334c34fdb017579ee5d421fee746f

Authored by Paul Barrett
1 parent 07800ae6

Added PermissionDeniedException class. Throw this on failed auth attempts (stil…

…l needed for service doc but in place for general services.) Added header for HTTP Basic Auth on failure.

Committed by: Paul Barrett
lib/api/ktcmis/exceptions/PermissionDeniedException.inc.php 0 → 100644
  1 +<?php
  2 +
  3 +class PermissionDeniedException extends Exception {
  4 +
  5 +}
  6 +
  7 +?>
... ...
lib/api/ktcmis/ktcmis.inc.php
... ... @@ -52,12 +52,14 @@ require_once(realpath(dirname(__FILE__) . &#39;/../../../config/dmsDefaults.php&#39;));
52 52 require_once(KT_DIR . '/ktapi/ktapi.inc.php');
53 53  
54 54 define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
  55 +require_once(CMIS_DIR . '/exceptions/PermissionDeniedException.inc.php');
55 56 require_once(CMIS_DIR . '/services/CMISRepositoryService.inc.php');
56 57 require_once(CMIS_DIR . '/services/CMISNavigationService.inc.php');
57 58 require_once(CMIS_DIR . '/services/CMISObjectService.inc.php');
58 59 require_once(CMIS_DIR . '/util/CMISUtil.inc.php');
59 60  
60 61 /**
  62 + * Base class for all KT CMIS classes
61 63 * Handles authentication
62 64 */
63 65 class KTCMISBase {
... ... @@ -67,6 +69,11 @@ class KTCMISBase {
67 69 static protected $ktapi;
68 70 static protected $session;
69 71  
  72 +// public function __construct($username = null, $password = null)
  73 +// {
  74 +// $this->startSession($username, $password);
  75 +// }
  76 +
70 77 // TODO try to pick up existing session if possible, i.e. if the $session value is not empty
71 78 public function startSession($username, $password)
72 79 {
... ... @@ -85,6 +92,12 @@ class KTCMISBase {
85 92 self::$ktapi = new KTAPI();
86 93 self::$session =& self::$ktapi->start_session($username, $password);
87 94 }
  95 +
  96 + // failed authentication?
  97 + if (PEAR::isError(self::$session))
  98 + {
  99 + throw new PermissionDeniedException('You must be authenticated to perform this action');
  100 + }
88 101  
89 102 // print_r(self::$ktapi);
90 103 return self::$session;
... ... @@ -181,7 +194,7 @@ class KTRepositoryService extends KTCMISBase {
181 194 * @param string $repositoryId
182 195 */
183 196 public function getTypes($repositoryId, $typeId = '', $returnPropertyDefinitions = false,
184   - $maxItems = 0, $skipCount = 0, &$hasMoreItems = false)
  197 + $maxItems = 0, $skipCount = 0, &$hasMoreItems = false)
185 198 {
186 199 try {
187 200 $repositoryObjectTypeResult = $this->RepositoryService->getTypes($repositoryId, $typeId, $returnPropertyDefinitions,
... ...
lib/api/ktcmis/services/CMISObjectService.inc.php
... ... @@ -166,6 +166,12 @@ class CMISObjectService {
166 166 $properties['name'] = $properties['title'];
167 167 }
168 168  
  169 + // TODO if name is blank! throw another exception (check type) - using invalidArgument Exception for now
  170 + if (trim($properties['name']) == '')
  171 + {
  172 + throw new InvalidArgumentException('Refusing to create an un-named document');
  173 + }
  174 +
169 175 // TODO also set to Default if a non-supported type is submitted
170 176 if ($properties['type'] == '')
171 177 {
... ... @@ -262,10 +268,10 @@ class CMISObjectService {
262 268 throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')');
263 269 }
264 270  
265   - // TODO if name is blank! throw another exception (check type) - using RuntimeException for now
  271 + // TODO if name is blank! throw another exception (check type) - using invalidArgument Exception for now
266 272 if (trim($properties['name']) == '')
267 273 {
268   - throw new RuntimeException('Refusing to create an un-named folder');
  274 + throw new InvalidArgumentException('Refusing to create an un-named folder');
269 275 }
270 276  
271 277 $response = $this->ktapi->create_folder((int)$folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = '');
... ...
webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php
... ... @@ -5,7 +5,7 @@ include_once CMIS_ATOM_LIB_FOLDER . &#39;NavigationService.inc.php&#39;;
5 5 include_once CMIS_ATOM_LIB_FOLDER . 'ObjectService.inc.php';
6 6 include_once 'KT_cmis_atom_service_helper.inc.php';
7 7  
8   -// TODO response if failed auth, need generic response which can be used by all code
  8 +// TODO auth failed response requires WWW-Authenticate: Basic realm="KnowledgeTree DMS" header
9 9  
10 10 /**
11 11 * AtomPub Service: folder
... ... @@ -13,12 +13,22 @@ include_once &#39;KT_cmis_atom_service_helper.inc.php&#39;;
13 13 * Returns children, descendants (up to arbitrary depth) or detail for a particular folder
14 14 *
15 15 */
16   -class KT_cmis_atom_service_folder extends KT_cmis_atom_service
17   -{
18   - public function GET_action()
  16 +class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
  17 +
  18 + public function GET_action()
19 19 {
20 20 $RepositoryService = new RepositoryService();
21   - $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  21 + try {
  22 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  23 + }
  24 + catch (Exception $e)
  25 + {
  26 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  27 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  28 + $this->responseFeed = $feed;
  29 + return null;
  30 + }
  31 +
22 32 $repositories = $RepositoryService->getRepositories();
23 33 $repositoryId = $repositories[0]['repositoryId'];
24 34  
... ... @@ -31,7 +41,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service
31 41 $folderId = CMISUtil::encodeObjectId('Folder', 1);
32 42 $folderName = urldecode($this->params[0]);
33 43 }
34   - // this is a bit of a hack, but then it's to accomodate a bit of a hack to work with the knowledgetree/drupal cmis modules...
35 44 else if ($this->params[0] == 'path')
36 45 {
37 46 $ktapi =& $RepositoryService->getInterface();
... ... @@ -41,43 +50,84 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service
41 50 {
42 51 $folderId = $this->params[0];
43 52 $ObjectService = new ObjectService();
44   - $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  53 +
  54 + try {
  55 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  56 + }
  57 + catch (Exception $e)
  58 + {
  59 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  60 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  61 + $this->responseFeed = $feed;
  62 + return null;
  63 + }
  64 +
45 65 $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false);
46 66 $folderName = $cmisEntry['properties']['Name']['value'];
47   -// $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $newObjectId, $cmisEntry['properties']['Name']['value']);
  67 + // $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $newObjectId, $cmisEntry['properties']['Name']['value']);
48 68 }
49 69  
50 70 if (!empty($this->params[1]) && (($this->params[1] == 'children') || ($this->params[1] == 'descendants')))
51 71 {
52 72 $NavigationService = new NavigationService();
53   - $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  73 +
  74 + try {
  75 + $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  76 + }
  77 + catch (Exception $e)
  78 + {
  79 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  80 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  81 + $this->responseFeed = $feed;
  82 + return null;
  83 + }
54 84  
55 85 $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $folderName, $this->params[1]);
56 86 }
57 87 else
58 88 {
59 89 $ObjectService = new ObjectService();
60   - $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  90 +
  91 + try {
  92 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  93 + }
  94 + catch (Exception $e)
  95 + {
  96 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  97 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  98 + $this->responseFeed = $feed;
  99 + return null;
  100 + }
61 101  
62 102 $feed = $this->getFolderFeed($ObjectService, $repositoryId, $folderId);
63 103 }
64 104  
65   - //Expose the responseFeed
66   - $this->responseFeed = $feed;
67   - }
68   -
69   - public function POST_action()
  105 + //Expose the responseFeed
  106 + $this->responseFeed = $feed;
  107 + }
  108 +
  109 + public function POST_action()
70 110 {
71   -// $username = $password = 'admin';
72 111 $RepositoryService = new RepositoryService();
73   - $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  112 +
  113 + try {
  114 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  115 + }
  116 + catch (Exception $e)
  117 + {
  118 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  119 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  120 + $this->responseFeed = $feed;
  121 + return null;
  122 + }
  123 +
74 124 $repositories = $RepositoryService->getRepositories();
75 125 $repositoryId = $repositories[0]['repositoryId'];
76 126  
77 127 $folderId = $this->params[0];
78 128 $title = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'title');
79 129 $summary = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'summary');
80   -
  130 +
81 131 $properties = array('name' => $title, 'summary' => $summary);
82 132  
83 133 // determine whether this is a folder or a document create
... ... @@ -109,7 +159,18 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service
109 159 [0]['@children']);
110 160  
111 161 $ObjectService = new ObjectService();
112   - $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  162 +
  163 + try {
  164 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  165 + }
  166 + catch (Exception $e)
  167 + {
  168 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  169 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  170 + $this->responseFeed = $feed;
  171 + return null;
  172 + }
  173 +
113 174 if ($type == 'folder')
114 175 $newObjectId = $ObjectService->createFolder($repositoryId, ucwords($cmisObjectProperties['ObjectTypeId']), $properties, $folderId);
115 176 else
... ... @@ -127,22 +188,30 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service
127 188 else
128 189 {
129 190 $NavigationService = new NavigationService();
130   - $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  191 +
  192 + try {
  193 + $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  194 + }
  195 + catch (Exception $e)
  196 + {
  197 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  198 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  199 + $this->responseFeed = $feed;
  200 + return null;
  201 + }
  202 +
131 203 $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false);
132 204 $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $cmisEntry['properties']['Name']['value']);
133 205 }
134 206 }
135 207 else
136 208 {
137   - $this->setStatus(self::STATUS_SERVER_ERROR);
138   - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Error: ' . self::STATUS_SERVER_ERROR);
139   - $entry = $feed->newEntry();
140   - $feed->newField('error', $newObjectId['message'], $entry);
  209 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $newObjectId['message']);
141 210 }
142 211  
143 212 //Expose the responseFeed
144   - $this->responseFeed = $feed;
145   - }
  213 + $this->responseFeed = $feed;
  214 + }
146 215  
147 216 /**
148 217 * Retrieves children/descendants of the specified folder
... ... @@ -169,7 +238,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service
169 238 }
170 239  
171 240 // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL
172   - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $folderName . ' ' . ucwords($feedType), null, null, null,
  241 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $folderName . ' ' . ucwords($feedType), null, null, null,
173 242 'urn:uuid:' . $folderName . '-' . $feedType);
174 243  
175 244 foreach($entries as $cmisEntry)
... ... @@ -200,14 +269,15 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service
200 269  
201 270 $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $cmisEntry['properties']['ObjectTypeId']['value'], null, null, null,
202 271 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value']);
203   -
  272 +
204 273 KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName);
205   -// // <cmis:hasMoreItems>false</cmis:hasMoreItems>
206   -// // global $folderFeed;
207   -// // $outputs =
  274 + // // <cmis:hasMoreItems>false</cmis:hasMoreItems>
  275 + // // global $folderFeed;
  276 + // // $outputs =
208 277  
209 278 return $feed;
210 279 }
  280 +
211 281 }
212 282  
213 283 /**
... ... @@ -216,15 +286,22 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service
216 286 * Returns a list of supported object types
217 287 *
218 288 */
219   -class KT_cmis_atom_service_types extends KT_cmis_atom_service
220   -{
221   - public function GET_action()
  289 +class KT_cmis_atom_service_types extends KT_cmis_atom_service {
  290 +
  291 + public function GET_action()
222 292 {
223   -// $username = $password = 'admin';
224 293 $RepositoryService = new RepositoryService();
225   - // technically do not need to log in to access this information
226   - // TODO consider requiring authentication even to access basic repository information
227   - $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  294 +
  295 + try {
  296 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  297 + }
  298 + catch (Exception $e)
  299 + {
  300 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  301 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  302 + $this->responseFeed = $feed;
  303 + return null;
  304 + }
228 305  
229 306 // fetch repository id
230 307 $repositories = $RepositoryService->getRepositories();
... ... @@ -234,9 +311,10 @@ class KT_cmis_atom_service_types extends KT_cmis_atom_service
234 311 $type = ((empty($this->params[0])) ? 'all' : $this->params[0]);
235 312 $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);
236 313  
237   - //Expose the responseFeed
238   - $this->responseFeed = $feed;
239   - }
  314 + //Expose the responseFeed
  315 + $this->responseFeed = $feed;
  316 + }
  317 +
240 318 }
241 319  
242 320 /**
... ... @@ -245,42 +323,48 @@ class KT_cmis_atom_service_types extends KT_cmis_atom_service
245 323 * Returns the type defintion for the selected type
246 324 *
247 325 */
248   -class KT_cmis_atom_service_type extends KT_cmis_atom_service
249   -{
250   - public function GET_action()
  326 +class KT_cmis_atom_service_type extends KT_cmis_atom_service {
  327 +
  328 + public function GET_action()
251 329 {
252   -// $username = $password = 'admin';
253 330 $RepositoryService = new RepositoryService();
254   - // technically do not need to log in to access this information
255   - // TODO consider requiring authentication even to access basic repository information
256   - $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  331 +
  332 + try {
  333 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  334 + }
  335 + catch (Exception $e)
  336 + {
  337 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  338 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  339 + $this->responseFeed = $feed;
  340 + return null;
  341 + }
257 342  
258 343 // fetch repository id
259 344 $repositories = $RepositoryService->getRepositories();
260 345 $repositoryId = $repositories[0]['repositoryId'];
261   -
262   - if (!isset($this->params[1]))
263   - {
264   - // For easier return in the wanted format, we call getTypes instead of getTypeDefinition.
265   - // Calling this with a single type specified returns an array containing the definition of
266   - // just the requested type.
267   - // NOTE could maybe be more efficient to call getTypeDefinition direct and then place in
268   - // an array on this side? or directly expose the individual entry response code and
269   - // call directly from here rather than via getTypeFeed.
  346 +
  347 + if (!isset($this->params[1])) {
  348 + // For easier return in the wanted format, we call getTypes instead of getTypeDefinition.
  349 + // Calling this with a single type specified returns an array containing the definition of
  350 + // just the requested type.
  351 + // NOTE could maybe be more efficient to call getTypeDefinition direct and then place in
  352 + // an array on this side? or directly expose the individual entry response code and
  353 + // call directly from here rather than via getTypeFeed.
270 354 $type = ucwords($this->params[0]);
271 355 $types = $RepositoryService->getTypes($repositoryId, $type);
272 356 $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);
273 357 }
274   - else
275   - {
276   - // TODO dynamic dates, as needed everywhere
277   - // NOTE children of types not yet implemented and we don't support any non-basic types at this time
  358 + else {
  359 + // TODO dynamic dates, as needed everywhere
  360 + // NOTE children of types not yet implemented and we don't support any non-basic types at this time
278 361 $feed = $this->getTypeChildrenFeed($this->params[1]);
279 362 }
280 363  
281   - //Expose the responseFeed
282   - $this->responseFeed=$feed;
283   - }
  364 + //Expose the responseFeed
  365 + $this->responseFeed=$feed;
  366 + }
  367 +
284 368 /**
285 369 * Retrieves a list of child types for the supplied type
286 370 *
... ... @@ -292,10 +376,10 @@ class KT_cmis_atom_service_type extends KT_cmis_atom_service
292 376 */
293 377 private function getTypeChildrenFeed()
294 378 {
295   - //Create a new response feed
296   - // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL
297   - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Child Types of ' . ucwords($this->params[0]), null, null, null,
298   - $this->params[0] . '-children');
  379 + //Create a new response feed
  380 + // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL
  381 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Child Types of ' . ucwords($this->params[0]), null, null, null,
  382 + $this->params[0] . '-children');
299 383  
300 384 // TODO actually fetch child types - to be implemented when we support child types in the API
301 385  
... ... @@ -316,8 +400,8 @@ class KT_cmis_atom_service_type extends KT_cmis_atom_service
316 400 // TODO actual dynamic listing, currently we have no objects with which to test
317 401  
318 402 // TODO
319   -// <updated>2009-06-23T13:40:32.786+02:00</updated>
320   -// <cmis:hasMoreItems>false</cmis:hasMoreItems>
  403 + // <updated>2009-06-23T13:40:32.786+02:00</updated>
  404 + // <cmis:hasMoreItems>false</cmis:hasMoreItems>
321 405 /*
322 406 // TODO need to create this dynamically now, will no longer work with static output
323 407 $output = '<?xml version="1.0" encoding="UTF-8"?>
... ... @@ -343,23 +427,31 @@ class KT_cmis_atom_service_type extends KT_cmis_atom_service
343 427 *
344 428 */
345 429 // NOTE this is always an empty document, underlying API code still to be implemented
346   -class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service
347   -{
348   - public function GET_action()
  430 +class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {
  431 +
  432 + public function GET_action()
349 433 {
350   -// $username = $password = 'admin';
351 434 $RepositoryService = new RepositoryService();
352 435 $NavigationService = new NavigationService();
353 436  
354   - $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  437 + try {
  438 + $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  439 + }
  440 + catch (Exception $e)
  441 + {
  442 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  443 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  444 + $this->responseFeed = $feed;
  445 + return null;
  446 + }
355 447  
356 448 $repositories = $RepositoryService->getRepositories();
357 449 $repositoryId = $repositories[0]['repositoryId'];
358 450  
359 451 $checkedout = $NavigationService->getCheckedoutDocs($repositoryId);
360 452  
361   - //Create a new response feed
362   - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Checked out Documents', null, null, null, 'urn:uuid:checkedout');
  453 + //Create a new response feed
  454 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Checked out Documents', null, null, null, 'urn:uuid:checkedout');
363 455  
364 456 foreach($checkedout as $document)
365 457 {
... ... @@ -382,9 +474,9 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service
382 474 $entry = null;
383 475 $feed->newField('hasMoreItems', 'false', $entry, true);
384 476  
385   - //Expose the responseFeed
386   - $this->responseFeed = $feed;
387   - }
  477 + //Expose the responseFeed
  478 + $this->responseFeed = $feed;
  479 + }
388 480  
389 481 }
390 482  
... ... @@ -394,35 +486,45 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service
394 486 * Returns detail on a particular document
395 487 *
396 488 */
397   -class KT_cmis_atom_service_document extends KT_cmis_atom_service
398   -{
399   - public function GET_action()
  489 +class KT_cmis_atom_service_document extends KT_cmis_atom_service {
  490 +
  491 + public function GET_action()
400 492 {
401   -// $username = $password = 'admin';
402 493 $RepositoryService = new RepositoryService();
403 494  
404 495 $ObjectService = new ObjectService();
405   - $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
406   -
  496 +
  497 + try {
  498 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  499 + }
  500 + catch (Exception $e)
  501 + {
  502 + $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"';
  503 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage());
  504 + $this->responseFeed = $feed;
  505 + return null;
  506 + }
  507 +
407 508 $repositories = $RepositoryService->getRepositories();
408 509 $repositoryId = $repositories[0]['repositoryId'];
409 510  
410 511 $cmisEntry = $ObjectService->getProperties($repositoryId, $this->params[0], false, false);
411 512  
412 513 //Create a new response feed
413   - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $cmisEntry['properties']['ObjectTypeId']['value'], null, null, null,
414   - 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value']);
  514 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $cmisEntry['properties']['ObjectTypeId']['value'], null, null, null,
  515 + 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value']);
415 516  
416 517 KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $cmisEntry['properties']['ParentId']['value']);
417 518  
418 519 // <cmis:hasMoreItems>false</cmis:hasMoreItems>
419 520  
420   -// global $docFeed;
421   -// $output = $docFeed;
  521 + // global $docFeed;
  522 + // $output = $docFeed;
422 523  
423   - //Expose the responseFeed
424   - $this->responseFeed=$feed;
425   - }
  524 + //Expose the responseFeed
  525 + $this->responseFeed=$feed;
  526 + }
  527 +
426 528 }
427 529  
428 530 $childrenFeed[] = '<?xml version="1.0" encoding="utf-8"?>
... ... @@ -532,7 +634,7 @@ $childrenFeed[] = &#39;&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
532 634 </entry>
533 635 </feed>';
534 636  
535   - $childrenFeed[] = '<?xml version="1.0" encoding="UTF-8"?>
  637 +$childrenFeed[] = '<?xml version="1.0" encoding="UTF-8"?>
536 638 <feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:cmis="http://www.cmis.org/2008/05" xmlns:alf="http://www.alfresco.org" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
537 639 <author><name>System</name></author>
538 640 <generator version="3.0.0 (Stable 1526)">Alfresco (Labs)</generator>
... ...
webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php
... ... @@ -112,7 +112,7 @@ class KT_cmis_atom_service_helper {
112 112 }
113 113  
114 114 //Create a new response feed
115   - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $typesHeading, null, null, null, 'urn:uuid:' . $typesString);
  115 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $typesHeading, null, null, null, 'urn:uuid:' . $typesString);
116 116  
117 117 foreach($types as $type)
118 118 {
... ... @@ -157,6 +157,16 @@ class KT_cmis_atom_service_helper {
157 157 return $feed;
158 158 }
159 159  
  160 + static public function getErrorFeed(&$service, $status, $message)
  161 + {
  162 + $service->setStatus($status);
  163 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Error: ' . $status);
  164 + $entry = $feed->newEntry();
  165 + $feed->newField('error', $message, $entry);
  166 +
  167 + return $feed;
  168 + }
  169 +
160 170 /**
161 171 * Fetches the CMIS objectId based on the path
162 172 *
... ...
webservice/classes/atompub/KT_atom_server.inc.php
1 1 <?php
2   -class KT_atom_server{
  2 +class KT_atom_server {
  3 +
  4 + public $output='';
3 5 protected $services=array();
4 6 protected $workspaceDetail=array();
5 7 protected $errors=array();
6   - public $output='';
7 8 protected $queryArray=array();
8 9 protected $serviceName='';
9 10 protected $method='';
10 11 protected $workspace='';
11   -
  12 + protected $serviceObject = null;
12 13  
13 14 public function __construct(){
14 15 }
... ...
webservice/classes/atompub/KT_atom_service.inc.php
... ... @@ -3,11 +3,11 @@ class KT_atom_service{
3 3 const STATUS_OK = '200 OK';
4 4 const STATUS_NOT_FOUND = '204 No Content';
5 5 const STATUS_NOT_ALLOWED = '204 Not Allowed';
6   - const STATUS_NOT_AUTHENTICATED = '204 Not Authenticated';
7 6 const STATUS_CREATED = '201 Created';
8 7 const STATUS_UPDATED = '200 Updated';
9 8 const STATUS_NOT_MODIFIED = '304 Not Modified'; // For use with ETag & If-None-Match headers.
10 9 const STATUS_BAD_REQUEST = '400 Bad Request'; // Client issued a wrongly constructed request
  10 + const STATUS_NOT_AUTHENTICATED = '401 Not Authenticated';
11 11 const STATUS_PRECONDITION_FAILED = '412 Precondition Failed'; // Could not update document because another a newer version exist on the server than the one you are trying to update
12 12 const STATUS_SERVER_ERROR = '500 Internal Server Error'; // Server encountered an error processing the request
13 13  
... ... @@ -56,6 +56,10 @@ class KT_atom_service{
56 56 $this->setStatus(KT_atom_service::STATUS_NOT_FOUND );
57 57 }
58 58  
  59 + public function getHeaders()
  60 + {
  61 + return $this->headers;
  62 + }
59 63  
60 64 public function render(){
61 65 return $this->responseFeed->render();
... ...
webservice/classes/atompub/cmis/KT_cmis_atom_server.inc.php
... ... @@ -119,6 +119,24 @@ class KT_cmis_atom_server extends KT_atom_server {
119 119 return false;
120 120 }
121 121  
  122 + // TODO we probably want this version in the base class for auth purposes
  123 + public function render()
  124 + {
  125 + ob_end_clean();
  126 + // possible additional headers, e.g. basic auth request
  127 + // FIXME this won't work with the service document as no service object exists
  128 + if (!is_null($this->serviceObject))
  129 + {
  130 + $headers = $this->serviceObject->getHeaders();
  131 + foreach ($headers as $header)
  132 + {
  133 + header($header);
  134 + }
  135 + }
  136 + header('Content-type: text/xml');
  137 + echo $this->output;
  138 + }
  139 +
122 140 }
123 141  
124 142 ?>
125 143 \ No newline at end of file
... ...
webservice/classes/atompub/cmis/KT_cmis_atom_service.inc.php
... ... @@ -10,17 +10,12 @@ class KT_cmis_atom_service extends KT_atom_service {
10 10  
11 11 protected function parseHeaders()
12 12 {
13   -// echo "PARSE HEADERS\n";
14 13 parent::parseHeaders();
15   -// echo "CHECKING HEADERS\n";
16   -// print_r($this->headers);
17   -// print_r($_SERVER);
18 14 // attempt to fetch auth info from supplied headers
19 15 if (!empty($this->headers['Authorization']))
20 16 {
21 17 $auth = base64_decode(preg_replace('/Basic */', '', $this->headers['Authorization']));
22 18 $authData = explode(':', $auth);
23   -// print_r($authData);
24 19 self::$authData['username'] = $authData[0];
25 20 self::$authData['password'] = $authData[1];
26 21 }
... ...
webservice/classes/atompub/cmis/KT_cmis_atom_serviceDoc.inc.php
... ... @@ -32,7 +32,7 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
35   - * Contributor( s):
  35 + * Contributor( s):
36 36 * Mark Holtzhausen <mark@knowledgetree.com>
37 37 * Paul Barrett <paul@knowledgetree.com>
38 38 *
... ... @@ -47,13 +47,13 @@ include_once(KT_ATOM_LIB_FOLDER.&#39;KT_atom_serviceDoc.inc.php&#39;);
47 47  
48 48 class KT_cmis_atom_serviceDoc extends KT_atom_serviceDoc {
49 49  
50   - // override and extend as needed
  50 +// override and extend as needed
51 51  
52 52 public $repositoryInfo = array();
53 53  
54 54 public function __construct($baseURI = NULL)
55 55 {
56   - parent::__construct();
  56 + parent::__construct();
57 57  
58 58 // get repositoryInfo
59 59 // NOTE currently we only support one repository, which will be the first one found in the repositories.xml config
... ... @@ -61,63 +61,65 @@ class KT_cmis_atom_serviceDoc extends KT_atom_serviceDoc {
61 61  
62 62 include 'services/cmis/RepositoryService.inc.php';
63 63 $RepositoryService = new RepositoryService();
  64 + // TODO add auth requirement here, don't want to even supply service doc without auth
  65 +// $RepositoryService->startSession();
64 66  
65 67 // fetch data for response
66 68 $repositories = $RepositoryService->getRepositories();
67 69 // fetch for default first repo; NOTE that this will probably have to change at some point, quick and dirty for now
68 70 $this->repositoryInfo = $RepositoryService->getRepositoryInfo($repositories[0]['repositoryId']);
69   - }
70   -
71   - protected function constructServiceDocumentHeaders()
  71 + }
  72 +
  73 + protected function constructServiceDocumentHeaders()
72 74 {
73   - $service = $this->newElement('service');
74   - $service->appendChild($this->newAttr('xmlns', 'http://www.w3.org/2007/app'));
75   - $service->appendChild($this->newAttr('xmlns:atom', 'http://www.w3.org/2005/Atom'));
  75 + $service = $this->newElement('service');
  76 + $service->appendChild($this->newAttr('xmlns', 'http://www.w3.org/2007/app'));
  77 + $service->appendChild($this->newAttr('xmlns:atom', 'http://www.w3.org/2005/Atom'));
76 78 $service->appendChild($this->newAttr('xmlns:cmis', 'http://www.cmis.org/2008/05'));
77 79 $this->service =& $service;
78   - $this->DOM->appendChild($this->service);
79   - }
80   -
81   - public function &newCollection($url = NULL, $title = NULL, $cmisCollectionType = NULL, &$ws = NULL)
  80 + $this->DOM->appendChild($this->service);
  81 + }
  82 +
  83 + public function &newCollection($url = NULL, $title = NULL, $cmisCollectionType = NULL, &$ws = NULL)
82 84 {
83   - $collection=$this->newElement('collection');
84   - $collection->appendChild($this->newAttr('href', $url));
85   - $collection->appendChild($this->newAttr('cmis:collectionType', $cmisCollectionType));
86   - $collection->appendChild($this->newElement('atom:title', $title));
87   - if(isset($ws))$ws->appendChild($collection);
88   - return $collection;
89   - }
90   -
  85 + $collection=$this->newElement('collection');
  86 + $collection->appendChild($this->newAttr('href', $url));
  87 + $collection->appendChild($this->newAttr('cmis:collectionType', $cmisCollectionType));
  88 + $collection->appendChild($this->newElement('atom:title', $title));
  89 + if(isset($ws))$ws->appendChild($collection);
  90 + return $collection;
  91 + }
  92 +
91 93 }
92 94  
93 95 /**
94   -<?xml version="1.0" encoding="utf-8"?>
95   -<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
96   - <workspace>
97   - <atom:title>Main Site</atom:title>
98   - <collection href="http://example.org/blog/main" >
99   - <atom:title>My Blog Entries</atom:title>
100   - <categories href="http://example.com/cats/forMain.cats" />
101   - </collection>
102   - <collection href="http://example.org/blog/pic" >
103   - <atom:title>Pictures</atom:title>
104   - <accept>image/png</accept>
105   - <accept>image/jpeg</accept>
106   - <accept>image/gif</accept>
107   - </collection>
108   - </workspace>
109   - <workspace>
110   - <atom:title>Sidebar Blog</atom:title>
111   - <collection href="http://example.org/sidebar/list" >
112   - <atom:title>Remaindered Links</atom:title>
113   - <accept>application/atom+xml;type=entry</accept>
114   - <categories fixed="yes">
115   - <atom:category scheme="http://example.org/extra-cats/" term="joke" />
116   - <atom:category scheme="http://example.org/extra-cats/" term="serious" />
117   - </categories>
118   - </collection>
119   - </workspace>
120   -</service>
  96 + <?xml version="1.0" encoding="utf-8"?>
  97 + <service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
  98 + <workspace>
  99 + <atom:title>Main Site</atom:title>
  100 + <collection href="http://example.org/blog/main" >
  101 + <atom:title>My Blog Entries</atom:title>
  102 + <categories href="http://example.com/cats/forMain.cats" />
  103 + </collection>
  104 + <collection href="http://example.org/blog/pic" >
  105 + <atom:title>Pictures</atom:title>
  106 + <accept>image/png</accept>
  107 + <accept>image/jpeg</accept>
  108 + <accept>image/gif</accept>
  109 + </collection>
  110 + </workspace>
  111 + <workspace>
  112 + <atom:title>Sidebar Blog</atom:title>
  113 + <collection href="http://example.org/sidebar/list" >
  114 + <atom:title>Remaindered Links</atom:title>
  115 + <accept>application/atom+xml;type=entry</accept>
  116 + <categories fixed="yes">
  117 + <atom:category scheme="http://example.org/extra-cats/" term="joke" />
  118 + <atom:category scheme="http://example.org/extra-cats/" term="serious" />
  119 + </categories>
  120 + </collection>
  121 + </workspace>
  122 + </service>
121 123  
122 124 */
123 125  
... ...