/private/syncInit.php

https://github.com/ciniki/core · PHP · 151 lines · 95 code · 12 blank · 44 comment · 36 complexity · 9dc8fa72c1c3853f99cdfae85415cddd MD5 · raw file

  1. <?php
  2. //
  3. // Description
  4. // -----------
  5. // This function will initialize the sync, and pull the request from the POST content
  6. //
  7. // Arguments
  8. // ---------
  9. // ciniki_root: The root of the ciniki install, which must contain a ciniki-api.ini file.
  10. //
  11. function ciniki_core_syncInit($ciniki_root) {
  12. //
  13. // Initialize the ciniki structure, and setup the return value
  14. // to include the stat.
  15. //
  16. $ciniki = array();
  17. //
  18. // Load the config
  19. //
  20. require_once($ciniki_root . '/ciniki-mods/core/private/loadCinikiConfig.php');
  21. if( ciniki_core_loadCinikiConfig($ciniki, $ciniki_root) == false ) {
  22. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.208', 'msg'=>'Internal configuration error'));
  23. }
  24. //
  25. // Initialize Database
  26. //
  27. ciniki_core_loadMethod($ciniki, 'ciniki', 'core', 'private', 'dbInit');
  28. $rc = ciniki_core_dbInit($ciniki);
  29. if( $rc['stat'] != 'ok' ) {
  30. return $rc;
  31. }
  32. //
  33. // The synctype (type), tenant UUID (uuid) must be specifed in the URL
  34. //
  35. if( !isset($_GET) || !is_array($_GET) ) {
  36. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.209', 'msg'=>'Internal configuration error'));
  37. }
  38. //
  39. // Check the request, make sure it's valid
  40. // We only allow the sync type of tenant right now.
  41. // The remote end must pass their tenant uuid, so we know which sync connection to use.
  42. //
  43. if( !isset($_GET['type']) || $_GET['type'] != 'tenant'
  44. || !isset($_GET['uuid']) || $_GET['uuid'] == ''
  45. || !isset($_GET['from']) || $_GET['from'] == '' ) {
  46. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.210', 'msg'=>'Internal configuration error'));
  47. }
  48. $ciniki['sync'] = array('type'=>$_GET['type'], 'local_uuid'=>$_GET['uuid'], 'remote_uuid'=>$_GET['from']);
  49. //
  50. // Get the local_private_key to decode the request
  51. //
  52. ciniki_core_loadMethod($ciniki, 'ciniki', 'core', 'private', 'dbQuote');
  53. $strsql = "SELECT ciniki_tenant_syncs.id AS sync_id, "
  54. . "ciniki_tenants.id AS tnid, ciniki_tenants.uuid, "
  55. . "ciniki_tenants.sitename, "
  56. . "ciniki_tenant_syncs.status, "
  57. . "ciniki_tenant_syncs.flags, "
  58. . "local_private_key, "
  59. . "ciniki_tenant_syncs.remote_name, ciniki_tenant_syncs.remote_uuid, "
  60. . "ciniki_tenant_syncs.remote_url, ciniki_tenant_syncs.remote_public_key "
  61. . "FROM ciniki_tenants, ciniki_tenant_syncs "
  62. . "WHERE ciniki_tenants.uuid = '" . ciniki_core_dbQuote($ciniki, $ciniki['sync']['local_uuid']) . "' "
  63. . "AND ciniki_tenants.id = ciniki_tenant_syncs.tnid "
  64. . "AND ciniki_tenant_syncs.remote_uuid = '" . ciniki_core_dbQuote($ciniki, $ciniki['sync']['remote_uuid']) . "' "
  65. . "";
  66. ciniki_core_loadMethod($ciniki, 'ciniki', 'core', 'private', 'dbHashQuery');
  67. $rc = ciniki_core_dbHashQuery($ciniki, $strsql, 'ciniki.tenants', 'sync');
  68. if( $rc['stat'] != 'ok' ) {
  69. return $rc;
  70. }
  71. if( !isset($rc['sync']) ) {
  72. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.211', 'msg'=>'Internal configuration error'));
  73. }
  74. if( $rc['sync']['status'] != '10' ) {
  75. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.212', 'msg'=>'Suspended sync'));
  76. }
  77. $local_private_key = $rc['sync']['local_private_key'];
  78. $ciniki['sync']['local_private_key'] = $rc['sync']['local_private_key'];
  79. $ciniki['sync']['remote_name'] = $rc['sync']['remote_name'];
  80. $ciniki['sync']['remote_uuid'] = $rc['sync']['remote_uuid'];
  81. $ciniki['sync']['remote_url'] = $rc['sync']['remote_url'];
  82. $ciniki['sync']['remote_public_key'] = $rc['sync']['remote_public_key'];
  83. $ciniki['sync']['tnid'] = $rc['sync']['tnid'];
  84. $ciniki['sync']['sitename'] = $rc['sync']['sitename'];
  85. $ciniki['sync']['id'] = $rc['sync']['sync_id'];
  86. // uuidmaps stores the mappings from remote to local uuid
  87. $ciniki['sync']['uuidmaps'] = array();
  88. // uuids is a cache for looked up uuids in different modules
  89. $ciniki['sync']['uuids'] = array();
  90. $ciniki['syncqueue'] = array();
  91. if( isset($ciniki['config']['ciniki.core']['sync.log_lvl']) ) {
  92. $ciniki['syncloglvl'] = $ciniki['config']['ciniki.core']['sync.log_lvl'];
  93. } else {
  94. $ciniki['syncloglvl'] = 0;
  95. }
  96. $ciniki['synclogfile'] = '';
  97. //
  98. // unserialize the POST content
  99. //
  100. if( isset($_POST) && is_array($_POST) ) {
  101. $encrypted_content = file_get_contents("php://input");
  102. // unencrypt
  103. // private_decrypt and encrypt can only be used for short strings
  104. // if( !openssl_private_decrypt($encrypted_content, $decrypted_content, $local_private_key) ) {
  105. $arsp = preg_split('/:::/', $encrypted_content);
  106. if( count($arsp) != 2 || !isset($arsp[1]) ) {
  107. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.213', 'msg'=>'Invalid request'));
  108. }
  109. if( !openssl_open(base64_decode($arsp[1]), $decrypted_content, base64_decode($arsp[0]), $local_private_key) ) {
  110. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.214', 'msg'=>'Internal configuration error'));
  111. }
  112. // unserialize
  113. $request = unserialize($decrypted_content);
  114. if( !is_array($request) ) {
  115. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.215', 'msg'=>'Internal configuration error'));
  116. }
  117. $ciniki['request'] = $request;
  118. //
  119. // Check the ts to make sure it's within 1 minute of UTC
  120. // This makes sure that the request is current, and not a cut and paste, listening in the middle. If
  121. // the timestamp decrypts and is accurate, it is assumed the request is valid.
  122. //
  123. date_default_timezone_set('UTC');
  124. if( !isset($ciniki['request']['ts'])
  125. || $ciniki['request']['ts'] <= 0
  126. || abs(time() - $ciniki['request']['ts']) > 60 ) {
  127. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.216', 'msg'=>'System Clocks out of sync'));
  128. }
  129. if( !isset($ciniki['request']['method'])
  130. || $ciniki['request']['method'] == ''
  131. ) {
  132. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.217', 'msg'=>'No action specified'));
  133. }
  134. } else {
  135. return array('stat'=>'fail', 'err'=>array('code'=>'ciniki.core.218', 'msg'=>'Invalid request'));
  136. }
  137. return array('stat'=>'ok', 'ciniki'=>$ciniki);
  138. }
  139. ?>