]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
combined the two different pams into one and fixed an issue with hmac authentication
authorcash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sat, 7 Nov 2009 22:36:23 +0000 (22:36 +0000)
committercash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sat, 7 Nov 2009 22:36:23 +0000 (22:36 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@3635 36083f99-b078-4883-b0ff-0f9b5a30f544

engine/lib/api.php
engine/lib/pam.php
engine/tests/services/api.php
services/api/rest.php

index 38b93cd3a766e2a3d83926b9c2a9a9d8bd84ecba..5372c0214aed79aaa9db43d6c75f7fd4cfb513cc 100644 (file)
@@ -411,7 +411,7 @@ function authenticate_method($method) {
        
        // check API authentication if required
        if ($API_METHODS[$method]["require_api_auth"] == true) {
-               if (api_authenticate() == false) {
+               if (pam_authenticate(null, "api") == false) {
                        throw new APIException(elgg_echo('APIException:APIAuthenticationFailed'));
                }
        }
@@ -426,65 +426,6 @@ function authenticate_method($method) {
        return true;
 }
 
-$API_AUTH_HANDLERS = array();
-
-/**
- * Register an API authorization handler
- * 
- * @param $handler
- * @param $importance
- * @return bool
- */
-function register_api_auth_handler($handler, $importance = "sufficient") {
-       global $API_AUTH_HANDLERS;
-
-       if (is_callable($handler)) {
-               $API_AUTH_HANDLERS[$handler] = new stdClass;
-
-               $API_AUTH_HANDLERS[$handler]->handler = $handler;
-               $API_AUTH_HANDLERS[$handler]->importance = strtolower($importance);
-
-               return true;
-       }
-
-       return false;   
-}
-
-/**
- * Authenticate an API method call
- * 
- * @return bool
- */
-function api_authenticate() {
-       global $API_AUTH_HANDLERS;
-
-       $authenticated = false;
-
-       foreach ($API_AUTH_HANDLERS as $k => $v) {
-               $handler = $v->handler;
-               $importance = $v->importance;
-
-               try {
-                       // Execute the handler
-                       if ($handler()) {
-                               $authenticated = true;
-                       } else {
-                               // If this is required then abort.
-                               if ($importance == 'required') {
-                                       return false;
-                               }
-                       }
-               } catch (Exception $e) {
-                       // If this is required then abort.
-                       if ($importance == 'required') {
-                               return false;
-                       }
-               }
-       }
-
-       return $authenticated;
-}
-
 /**
  * Executes a method.
  * A method is a function which you have previously exposed using expose_function.
@@ -758,7 +699,7 @@ function api_auth_hmac() {
 
        // Get api header
        $api_header = get_and_validate_api_headers();
-
+       
        // Pull API user details
        $api_user = get_api_user($CONFIG->site_id, $api_header->api_key);
 
@@ -777,7 +718,7 @@ function api_auth_hmac() {
                                                        $api_header->time,
                                                        $api_header->api_key,
                                                        $secret_key,
-                                                       $params,
+                                                       $query,
                                                        $api_header->method == 'POST' ? $api_header->posthash : "");
 
        
@@ -842,7 +783,7 @@ function get_and_validate_api_headers() {
        }
 
        // Basic timecheck, think about making this smaller if we get loads of users and the cache gets really big.
-       if (($result->time<(microtime(true)-86400.00)) || ($result->time>(microtime(true)+86400.00))) {
+       if (($result->time<(time()-86400)) || ($result->time>(time()+86400))) {
                throw new APIException(elgg_echo('APIException:TemporalDrift'));
        }
 
@@ -899,7 +840,7 @@ function map_api_hash($algo) {
  * @param $time string String representation of unix time as stored in X-Searunner-time.
  * @param $api_key string Your api key.
  * @param $secret string Your secret key.
- * @param $get_variables string URLEncoded string representation of the get variable parameters, eg "format=php&method=searunner.test".
+ * @param $get_variables string URLEncoded string representation of the get variable parameters, eg "method=user&guid=2"
  * @param $post_hash string Optional sha1 hash of the post data.
  * @return string The HMAC string.
  */
@@ -1036,8 +977,11 @@ function pam_auth_usertoken($credentials = NULL) {
        global $CONFIG;
 
        $token = get_input('auth_token');
-
-       $validated_userid = validate_user_token($token);
+       if (!$token) {
+               return false;   
+       }
+       
+       $validated_userid = validate_user_token($token, $CONFIG->site_id);
 
        if ($validated_userid) {
                $u = get_entity($validated_userid);
@@ -1218,17 +1162,11 @@ function send_api_call(array $keys, $url, array $call, $method = 'GET', $post_da
        }
 
        // Time
-       $time = microtime(true);
+       $time = time();
 
-       // URL encode all the parameters, ensuring auth_token (if present) is at the end!
+       // URL encode all the parameters
        foreach ($call as $k => $v){
-               if ($k!='auth_token') {
-                       $encoded_params[] = urlencode($k).'='.urlencode($v);
-               }
-       }
-
-       if ($call['auth_token']) {
-               $encoded_params[] = urlencode('auth_token').'='.urlencode($call['auth_token']);
+               $encoded_params[] = urlencode($k).'='.urlencode($v);
        }
 
        $params = implode('&', $encoded_params);
index 17b10b5ccfd4bdcebfb234ee99fcb5c9a45f259d..590ef9fdee79f0d0c5a56460b7054cdec9188e1b 100644 (file)
@@ -3,12 +3,13 @@
  * Elgg Simple PAM library
  * Contains functions for managing authentication.
  * This is not a full implementation of PAM. It supports a single facility 
- * (authentication) and only allows one policy at a time. There are two control
- * flags possible for each module: sufficient or required. The entire chain for 
- * a policy is processed (or until a required module fails). A module fails by 
- * returning false or throwing an exception. The order that modules are 
- * processed is determined by the order they are registered. For an example of
- * a PAM, see pam_auth_userpass() in sessions.php.
+ * (authentication) and allows multiple policies (user authentication is the
+ * default). There are two control flags possible for each module: sufficient 
+ * or required. The entire chain for a policy is processed (or until a 
+ * required module fails). A module fails by returning false or throwing an 
+ * exception. The order that modules are processed is determined by the order 
+ * they are registered. For an example of a PAM, see pam_auth_userpass() in 
+ * sessions.php.
  * 
  * For more information on PAMs see:
  * http://www.freebsd.org/doc/en/articles/pam/index.html
@@ -27,16 +28,23 @@ $_PAM_HANDLERS_MSG = array();
  *
  * @param string $handler The handler function in the format
  *             pam_handler($credentials = NULL);
- * @param string $importance The importance - "sufficient" or "required"
+ * @param string $importance The importance - "sufficient" (default) or "required"
+ * @param string $policy - the policy type, default is "user"
+ * @return boolean
  */
-function register_pam_handler($handler, $importance = "sufficient") {
+function register_pam_handler($handler, $importance = "sufficient", $policy = "user") {
        global $_PAM_HANDLERS;
 
+       // setup array for this type of pam if not already set
+       if (!isset($_PAM_HANDLERS[$policy])) {
+               $_PAM_HANDLERS[$policy] = array();
+       }
+       
        if (is_callable($handler)) {
-               $_PAM_HANDLERS[$handler] = new stdClass;
+               $_PAM_HANDLERS[$policy][$handler] = new stdClass;
 
-               $_PAM_HANDLERS[$handler]->handler = $handler;
-               $_PAM_HANDLERS[$handler]->importance = strtolower($importance);
+               $_PAM_HANDLERS[$policy][$handler]->handler = $handler;
+               $_PAM_HANDLERS[$policy][$handler]->importance = strtolower($importance);
 
                return true;
        }
@@ -48,18 +56,19 @@ function register_pam_handler($handler, $importance = "sufficient") {
  * Unregisters a PAM handler.
  *
  * @param string $handler The PAM handler function name
+ * @param string $policy - the policy type, default is "user"
  */
-function unregister_pam_handler($handler) {
+function unregister_pam_handler($handler, $policy = "user") {
        global $_PAM_HANDLERS;
 
-       unset($_PAM_HANDLERS[$handler]);
+       unset($_PAM_HANDLERS[$policy][$handler]);
 }
 
 /**
  * Attempt to authenticate.
  * This function will process all registered PAM handlers or stop when the first 
  * handler fails. A handler fails by either returning false or throwing an 
- * exception. The advatange of throwing an exception is that it returns a message
+ * exception. The advantage of throwing an exception is that it returns a message
  * through the global $_PAM_HANDLERS_MSG which can be used in communication with 
  * a user. The order that handlers are processed is determined by the order that
  * they were registered.
@@ -69,14 +78,17 @@ function unregister_pam_handler($handler) {
  * otherwise retrieved (eg from the HTTP header or $_SESSION).
  *
  * @param mixed $credentials Mixed PAM handler specific credentials (e.g. username, password)
+ * @param string $policy - the policy type, default is "user"
  * @return bool true if authenticated, false if not.
  */
-function pam_authenticate($credentials = NULL) {
+function pam_authenticate($credentials = NULL, $policy = "user") {
        global $_PAM_HANDLERS, $_PAM_HANDLERS_MSG;
 
+       $_PAM_HANDLERS_MSG = array();
+       
        $authenticated = false;
 
-       foreach ($_PAM_HANDLERS as $k => $v) {
+       foreach ($_PAM_HANDLERS[$policy] as $k => $v) {
                $handler = $v->handler;
                $importance = $v->importance;
 
index 66fff268d4d87aa0a04a7644c7d62e852175d210..28a7a64bc9c5a5d9a3ca78f1a1acfca770d2efac 100644 (file)
@@ -257,7 +257,7 @@ class ElggCoreServicesApiTest extends ElggCoreUnitTest {
        \r
 // api key methods\r
        public function testApiAuthenticate() {\r
-               $this->assertFalse(api_authenticate());\r
+               $this->assertFalse(pam_authenticate(null, "api"));\r
        }\r
        \r
        public function testApiAuthKeyNoKey() {\r
index 8ac63022d07b0ba7c6283b93150e384266e1f1fe..4d3e39aaa4e688ffd6e9f1ee4581c7dbcfba75dc 100644 (file)
@@ -34,8 +34,10 @@ if (trigger_plugin_hook('rest', 'init', null, false) == false) {
        // user token can also be used for user authentication
        register_pam_handler('pam_auth_usertoken');
 
-       // for api authentication, we default to a simple API key check
-       register_api_auth_handler('api_auth_key');
+       // simple API key check 
+       register_pam_handler('api_auth_key', "sufficient", "api");
+       // hmac 
+       register_pam_handler('api_auth_hmac', "sufficient", "api");
 }
 
 // Get parameter variables