]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/OAuthTokens/OAuthToken.php
Release 6.4.1
[Github/sugarcrm.git] / modules / OAuthTokens / OAuthToken.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39
40 require_once 'Zend/Oauth/Provider.php';
41 require_once 'modules/OAuthKeys/OAuthKey.php';
42
43 class OAuthToken extends SugarBean
44 {
45         public $module_dir = 'OAuthTokens';
46         public $object_name = 'OAuthToken';
47         public $table_name = 'oauth_tokens';
48         public $disable_row_level_security = true;
49
50         public $token;
51     public $secret;
52     public $tstate;
53     public $token_ts;
54     public $verify;
55     public $consumer;
56     public $assigned_user_id;
57     public $consumer_obj;
58     // authdata is not preserved so far since we don't have any useful data yet
59     // so it's an extension point for the future
60     public $authdata;
61
62     const REQUEST = 1;
63     const ACCESS = 2;
64     const INVALID = 3;
65
66     function __construct($token='', $secret='')
67         {
68             parent::SugarBean();
69         $this->token = $token;
70         $this->secret = $secret;
71         $this->setState(self::REQUEST);
72         }
73
74         /**
75          * Set token state
76          * @param int $s
77          * @return OAuthToken
78          */
79         public function setState($s)
80         {
81             $this->tstate = $s;
82             return $this;
83         }
84
85         /**
86          * Associate the token with the consumer key
87          * @param OAuthKey $consumer
88          */
89         public function setConsumer($consumer)
90         {
91             $this->consumer = $consumer->id;
92             $this->consumer_obj = $consumer;
93             return $this;
94         }
95
96         /**
97          * Generate random token
98          * @return string
99          */
100         protected static function randomValue()
101         {
102             return bin2hex(Zend_Oauth_Provider::generateToken(6));
103         }
104
105         /**
106          * Generate random token/secret pair and create token
107          * @return OAuthToken
108          */
109     static function generate()
110     {
111         $t = self::randomValue();
112         $s = self::randomValue();
113         return new self($t, $s);
114     }
115
116     public function save()
117     {
118         $this->token_ts = time();
119         if(!isset($this->id)) {
120             $this->new_with_id = true;
121             $this->id = $this->token;
122         }
123         parent::save();
124     }
125
126     /**
127      * Load token by ID
128      * @param string $token
129          * @return OAuthToken
130      */
131     static function load($token)
132         {
133             $ltoken = new self();
134             $ltoken->retrieve($token);
135         if(empty($ltoken->id)) return null;
136         $ltoken->token = $ltoken->id;
137         if(!empty($ltoken->consumer)) {
138             $ltoken->consumer_obj = new OAuthKey();
139             $ltoken->consumer_obj->retrieve($ltoken->consumer);
140             if(empty($ltoken->consumer_obj->id)) {
141                 return null;
142             }
143         }
144         return $ltoken;
145         }
146
147         /**
148          * Invalidate token
149          */
150         public function invalidate()
151         {
152             $this->setState(self::INVALID);
153             $this->verify = false;
154             return $this->save();
155         }
156
157         /**
158          * Authorize request token
159          * @param mixed $authdata
160          * @return string Validation token
161          */
162         public function authorize($authdata)
163         {
164             if($this->tstate != self::REQUEST) {
165                 return false;
166             }
167             $this->verify = self::randomValue();
168             $this->authdata = $authdata;
169             if(isset($authdata['user'])) {
170                 $this->assigned_user_id = $authdata['user'];
171             }
172             $this->save();
173             return $this->verify;
174         }
175
176         /**
177          * Copy auth data between tokens
178          * @param OAuthToken $token
179          * @return OAuthToken
180          */
181         public function copyAuthData(OAuthToken $token)
182         {
183             $this->authdata = $token->authdata;
184             $this->assigned_user_id = $token->assigned_user_id;
185             return $this;
186         }
187
188         /**
189          * Get query string for the token
190          */
191         public function queryString()
192         {
193             return "oauth_token={$this->token}&oauth_token_secret={$this->secret}";
194         }
195
196         /**
197          * Clean up stale tokens
198          */
199     static public function cleanup()
200         {
201             global $db;
202             // delete invalidated tokens older than 1 day
203             $db->query("DELETE FROM oauth_token WHERE status = ".self::INVALID." AND token_ts < ".time()-60*60*24);
204             // delete request tokens older than 1 day
205             $db->query("DELETE FROM oauth_token WHERE status = ".self::REQUEST." AND token_ts < ".time()-60*60*24);
206         }
207
208         /**
209          * Check if the nonce is valid
210          * @param string $key
211          * @param string $nonce
212          * @param string $ts
213          */
214         public static function checkNonce($key, $nonce, $ts)
215         {
216             global $db;
217
218             $res = $db->query(sprintf("SELECT * FROM oauth_nonce WHERE conskey='%s' AND nonce_ts > %d", $db->quote($key), $ts));
219             if($res && $db->fetchByAssoc($res)) {
220                 // we have later ts
221                 return Zend_Oauth_Provider::BAD_TIMESTAMP;
222             }
223
224             $res = $db->query(sprintf("SELECT * FROM oauth_nonce WHERE conskey='%s' AND nonce='%s' AND nonce_ts = %d", $db->quote($key), $db->quote($nonce), $ts));
225             if($res && $db->fetchByAssoc($res)) {
226                 // Already seen this one
227                 return Zend_Oauth_Provider::BAD_NONCE;
228         }
229         $db->query(sprintf("DELETE FROM oauth_nonce WHERE conskey='%s' AND nonce_ts < %d", $db->quote($key), $ts));
230         $db->query(sprintf("INSERT INTO oauth_nonce(conskey, nonce, nonce_ts) VALUES('%s', '%s', %d)", $db->quote($key), $db->quote($nonce), $ts));
231             return Zend_Oauth_Provider::OK;
232         }
233
234         public function mark_deleted($id)
235         {
236             $this->db->query("DELETE from {$this->table_name} WHERE id='".$this->db->quote($id)."'");
237         }
238 }
239
240 function displayDateFromTs($focus, $field, $value, $view='ListView')
241 {
242     $field = strtoupper($field);
243     if(!isset($focus[$field])) return '';
244     global $timedate;
245     return $timedate->asUser($timedate->fromTimestamp($focus[$field]));
246 }