Basic API and Authentication extensions.
这个提交包含在:
		
							父节点
							
								
									205fd1bab5
								
							
						
					
					
						当前提交
						8a793391ad
					
				
					共有  12 个文件被更改,包括 1312 次插入 和 0 次删除
				
			
		
							
								
								
									
										141
									
								
								application/controllers/api.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										141
									
								
								application/controllers/api.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,141 @@ | |||
| <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | ||||
| 
 | ||||
| class API extends CI_Controller { | ||||
| 
 | ||||
| 	// Do absolutely nothing
 | ||||
| 	function index() | ||||
| 	{ | ||||
| 		//load the model and get results
 | ||||
| 		$this->load->model('logbook_model'); | ||||
| 		$data['data'] = array(); | ||||
| 
 | ||||
| 		// load the view
 | ||||
| 		//$this->load->view('layout/header');
 | ||||
| 		$this->load->view('api/index', $data); | ||||
| 		//$this->load->view('layout/footer');
 | ||||
| 	} | ||||
| 
 | ||||
| 	// FUNCTION: search()
 | ||||
| 	// Handle search requests
 | ||||
| 	/* | ||||
| 		Okay, so here's how it works in a nutshell... | ||||
| 
 | ||||
| 		******************************************************************* | ||||
| 		Because this is effectively just a filter between the query string | ||||
| 		and a MySQL statement, if done wrong we're just asking for pain. | ||||
| 
 | ||||
| 		DO NOT alter any of the filtering statements without fully | ||||
| 		understanding what you're doing. CodeIgniter provides some | ||||
| 		protection against unwanted characters in the query string, but | ||||
| 		this should in no way be relied upon for safety. | ||||
| 		******************************************************************* | ||||
| 
 | ||||
| 		Example query:- | ||||
| 		.../search/query[Call~M0*(and)(Locator~I*(or)Locator~J*)]/limit[10]/fields[distinct(Call),Locator]/order[Call(asc)] | ||||
| 
 | ||||
| 		There's four parts to this query, separated with forward slashes. It's effectively a heavily-sanitised | ||||
| 		MySQL query, hence the hideous search and replace code blocks below. | ||||
| 
 | ||||
| 		FIELDS | ||||
| 		------ | ||||
| 		Straightforward - input is sanitised and passed on - in the example, this ends up as "DISTINCT (Call),Locator", | ||||
| 		which is then the first argument to 'SELECT' | ||||
| 
 | ||||
| 		QUERY | ||||
| 		----- | ||||
| 		This forms the 'WHERE' clause. | ||||
| 
 | ||||
| 		* '(and)' and '(or)' are expanded out to ' AND ' and ' OR ' | ||||
| 		* Parentheses are preserved | ||||
| 		* '~' is expanded out to ' LIKE ' | ||||
| 		* '*' is translated to '%' | ||||
| 		* Values are encapsulated in quote marks | ||||
| 
 | ||||
| 		So in the example, this translates to "WHERE Call LIKE 'M0%' AND (Locator LIKE 'I%' OR Locator LIKE 'J%')" | ||||
| 
 | ||||
| 		ORDER | ||||
| 		----- | ||||
| 		Sanitised, so our example ends up as "ORDER BY Call ASC". | ||||
| 
 | ||||
| 		LIMIT | ||||
| 		----- | ||||
| 		Straightforward - what's between the square brackets is passed as an argument to 'LIMIT' | ||||
| 
 | ||||
| 		Finally, once this has been done, each field name is translated to the MySQL column name. | ||||
| 	*/ | ||||
| 
 | ||||
| 	function search() | ||||
| 	{ | ||||
| 		// Load the API and Logbook models
 | ||||
| 		$this->load->model('api_model'); | ||||
| 		$this->load->model('logbook_model'); | ||||
| 
 | ||||
| 		// Retrieve the arguments from the query string
 | ||||
| 		$arguments = $this->_retrieve(); | ||||
| 	 | ||||
| 		// Call the parser within the API model to build the query
 | ||||
| 		$query = $this->api_model->parse($arguments); | ||||
| 
 | ||||
| 		// Execute the query, and retrieve the results
 | ||||
| 		$s = $this->logbook_model->api_search_query($query); | ||||
| 		$results = $s['results']; | ||||
| 
 | ||||
| 		// Cycle through the results, and translate between MySQL column names
 | ||||
| 		// and more friendly, descriptive names
 | ||||
| 		$a = 0; | ||||
| 		if($results->num_rows != 0) | ||||
| 		{ | ||||
| 			foreach ($results->result() as $row) { | ||||
| 				$record = (array)$row; | ||||
| 				$r[$a]['rid'] = $a; | ||||
| 				while (list($key, $val) = each($record)) { | ||||
| 					$r[$a][$this->api_model->name($key)] = $val; | ||||
| 				} | ||||
|        			$a++; | ||||
| 			} | ||||
| 			// Add the result record to the main results array
 | ||||
| 	    	$data['data']['search_Result']['results'] = $r; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// We've got no results, so make this empty for completeness
 | ||||
| 		    $data['data']['search_Result']['results'] = ""; | ||||
| 		} | ||||
| 		 | ||||
| 		// Add some debugging information to the XML output
 | ||||
| 		$data['data']['queryInfo']['call'] = "search"; | ||||
| 		$data['data']['queryInfo']['dbQuery'] = $s['query']; | ||||
| 		$data['data']['queryInfo']['numResults'] = $a; | ||||
| 		$data['data']['queryInfo']['executionTime'] = $s['time']; | ||||
| 
 | ||||
| 		// Load the XML output view
 | ||||
| 		$this->load->view('api/index', $data); | ||||
| 	} | ||||
| 
 | ||||
| 	// FUNCTION: _retrieve()
 | ||||
| 	// Pull the search query arguments from the query string
 | ||||
| 	private function _retrieve() | ||||
| 	{ | ||||
| 		// This whole function could probably have been done in one line... if this was Perl.
 | ||||
| 		$arguments = array(); | ||||
| 
 | ||||
| 		// Retrieve each arguments
 | ||||
| 		$query = preg_grep("/^query\[(.*)\]$/", $this->uri->segments); | ||||
| 		$limit = preg_grep("/^limit\[(.*)\]$/", $this->uri->segments); | ||||
| 		$order = preg_grep("/^order\[(.*)\]$/", $this->uri->segments); | ||||
| 		$fields = preg_grep("/^fields\[(.*)\]$/", $this->uri->segments); | ||||
| 
 | ||||
| 		// Strip each argument
 | ||||
| 		$arguments['query'] = substr(array_pop($query), 6); | ||||
| 		$arguments['query'] = substr($arguments['query'], 0, strlen($arguments['query']) - 1); | ||||
| 		$arguments['limit'] = substr(array_pop($limit), 6); | ||||
| 		$arguments['limit'] = substr($arguments['limit'], 0, strlen($arguments['limit']) - 1); | ||||
| 		$arguments['order'] = substr(array_pop($order), 6); | ||||
| 		$arguments['order'] = substr($arguments['order'], 0, strlen($arguments['order']) - 1); | ||||
| 		$arguments['fields'] = substr(array_pop($fields), 7); | ||||
| 		$arguments['fields'] = substr($arguments['fields'], 0, strlen($arguments['fields']) - 1); | ||||
| 
 | ||||
| 		// Return the arguments
 | ||||
| 		return $arguments; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										95
									
								
								application/controllers/auth.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										95
									
								
								application/controllers/auth.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,95 @@ | |||
| <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | ||||
| 
 | ||||
| class Auth extends CI_Controller { | ||||
| 
 | ||||
| 	/* Displays all notes in a list */ | ||||
| 	public function index() | ||||
| 	{ | ||||
| 		$this->load->model('auth_model'); | ||||
| 
 | ||||
| 		echo "<pre>"; | ||||
| 		echo "Querying for user...\n"; | ||||
| 		$u = $this->auth_model->get("m0vkga"); | ||||
| 		print_r($u); | ||||
| 		echo "Test hashing\n"; | ||||
| 		echo $this->auth_model->test(); | ||||
| 
 | ||||
| 	} | ||||
| 	/* | ||||
| 		$this->load->model('note'); | ||||
| 		$data['notes'] = $this->note->list_all(); | ||||
| 	 | ||||
| 		$this->load->view('layout/header'); | ||||
| 		$this->load->view('notes/main', $data); | ||||
| 		$this->load->view('layout/footer'); | ||||
| 	} | ||||
| 	 | ||||
| 	function add() { | ||||
| 	 | ||||
| 		$this->load->model('note'); | ||||
| 	 | ||||
| 		$this->load->library('form_validation'); | ||||
| 
 | ||||
| 		$this->form_validation->set_rules('title', 'Note Title', 'required'); | ||||
| 		$this->form_validation->set_rules('content', 'Content', 'required'); | ||||
| 
 | ||||
| 
 | ||||
| 		if ($this->form_validation->run() == FALSE) | ||||
| 		{ | ||||
| 			$this->load->view('layout/header'); | ||||
| 			$this->load->view('notes/add'); | ||||
| 			$this->load->view('layout/footer'); | ||||
| 		} | ||||
| 		else | ||||
| 		{	 | ||||
| 			$this->note->add(); | ||||
| 			 | ||||
| 			redirect('notes'); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	function view($id) { | ||||
| 		$this->load->model('note'); | ||||
| 		 | ||||
| 		$data['note'] = $this->note->view($id); | ||||
| 		 | ||||
| 		// Display
 | ||||
| 		$this->load->view('layout/header'); | ||||
| 		$this->load->view('notes/view',$data); | ||||
| 		$this->load->view('layout/footer'); | ||||
| 	} | ||||
| 	 | ||||
| 	function edit($id) { | ||||
| 		$this->load->model('note'); | ||||
| 		$data['id'] = $id; | ||||
| 		 | ||||
| 		$data['note'] = $this->note->view($id); | ||||
| 			 | ||||
| 		$this->load->library('form_validation'); | ||||
| 
 | ||||
| 		$this->form_validation->set_rules('title', 'Note Title', 'required'); | ||||
| 		$this->form_validation->set_rules('content', 'Content', 'required'); | ||||
| 
 | ||||
| 
 | ||||
| 		if ($this->form_validation->run() == FALSE) | ||||
| 		{ | ||||
| 			$this->load->view('layout/header'); | ||||
| 			$this->load->view('notes/edit', $data); | ||||
| 			$this->load->view('layout/footer'); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			$this->note->edit(); | ||||
| 			 | ||||
| 			redirect('notes'); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	function delete($id) { | ||||
| 		$this->load->model('note'); | ||||
| 		$this->note->delete($id); | ||||
| 		 | ||||
| 		redirect('notes'); | ||||
| 	} | ||||
| */ | ||||
| } | ||||
							
								
								
									
										319
									
								
								application/models/api_model.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										319
									
								
								application/models/api_model.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,319 @@ | |||
| <?php | ||||
| 
 | ||||
| class API_Model extends CI_Model { | ||||
| 
 | ||||
|     function __construct() | ||||
|     { | ||||
|         // Call the Model constructor
 | ||||
|         parent::__construct(); | ||||
|     } | ||||
| 
 | ||||
| 	// FUNCTION: string name(string $column)
 | ||||
| 	// Converts a MySQL column name to a more friendly name
 | ||||
| 	function name($col) | ||||
| 	{ | ||||
| 		if($this->_columnName[$col]) | ||||
| 		{ | ||||
| 			return $this->_columnName[$col]['Name']; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// FUNCTION: string description(string $column)
 | ||||
| 	// Returns the description for a MySQL column name
 | ||||
| 	function description($col) | ||||
| 	{ | ||||
| 		if($this->_columnName[$col]) | ||||
| 		{ | ||||
| 			if($this->_columnName[$col]['Description'] != "") | ||||
| 			{ | ||||
| 				return $this->_columnName[$col]['Description']; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return "No description available"; | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// FUNCTION: string name(string $name)
 | ||||
| 	// Converts a friendly name to a MySQL column name
 | ||||
| 	function column($name) | ||||
| 	{ | ||||
| 		while ($column = current($this->_columnName)) | ||||
| 		{ | ||||
| 			if($this->_columnName[key($this->_columnName)]['Name'] == $name) | ||||
| 			{ | ||||
| 				return key($this->_columnName); | ||||
| 			} | ||||
| 			next($this->_columnName); | ||||
| 		} | ||||
| 
 | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	// FUNCTION: string parse(array $arguments)
 | ||||
| 	// Converts an array of arguments into a MySQL query string
 | ||||
| 	// See documentation for search() under the API controller for more details
 | ||||
| 	function parse($arguments) | ||||
| 	{ | ||||
| 		// Initialise our string
 | ||||
| 		$q = "SELECT "; | ||||
| 
 | ||||
| 		// Cycle through the fields, converting friendly names to MySQL column names
 | ||||
| 		if($arguments['fields'] != "") { | ||||
| 			$field = ""; | ||||
| 			$fields = explode(",", $arguments['fields']); | ||||
| 			foreach ($fields as $f) { | ||||
| 				if($field != "") { | ||||
| 					$field .= ","; | ||||
| 				} | ||||
| 				// Add field to the query, with '++' placeholders for later translation
 | ||||
| 				$field .= "++$f++"; | ||||
| 			} | ||||
| 			// Handle any DISTINCT arguments
 | ||||
| 			$field = str_replace("++distinct(", "DISTINCT(++", $field); | ||||
| 			$field = str_replace(")++", "++)", $field); | ||||
| 			// Add the MySQL column name to the query
 | ||||
| 			$q .= $field." "; | ||||
| 		} else { | ||||
| 			// If no fields are specified, display all fields
 | ||||
| 			$q .= "* "; | ||||
| 		} | ||||
| 
 | ||||
| 		// Append the table we're pulling data from
 | ||||
| 		$q .= "FROM ".$this->config->item('table_name'); | ||||
| 
 | ||||
| 		// Parse the 'query' string, which is converted into a standard MySQL 'WHERE'
 | ||||
| 		// clause.
 | ||||
| 		// $s and $r can be refactored into single array definitions, but during
 | ||||
| 		// development it's easier to list them in this way for quick reference.
 | ||||
| 		if($arguments['query'] != "") | ||||
| 		{ | ||||
| 			$q .= " WHERE "; | ||||
| 			$s = null; | ||||
| 			$r = null; | ||||
| 			// (and), becomes ' AND '
 | ||||
| 			$s[0]   = '/(and)/'; | ||||
| 			// (or), becomes ' OR '
 | ||||
| 			$s[1]   = '/(or)/'; | ||||
| 			// <, >, [ and ] all translated from their urlencoded forms
 | ||||
| 			$s[2]   = '/%3C/'; | ||||
| 			$s[3]   = '/%3E/'; | ||||
| 			$s[4]   = '/%5B/'; | ||||
| 			$s[5]   = '/%5D/'; | ||||
| 			// FieldName=, which becomes '++FieldName++ = '
 | ||||
| 			$s[6]   = '/([a-zA-Z0-9\-\_\*\(\)\=\~]+)=/'; | ||||
| 			// =Value, which becomes '= 'Value''
 | ||||
| 			$s[7]   = '/=([a-zA-Z0-9\-\_\*\(\)\=\~]+)/'; | ||||
| 			// now(), which becomes 'UNIX_TIMESTAMP(NOW())'
 | ||||
| 			$s[8]   = '/now()/'; | ||||
| 			// (, and ), which are translated to their non-HTML entity forms,
 | ||||
| 			// and with added padding
 | ||||
| 			$s[9]   = '/(/'; | ||||
| 			$s[10]  = '/)/'; | ||||
| 			// FieldName~, becomes '++FieldName++ LIKE~'
 | ||||
| 			$s[11]  = '/([a-zA-Z0-9\-\_\*\(\)\=\~]+)~/'; | ||||
| 			// ~Value, becomes ' 'Value''
 | ||||
| 			$s[12]  = '/~([a-zA-Z0-9\-\_\*\(\)\=\~]+)/'; | ||||
| 			// *, which becomes '%'
 | ||||
| 			$s[13]  = '/\*/'; | ||||
| 	 | ||||
| 			$r[0]   = ' AND '; | ||||
| 			$r[1]   = ' OR '; | ||||
| 			$r[2]   = ' < '; | ||||
| 			$r[3]   = ' > '; | ||||
| 			$r[4]   = '['; | ||||
| 			$r[5]   = ']'; | ||||
| 			$r[6]   = '++$1++ ='; | ||||
| 			$r[7]   = '= \'$1\''; | ||||
| 			$r[8]   = 'UNIX_TIMESTAMP(NOW())'; | ||||
| 			$r[9]   = '( '; | ||||
| 			$r[10]  = ' )'; | ||||
| 			$r[11]  = '++$1++ LIKE~'; | ||||
| 			$r[12]  = ' \'$1\''; | ||||
| 			$r[13]  = '%'; | ||||
| 
 | ||||
| 			// Bulk replace everything
 | ||||
| 			$q .= preg_replace($s, $r, $arguments['query']); | ||||
| 		} | ||||
| 
 | ||||
| 		// Parse any order arguments
 | ||||
| 		if($arguments['order'] != "") | ||||
| 		{ | ||||
| 			$q .= " ORDER BY "; | ||||
| 
 | ||||
| 			$s = null; | ||||
| 			$r = null; | ||||
| 			$s[0]   = '/(/'; | ||||
| 			$s[1]	= '/)/'; | ||||
| 			$s[2]	= '/([a-zA-Z0-9\-\_]+)([,\(]{1}|$)/'; | ||||
| 		    $s[3]   = '/\(asc\)/'; | ||||
| 	    	$s[4]   = '/\(desc\)/'; | ||||
| 			$s[5]	= '/,$/'; | ||||
| 
 | ||||
| 			$r[0]	= '('; | ||||
| 			$r[1]	= ')'; | ||||
| 			$r[2]	= '++$1++ $2'; | ||||
| 		    $r[3]   = ' ASC '; | ||||
| 		    $r[4]   = ' DESC '; | ||||
| 			$r[5]	= ''; | ||||
| 
 | ||||
| 			$q .= preg_replace($s, $r, $arguments['order']); | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		// Do search/replace on field names, to convert from friendly names
 | ||||
| 		// to MySQL column names
 | ||||
| 		while (list($key, $val) = each($this->_columnName)) { | ||||
| 			$q = str_replace("++".$val['Name']."++", $key, $q); | ||||
| 		} | ||||
| 
 | ||||
| 		// Parse any limit arguments
 | ||||
| 		if($arguments['limit'] != "") | ||||
| 		{ | ||||
| 			// Add the limit arguments, removing any characters other than numbers and commas
 | ||||
| 			$q .= " LIMIT " . preg_replace(array("/[^0-9\,]/","/,$/"), "", $arguments['limit']); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// If no limit argument is given, default to the first 20 results
 | ||||
| 			$q .= " LIMIT 0,20"; | ||||
| 		} | ||||
| 
 | ||||
| 		return $q; | ||||
| 	} | ||||
| 
 | ||||
| 	// ARRAY: $_columnName
 | ||||
| 	// An array matching MySQL column names to friendly names, descriptions and types
 | ||||
| 	private $_columnName = array( | ||||
| 		'COL_PRIMARY_KEY'				=> array('Name' => 'ID', 'Description' => 'Unique QSO ID', 'Type' => 'I'), | ||||
| 		'COL_ADDRESS'					=> array('Name' => 'Address', 'Description' => 'Operator\'s address', 'Type' => 'S'), | ||||
| 		'COL_AGE'						=> array('Name' => 'Age', 'Description' => 'Operator\'s age', 'Type' => 'I'), | ||||
| 		'COL_A_INDEX'					=> array('Name' => 'AIndex', 'Description' => 'Solar A Index', 'Type' => 'I'), | ||||
| 		'COL_ANT_AZ'					=> array('Name' => 'AntennaAzimuth', 'Description' => 'Antenna azimuth', 'Type' => 'I'), | ||||
| 		'COL_ANT_EL'					=> array('Name' => 'AntennaElevation', 'Description' => 'Antenna elevation', 'Type' => 'I'), | ||||
| 		'COL_ANT_PATH'					=> array('Name' => 'AntennaPath', 'Description' => 'Antenna path', 'Type' => ''), | ||||
| 		'COL_ARRL_SECT'					=> array('Name' => 'ARRLSection', 'Description' => 'ARRL Section', 'Type' => ''), | ||||
| 		'COL_BAND'						=> array('Name' => 'Band', 'Description' => 'Band', 'Type' => ''), | ||||
| 		'COL_BAND_RX'					=> array('Name' => 'BandRX', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_BIOGRAPHY'					=> array('Name' => 'Biography', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CALL'						=> array('Name' => 'Call', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CHECK'						=> array('Name' => 'UNK_CHECK', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CLASS'						=> array('Name' => 'Class', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CNTY'						=> array('Name' => 'County', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_COMMENT'					=> array('Name' => 'Comment', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CONT'						=> array('Name' => 'Continent', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CONTACTED_OP'				=> array('Name' => 'UNK_CONTACTED_OP', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CONTEST_ID'				=> array('Name' => 'ContestID', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_COUNTRY'					=> array('Name' => 'Country', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CQZ'						=> array('Name' => 'CQZone', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_DISTANCE'					=> array('Name' => 'Distance', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_DXCC'						=> array('Name' => 'DXCC', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_EMAIL'						=> array('Name' => 'EMail', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_EQ_CALL'					=> array('Name' => 'UNK_EQ_CALL', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_EQSL_QSLRDATE'				=> array('Name' => 'EQSLRecievedDate', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_EQSL_QSLSDATE'				=> array('Name' => 'EQSLSentDate', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_EQSL_QSL_RCVD'				=> array('Name' => 'EQSLRecieved', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_EQSL_QSL_SENT'				=> array('Name' => 'EQSLSent', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_EQSL_STATUS'				=> array('Name' => 'EQSLStatus', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_FORCE_INIT'				=> array('Name' => 'UNK_FORCE_INIT', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_FREQ'						=> array('Name' => 'Frequency', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_FREQ_RX'					=> array('Name' => 'FrequencyRX', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_GRIDSQUARE'				=> array('Name' => 'Locator', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_HEADING'					=> array('Name' => 'Heading', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_IOTA'						=> array('Name' => 'IOTA', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_ITUZ'						=> array('Name' => 'ITUZone', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_K_INDEX'					=> array('Name' => 'KIndex', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_LAT'						=> array('Name' => 'Latitude', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_LON'						=> array('Name' => 'Longitude', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_LOTW_QSLRDATE'				=> array('Name' => 'LOTWRecievedDate', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_LOTW_QSLSDATE'				=> array('Name' => 'LOTWSentDate', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_LOTW_QSL_RCVD'				=> array('Name' => 'LOTWRecieved', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_LOTW_QSL_SENT'				=> array('Name' => 'LOTWSent', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_LOTW_STATUS'				=> array('Name' => 'LOTWStatus', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MAX_BURSTS'				=> array('Name' => 'MaxBursts', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MODE'						=> array('Name' => 'Mode', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MS_SHOWER'					=> array('Name' => 'MSShower', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_CITY'					=> array('Name' => 'MyCity', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_CNTY'					=> array('Name' => 'MyCounty', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_COUNTRY'				=> array('Name' => 'MyCountry', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_CQ_ZONE'				=> array('Name' => 'MyCQZone', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_GRIDSQUARE'				=> array('Name' => 'MyLocator', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_IOTA'					=> array('Name' => 'MyIOTA', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_ITU_ZONE'				=> array('Name' => 'MyITUZone', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_LAT'					=> array('Name' => 'MyLatitude', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_LON'					=> array('Name' => 'MyLongitude', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_NAME'					=> array('Name' => 'MyName', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_POSTAL_CODE'			=> array('Name' => 'MyPostalCode', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_RIG'					=> array('Name' => 'MyRig', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_SIG'					=> array('Name' => 'MySig', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_SIG_INFO'				=> array('Name' => 'MySigInfo', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_STATE'					=> array('Name' => 'MyState', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_MY_STREET'					=> array('Name' => 'MyStreet', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_NAME'						=> array('Name' => 'Name', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_NOTES'						=> array('Name' => 'Notes', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_NR_BURSTS'					=> array('Name' => 'NumBursts', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_NR_PINGS'					=> array('Name' => 'NumPings', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_OPERATOR'					=> array('Name' => 'Operator', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_OWNER_CALLSIGN'			=> array('Name' => 'OwnerCallsign', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_PFX'						=> array('Name' => 'Prefix', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_PRECEDENCE'				=> array('Name' => 'Precedence', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_PROP_MODE'					=> array('Name' => 'PropMode', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_PUBLIC_KEY'				=> array('Name' => 'PublicKey', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSLMSG'					=> array('Name' => 'QSLMessage', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSLRDATE'					=> array('Name' => 'QSLRecievedDate', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSLSDATE'					=> array('Name' => 'QSLSentDate', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSL_RCVD'					=> array('Name' => 'QSLRecieved', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSL_RCVD_VIA'				=> array('Name' => 'QSLRecievedVia', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSL_SENT'					=> array('Name' => 'QSLSent', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSL_SENT_VIA'				=> array('Name' => 'QSLSentVia', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSL_VIA'					=> array('Name' => 'QSLVia', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSO_COMPLETE'				=> array('Name' => 'QSOComplete', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QSO_RANDOM'				=> array('Name' => 'QSORandom', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_QTH'						=> array('Name' => 'QTH', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_RIG'						=> array('Name' => 'Rig', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_RST_RCVD'					=> array('Name' => 'ReportRecieved', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_RST_SENT'					=> array('Name' => 'ReportSent', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_RX_PWR'					=> array('Name' => 'RXPower', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SAT_MODE'					=> array('Name' => 'SatMode', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SAT_NAME'					=> array('Name' => 'SatName', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SFI'						=> array('Name' => 'SFI', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SIG'						=> array('Name' => 'Sig', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SIG_INFO'					=> array('Name' => 'SigInfo', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SRX'						=> array('Name' => 'UNK_SRX', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_STX'						=> array('Name' => 'UNK_STX', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SRX_STRING'				=> array('Name' => 'UNK_SRX_STRING', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_STX_STRING'				=> array('Name' => 'UNK_STX_STRING', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_STATE'						=> array('Name' => 'State', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_STATION_CALLSIGN'			=> array('Name' => 'StationCall', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_SWL'						=> array('Name' => 'SWL', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_TEN_TEN'					=> array('Name' => 'TenTen', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_TIME_OFF'					=> array('Name' => 'TimeOff', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_TIME_ON'					=> array('Name' => 'TimeOn', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_TX_PWR'					=> array('Name' => 'TXPower', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_WEB'						=> array('Name' => 'Website', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_0'			=> array('Name' => 'UNK_USER_DEFINED_0', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_1'			=> array('Name' => 'UNK_USER_DEFINED_1', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_2'			=> array('Name' => 'UNK_USER_DEFINED_2', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_3'			=> array('Name' => 'UNK_USER_DEFINED_3', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_4'			=> array('Name' => 'UNK_USER_DEFINED_4', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_5'			=> array('Name' => 'UNK_USER_DEFINED_5', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_6'			=> array('Name' => 'UNK_USER_DEFINED_6', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_7'			=> array('Name' => 'UNK_USER_DEFINED_7', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_8'			=> array('Name' => 'UNK_USER_DEFINED_8', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_USER_DEFINED_9'			=> array('Name' => 'UNK_USER_DEFINED_9', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CREDIT_GRANTED'			=> array('Name' => 'UNK_CREDIT_GRANTED', 'Description' => '', 'Type' => ''), | ||||
| 		'COL_CREDIT_SUBMITTED'			=> array('Name' => 'UNK_CREDIT_SUBMITTED', 'Description' => '', 'Type' => ''), | ||||
| 	); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| ?>
 | ||||
|  | @ -0,0 +1,95 @@ | |||
| <?php | ||||
| 
 | ||||
| // Uses 'phpass' from http://www.openwall.com/phpass/ to implement password hashing
 | ||||
| require_once('application/third_party/PasswordHash.php'); | ||||
| 
 | ||||
| class Auth_Model extends CI_Model { | ||||
| 
 | ||||
|     function __construct() | ||||
|     { | ||||
|         // Call the Model constructor
 | ||||
|         parent::__construct(); | ||||
|     } | ||||
| 
 | ||||
| 	// Test function, can be removed once class is complete
 | ||||
| 	function test() { | ||||
| 		$hash = $this->_hash("password"); | ||||
| 		echo "Password hashed is '".$hash."\n"; | ||||
| 		echo "Does 'password' match '$hash'? result is ".$this->_auth("password", $hash)."\n"; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	// Retrieve a user
 | ||||
| 	function get($username) { | ||||
| 		$this->db->where('user_name', $username); | ||||
| 		$r = $this->db->get($this->config->item('auth_table')); | ||||
| 		if($r->num_rows == 1) { | ||||
| 			return $r->result(); | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	function exists($username) { | ||||
| 		if($this->get($username)->num_rows == 0) { | ||||
| 			return 0; | ||||
| 		} else { | ||||
| 			return 1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	function add($username, $password, $email, $type) { | ||||
| 		if(!$this->exists($username)) { | ||||
| 			$data = array( | ||||
| 				'user_name' => $username, | ||||
| 				'user_password' => $this->_hash($password), | ||||
| 				'user_email' => $email, | ||||
| 				'user_type' => $type | ||||
| 			); | ||||
| 
 | ||||
| 			$this->db->insert($this->config->item('auth_table')); | ||||
| 			return 1; | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	function authenticate($username, $password) { | ||||
| 		$u = $this->get($username); | ||||
| 		if($this->_hash($password, $u['user_password'])) { | ||||
| 			return 1; | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	function set($username, $data) { | ||||
| 		$this->db->where('user_name', $username); | ||||
| 		$this->db->update($this->config->item('auth_table', $data)); | ||||
| 		return 1; | ||||
| 	} | ||||
| 
 | ||||
| 	private function _auth($password, $hash) { | ||||
| 		$h = new PasswordHash(8, FALSE); | ||||
| 		if($h->CheckPassword($password, $hash)) { | ||||
| 			return 1; | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private function _hash($password) { | ||||
| 		$h = new PasswordHash(8, FALSE); | ||||
| 		$hash = $h->HashPassword($password); | ||||
| 		unset($h); | ||||
| 
 | ||||
| 		if(strlen($hash) < 20) { | ||||
| 			return 0; | ||||
| 		} else { | ||||
| 			return $hash; | ||||
| 		} | ||||
| 	} | ||||
| 		 | ||||
| } | ||||
| 
 | ||||
| ?>
 | ||||
							
								
								
									
										253
									
								
								application/third_party/PasswordHash.php
									
									
									
									
										vendored
									
									
										普通文件
									
								
							
							
						
						
									
										253
									
								
								application/third_party/PasswordHash.php
									
									
									
									
										vendored
									
									
										普通文件
									
								
							|  | @ -0,0 +1,253 @@ | |||
| <?php | ||||
| #
 | ||||
| # Portable PHP password hashing framework.
 | ||||
| #
 | ||||
| # Version 0.3 / genuine.
 | ||||
| #
 | ||||
| # Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
 | ||||
| # the public domain.  Revised in subsequent years, still public domain.
 | ||||
| #
 | ||||
| # There's absolutely no warranty.
 | ||||
| #
 | ||||
| # The homepage URL for this framework is:
 | ||||
| #
 | ||||
| #	http://www.openwall.com/phpass/
 | ||||
| #
 | ||||
| # Please be sure to update the Version line if you edit this file in any way.
 | ||||
| # It is suggested that you leave the main version number intact, but indicate
 | ||||
| # your project name (after the slash) and add your own revision information.
 | ||||
| #
 | ||||
| # Please do not change the "private" password hashing method implemented in
 | ||||
| # here, thereby making your hashes incompatible.  However, if you must, please
 | ||||
| # change the hash type identifier (the "$P$") to something different.
 | ||||
| #
 | ||||
| # Obviously, since this code is in the public domain, the above are not
 | ||||
| # requirements (there can be none), but merely suggestions.
 | ||||
| #
 | ||||
| class PasswordHash { | ||||
| 	var $itoa64; | ||||
| 	var $iteration_count_log2; | ||||
| 	var $portable_hashes; | ||||
| 	var $random_state; | ||||
| 
 | ||||
| 	function PasswordHash($iteration_count_log2, $portable_hashes) | ||||
| 	{ | ||||
| 		$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; | ||||
| 
 | ||||
| 		if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31) | ||||
| 			$iteration_count_log2 = 8; | ||||
| 		$this->iteration_count_log2 = $iteration_count_log2; | ||||
| 
 | ||||
| 		$this->portable_hashes = $portable_hashes; | ||||
| 
 | ||||
| 		$this->random_state = microtime(); | ||||
| 		if (function_exists('getmypid')) | ||||
| 			$this->random_state .= getmypid(); | ||||
| 	} | ||||
| 
 | ||||
| 	function get_random_bytes($count) | ||||
| 	{ | ||||
| 		$output = ''; | ||||
| 		if (is_readable('/dev/urandom') && | ||||
| 		    ($fh = @fopen('/dev/urandom', 'rb'))) { | ||||
| 			$output = fread($fh, $count); | ||||
| 			fclose($fh); | ||||
| 		} | ||||
| 
 | ||||
| 		if (strlen($output) < $count) { | ||||
| 			$output = ''; | ||||
| 			for ($i = 0; $i < $count; $i += 16) { | ||||
| 				$this->random_state = | ||||
| 				    md5(microtime() . $this->random_state); | ||||
| 				$output .= | ||||
| 				    pack('H*', md5($this->random_state)); | ||||
| 			} | ||||
| 			$output = substr($output, 0, $count); | ||||
| 		} | ||||
| 
 | ||||
| 		return $output; | ||||
| 	} | ||||
| 
 | ||||
| 	function encode64($input, $count) | ||||
| 	{ | ||||
| 		$output = ''; | ||||
| 		$i = 0; | ||||
| 		do { | ||||
| 			$value = ord($input[$i++]); | ||||
| 			$output .= $this->itoa64[$value & 0x3f]; | ||||
| 			if ($i < $count) | ||||
| 				$value |= ord($input[$i]) << 8; | ||||
| 			$output .= $this->itoa64[($value >> 6) & 0x3f]; | ||||
| 			if ($i++ >= $count) | ||||
| 				break; | ||||
| 			if ($i < $count) | ||||
| 				$value |= ord($input[$i]) << 16; | ||||
| 			$output .= $this->itoa64[($value >> 12) & 0x3f]; | ||||
| 			if ($i++ >= $count) | ||||
| 				break; | ||||
| 			$output .= $this->itoa64[($value >> 18) & 0x3f]; | ||||
| 		} while ($i < $count); | ||||
| 
 | ||||
| 		return $output; | ||||
| 	} | ||||
| 
 | ||||
| 	function gensalt_private($input) | ||||
| 	{ | ||||
| 		$output = '$P$'; | ||||
| 		$output .= $this->itoa64[min($this->iteration_count_log2 + | ||||
| 			((PHP_VERSION >= '5') ? 5 : 3), 30)]; | ||||
| 		$output .= $this->encode64($input, 6); | ||||
| 
 | ||||
| 		return $output; | ||||
| 	} | ||||
| 
 | ||||
| 	function crypt_private($password, $setting) | ||||
| 	{ | ||||
| 		$output = '*0'; | ||||
| 		if (substr($setting, 0, 2) == $output) | ||||
| 			$output = '*1'; | ||||
| 
 | ||||
| 		$id = substr($setting, 0, 3); | ||||
| 		# We use "$P$", phpBB3 uses "$H$" for the same thing
 | ||||
| 		if ($id != '$P$' && $id != '$H$') | ||||
| 			return $output; | ||||
| 
 | ||||
| 		$count_log2 = strpos($this->itoa64, $setting[3]); | ||||
| 		if ($count_log2 < 7 || $count_log2 > 30) | ||||
| 			return $output; | ||||
| 
 | ||||
| 		$count = 1 << $count_log2; | ||||
| 
 | ||||
| 		$salt = substr($setting, 4, 8); | ||||
| 		if (strlen($salt) != 8) | ||||
| 			return $output; | ||||
| 
 | ||||
| 		# We're kind of forced to use MD5 here since it's the only
 | ||||
| 		# cryptographic primitive available in all versions of PHP
 | ||||
| 		# currently in use.  To implement our own low-level crypto
 | ||||
| 		# in PHP would result in much worse performance and
 | ||||
| 		# consequently in lower iteration counts and hashes that are
 | ||||
| 		# quicker to crack (by non-PHP code).
 | ||||
| 		if (PHP_VERSION >= '5') { | ||||
| 			$hash = md5($salt . $password, TRUE); | ||||
| 			do { | ||||
| 				$hash = md5($hash . $password, TRUE); | ||||
| 			} while (--$count); | ||||
| 		} else { | ||||
| 			$hash = pack('H*', md5($salt . $password)); | ||||
| 			do { | ||||
| 				$hash = pack('H*', md5($hash . $password)); | ||||
| 			} while (--$count); | ||||
| 		} | ||||
| 
 | ||||
| 		$output = substr($setting, 0, 12); | ||||
| 		$output .= $this->encode64($hash, 16); | ||||
| 
 | ||||
| 		return $output; | ||||
| 	} | ||||
| 
 | ||||
| 	function gensalt_extended($input) | ||||
| 	{ | ||||
| 		$count_log2 = min($this->iteration_count_log2 + 8, 24); | ||||
| 		# This should be odd to not reveal weak DES keys, and the
 | ||||
| 		# maximum valid value is (2**24 - 1) which is odd anyway.
 | ||||
| 		$count = (1 << $count_log2) - 1; | ||||
| 
 | ||||
| 		$output = '_'; | ||||
| 		$output .= $this->itoa64[$count & 0x3f]; | ||||
| 		$output .= $this->itoa64[($count >> 6) & 0x3f]; | ||||
| 		$output .= $this->itoa64[($count >> 12) & 0x3f]; | ||||
| 		$output .= $this->itoa64[($count >> 18) & 0x3f]; | ||||
| 
 | ||||
| 		$output .= $this->encode64($input, 3); | ||||
| 
 | ||||
| 		return $output; | ||||
| 	} | ||||
| 
 | ||||
| 	function gensalt_blowfish($input) | ||||
| 	{ | ||||
| 		# This one needs to use a different order of characters and a
 | ||||
| 		# different encoding scheme from the one in encode64() above.
 | ||||
| 		# We care because the last character in our encoded string will
 | ||||
| 		# only represent 2 bits.  While two known implementations of
 | ||||
| 		# bcrypt will happily accept and correct a salt string which
 | ||||
| 		# has the 4 unused bits set to non-zero, we do not want to take
 | ||||
| 		# chances and we also do not want to waste an additional byte
 | ||||
| 		# of entropy.
 | ||||
| 		$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | ||||
| 
 | ||||
| 		$output = '$2a$'; | ||||
| 		$output .= chr(ord('0') + $this->iteration_count_log2 / 10); | ||||
| 		$output .= chr(ord('0') + $this->iteration_count_log2 % 10); | ||||
| 		$output .= '$'; | ||||
| 
 | ||||
| 		$i = 0; | ||||
| 		do { | ||||
| 			$c1 = ord($input[$i++]); | ||||
| 			$output .= $itoa64[$c1 >> 2]; | ||||
| 			$c1 = ($c1 & 0x03) << 4; | ||||
| 			if ($i >= 16) { | ||||
| 				$output .= $itoa64[$c1]; | ||||
| 				break; | ||||
| 			} | ||||
| 
 | ||||
| 			$c2 = ord($input[$i++]); | ||||
| 			$c1 |= $c2 >> 4; | ||||
| 			$output .= $itoa64[$c1]; | ||||
| 			$c1 = ($c2 & 0x0f) << 2; | ||||
| 
 | ||||
| 			$c2 = ord($input[$i++]); | ||||
| 			$c1 |= $c2 >> 6; | ||||
| 			$output .= $itoa64[$c1]; | ||||
| 			$output .= $itoa64[$c2 & 0x3f]; | ||||
| 		} while (1); | ||||
| 
 | ||||
| 		return $output; | ||||
| 	} | ||||
| 
 | ||||
| 	function HashPassword($password) | ||||
| 	{ | ||||
| 		$random = ''; | ||||
| 
 | ||||
| 		if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) { | ||||
| 			$random = $this->get_random_bytes(16); | ||||
| 			$hash = | ||||
| 			    crypt($password, $this->gensalt_blowfish($random)); | ||||
| 			if (strlen($hash) == 60) | ||||
| 				return $hash; | ||||
| 		} | ||||
| 
 | ||||
| 		if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) { | ||||
| 			if (strlen($random) < 3) | ||||
| 				$random = $this->get_random_bytes(3); | ||||
| 			$hash = | ||||
| 			    crypt($password, $this->gensalt_extended($random)); | ||||
| 			if (strlen($hash) == 20) | ||||
| 				return $hash; | ||||
| 		} | ||||
| 
 | ||||
| 		if (strlen($random) < 6) | ||||
| 			$random = $this->get_random_bytes(6); | ||||
| 		$hash = | ||||
| 		    $this->crypt_private($password, | ||||
| 		    $this->gensalt_private($random)); | ||||
| 		if (strlen($hash) == 34) | ||||
| 			return $hash; | ||||
| 
 | ||||
| 		# Returning '*' on error is safe here, but would _not_ be safe
 | ||||
| 		# in a crypt(3)-like function used _both_ for generating new
 | ||||
| 		# hashes and for validating passwords against existing hashes.
 | ||||
| 		return '*'; | ||||
| 	} | ||||
| 
 | ||||
| 	function CheckPassword($password, $stored_hash) | ||||
| 	{ | ||||
| 		$hash = $this->crypt_private($password, $stored_hash); | ||||
| 		if ($hash[0] == '*') | ||||
| 			$hash = crypt($password, $stored_hash); | ||||
| 
 | ||||
| 		return $hash == $stored_hash; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| ?>
 | ||||
							
								
								
									
										117
									
								
								application/views/api/index.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										117
									
								
								application/views/api/index.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,117 @@ | |||
| <?php | ||||
| 
 | ||||
| // Set the content-type for browsers
 | ||||
| header("Content-type: text/xml"); | ||||
| 
 | ||||
| // Create the DOMDocument for the XML output
 | ||||
| $xmlDoc = new DOMDocument("1.0"); | ||||
| // Add reference to the XSLT
 | ||||
| $xsl = $xmlDoc->createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"/css/api.xsl\""); | ||||
| $xmlDoc->appendChild($xsl); | ||||
| 
 | ||||
| // Get the method called, and build the root node
 | ||||
| $call = $data['queryInfo']['call']; | ||||
| $rootNode = $xmlDoc->createElement("HRDWebLogbook-API"); | ||||
| $parentNode = $xmlDoc->appendChild($rootNode); | ||||
| 
 | ||||
| // Get the results output
 | ||||
| $output = $data[$call."_Result"]; | ||||
| 
 | ||||
| // Add the queryInfo node
 | ||||
| $node = $xmlDoc->createElement("queryInfo"); | ||||
| $queryElement = $parentNode->appendChild($node); | ||||
| $queryElement->setAttribute("timeStamp", date("r", time())); | ||||
| $queryElement->setAttribute("calledMethod", $data['queryInfo']['call']); | ||||
| //$queryElement->setAttribute("queryArgs", $queryArgsString);
 | ||||
| $queryElement->setAttribute("resultsCount", count($data['queryInfo']['numResults'])); | ||||
| if(ENVIRONMENT == "development") { | ||||
| 	$debugInfo = $xmlDoc->createElement("debugInfo"); | ||||
| 	$debugElement = $queryElement->appendChild($debugInfo); | ||||
| 	$debugElement->setAttribute("dbQuery", $data['queryInfo']['dbQuery']); | ||||
| 	$debugElement->setAttribute("clientVersion", $_SERVER['HTTP_USER_AGENT']); | ||||
| 	$debugElement->setAttribute("requestURI", $_SERVER['REQUEST_URI']); | ||||
| 	$debugElement->setAttribute("benchMark", $this->benchmark->marker['total_execution_time_start'].", ".$this->benchmark->marker['loading_time:_base_classes_start'].", ".$this->benchmark->marker['loading_time:_base_classes_end'].", ".$this->benchmark->marker['controller_execution_time_( api / search )_start']); | ||||
| } | ||||
| $queryElement->setAttribute("executionTime", $data['queryInfo']['executionTime']); | ||||
| $queryElement->setAttribute("logbookURL", $this->config->item('base_url')); | ||||
| 
 | ||||
| // Add the main results node
 | ||||
| $node = $xmlDoc->createElement("elements"); | ||||
| $elementsNode = $parentNode->appendChild($node); | ||||
| 
 | ||||
| // Cycle through the results and add to the results node
 | ||||
| if($output['results']) | ||||
| { | ||||
| 	foreach($output['results'] as $e) { | ||||
| 		$node = $xmlDoc->createElement("element"); | ||||
| 		$element = $elementsNode->appendChild($node); | ||||
| 
 | ||||
| 		foreach($e as $attr) { | ||||
| 		#while($attr = current($e)) {
 | ||||
| 		    if(is_array($attr)) | ||||
| 			{ | ||||
| 			  foreach($attr as $subattr) | ||||
| 			  { | ||||
| 				$node = $xmlDoc->createElement(key($e)); | ||||
| 				foreach($subattr as $subsubattr) | ||||
| 				{ | ||||
| 				  $node->setAttribute(key($subattr), $subsubattr); | ||||
| 				  next($subattr); | ||||
| 				} | ||||
| 				$element->appendChild($node); | ||||
| 			  } | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 			  $element->setAttribute(key($e), $attr); | ||||
| 			} | ||||
| 			next($e); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Output formatted XML
 | ||||
| echo formatXmlString($xmlDoc->saveXML()); | ||||
| 
 | ||||
| // This function tidies up the outputted XML
 | ||||
| function formatXmlString($xml) { | ||||
| 
 | ||||
|   // add marker linefeeds to aid the pretty-tokeniser (adds a linefeed between all tag-end boundaries)
 | ||||
|   $xml = preg_replace('/(>)(<)(\/*)/', "$1\n$2$3", $xml); | ||||
| 
 | ||||
|   // now indent the tags
 | ||||
|   $token      = strtok($xml, "\n"); | ||||
|   $result     = ''; // holds formatted version as it is built
 | ||||
|   $pad        = 0; // initial indent
 | ||||
|   $matches    = array(); // returns from preg_matches()
 | ||||
| 
 | ||||
|   // scan each line and adjust indent based on opening/closing tags
 | ||||
|   while ($token !== false) : | ||||
| 
 | ||||
|     // test for the various tag states
 | ||||
| 
 | ||||
|     // 1. open and closing tags on same line - no change
 | ||||
|     if (preg_match('/.+<\/\w[^>]*>$/', $token, $matches)) : | ||||
|       $indent=0; | ||||
|     // 2. closing tag - outdent now
 | ||||
|     elseif (preg_match('/^<\/\w/', $token, $matches)) : | ||||
|       $pad--; | ||||
|     // 3. opening tag - don't pad this one, only subsequent tags
 | ||||
|     elseif (preg_match('/^<\w[^>]*[^\/]>.*$/', $token, $matches)) : | ||||
|       $indent=1; | ||||
|     // 4. no indentation needed
 | ||||
|     else : | ||||
|       $indent = 0; | ||||
|     endif; | ||||
| 
 | ||||
|     // pad the line with the required number of leading spaces
 | ||||
|     $line    = str_pad($token, strlen($token)+$pad, ' ', STR_PAD_LEFT); | ||||
|     $result .= $line . "\n"; // add to the cumulative result, with linefeed
 | ||||
|     $token   = strtok("\n"); // get the next token
 | ||||
|     $pad    += $indent; // update the pad size for subsequent lines
 | ||||
|   endwhile; | ||||
| 
 | ||||
|   return $result; | ||||
| } | ||||
| 
 | ||||
| ?>
 | ||||
							
								
								
									
										70
									
								
								application/views/auth/add.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										70
									
								
								application/views/auth/add.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,70 @@ | |||
| <h2>Add Note</h2> | ||||
| <div class="wrap_content"> | ||||
| <?php echo validation_errors(); ?>
 | ||||
| <form method="post" action="<?php echo site_url('notes/add'); ?>" name="notes_add" id="notes_add"> | ||||
| <table> | ||||
| 	<tr> | ||||
| 		<td><label for="title">Title</label></td> | ||||
| 		<td><input type="text" name="title" value="" /></td> | ||||
| 	</tr> | ||||
| 	 | ||||
| 	<tr> | ||||
| 		<td><label for="category">Category</label></td> | ||||
| 		<td><select name="category"> | ||||
| 			<option value="General" selected="selected">General</option> | ||||
| 			<option value="Antennas">Antennas</option> | ||||
| 			<option value="Satellites">Satellites</option> | ||||
| 		</select></td> | ||||
| 	</tr> | ||||
| 	 | ||||
| 	<tr> | ||||
| 		<td></td> | ||||
| 		<td><textarea name="content" id="markItUp" rows="10" cols="10"></textarea></td> | ||||
| 	</tr> | ||||
| </table> | ||||
| 
 | ||||
| <div><input type="submit" value="Submit" /></div> | ||||
| 
 | ||||
| </form> | ||||
| 
 | ||||
| </div> | ||||
| <script type="text/javascript">  | ||||
| <!-- | ||||
| $(document).ready(function()	{ | ||||
| 	// Add markItUp! to your textarea in one line
 | ||||
| 	// $('textarea').markItUp( { Settings }, { OptionalExtraSettings } );
 | ||||
| 	$('#markItUp').markItUp(mySettings); | ||||
| 
 | ||||
| 	// You can add content from anywhere in your page
 | ||||
| 	// $.markItUp( { Settings } );	
 | ||||
| 	$('.add').click(function() { | ||||
| 		$.markItUp( { 	openWith:'<opening tag>', | ||||
| 						closeWith:'<\/closing tag>', | ||||
| 						placeHolder:"New content" | ||||
| 					} | ||||
| 				); | ||||
| 		return false; | ||||
| 	}); | ||||
| 
 | ||||
| 	// And you can add/remove markItUp! whenever you want
 | ||||
| 	// $(textarea).markItUpRemove();
 | ||||
| 	$('.toggle').click(function() { | ||||
| 		if ($("#markItUp.markItUpEditor").length === 1) { | ||||
| 			$("#markItUp").markItUpRemove(); | ||||
| 			$("span", this).text("get markItUp! back"); | ||||
| 		} else { | ||||
| 			$('#markItUp').markItUp(mySettings); | ||||
| 			$("span", this).text("remove markItUp!"); | ||||
| 		} | ||||
| 		return false; | ||||
| 	}); | ||||
| }); | ||||
| --> | ||||
| </script>  | ||||
| <script type="text/javascript" src="<?php echo base_url(); ?>markitup/jquery.markitup.js"></script>  | ||||
| <!-- markItUp! toolbar settings -->  | ||||
| <script type="text/javascript" src="<?php echo base_url(); ?>markitup/sets/html/set.js"></script>  | ||||
| <!-- markItUp! skin -->  | ||||
| <link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/skins/markitup/style.css" />  | ||||
| <!--  markItUp! toolbar skin -->  | ||||
| <link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/sets/html/style.css" />  | ||||
							
								
								
									
										72
									
								
								application/views/auth/edit.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										72
									
								
								application/views/auth/edit.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,72 @@ | |||
| <?php foreach ($note->result() as $row) { ?>
 | ||||
| <h2>Edit Note - <?php echo $row->title; ?></h2>
 | ||||
| <div class="wrap_content"> | ||||
| <?php echo validation_errors(); ?>
 | ||||
| <form method="post" action="<?php echo site_url('notes/edit'); ?>/<?php echo $id; ?>" name="notes_add" id="notes_add"> | ||||
| <table> | ||||
| 	<tr> | ||||
| 		<td><label for="title">Title</label></td> | ||||
| 		<td><input type="text" name="title" value="<?php echo $row->title; ?>" /></td> | ||||
| 	</tr> | ||||
| 	 | ||||
| 	<tr> | ||||
| 		<td><label for="category">Category</label></td> | ||||
| 		<td><select name="category"> | ||||
| 			<option value="General" selected="selected">General</option> | ||||
| 			<option value="Antennas">Antennas</option> | ||||
| 			<option value="Satellites">Satellites</option> | ||||
| 		</select></td> | ||||
| 	</tr> | ||||
| 	 | ||||
| 	<tr> | ||||
| 		<td><input type="hidden" name="id" value="<?php echo $id; ?>" /></td> | ||||
| 		<td><textarea name="content" id="markItUp" rows="10" cols="10"><?php echo $row->note; ?></textarea></td>
 | ||||
| 	</tr> | ||||
| </table> | ||||
| 
 | ||||
| <div><input type="submit" value="Submit" /></div> | ||||
| 
 | ||||
| </form> | ||||
| 
 | ||||
| </div> | ||||
| <?php } ?>
 | ||||
| <script type="text/javascript">  | ||||
| <!-- | ||||
| $(document).ready(function()	{ | ||||
| 	// Add markItUp! to your textarea in one line
 | ||||
| 	// $('textarea').markItUp( { Settings }, { OptionalExtraSettings } );
 | ||||
| 	$('#markItUp').markItUp(mySettings); | ||||
| 
 | ||||
| 	// You can add content from anywhere in your page
 | ||||
| 	// $.markItUp( { Settings } );	
 | ||||
| 	$('.add').click(function() { | ||||
| 		$.markItUp( { 	openWith:'<opening tag>', | ||||
| 						closeWith:'<\/closing tag>', | ||||
| 						placeHolder:"New content" | ||||
| 					} | ||||
| 				); | ||||
| 		return false; | ||||
| 	}); | ||||
| 
 | ||||
| 	// And you can add/remove markItUp! whenever you want
 | ||||
| 	// $(textarea).markItUpRemove();
 | ||||
| 	$('.toggle').click(function() { | ||||
| 		if ($("#markItUp.markItUpEditor").length === 1) { | ||||
| 			$("#markItUp").markItUpRemove(); | ||||
| 			$("span", this).text("get markItUp! back"); | ||||
| 		} else { | ||||
| 			$('#markItUp').markItUp(mySettings); | ||||
| 			$("span", this).text("remove markItUp!"); | ||||
| 		} | ||||
| 		return false; | ||||
| 	}); | ||||
| }); | ||||
| --> | ||||
| </script>  | ||||
| <script type="text/javascript" src="<?php echo base_url(); ?>markitup/jquery.markitup.js"></script>  | ||||
| <!-- markItUp! toolbar settings -->  | ||||
| <script type="text/javascript" src="<?php echo base_url(); ?>markitup/sets/html/set.js"></script>  | ||||
| <!-- markItUp! skin -->  | ||||
| <link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/skins/markitup/style.css" />  | ||||
| <!--  markItUp! toolbar skin -->  | ||||
| <link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/sets/html/style.css" />  | ||||
							
								
								
									
										24
									
								
								application/views/auth/main.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										24
									
								
								application/views/auth/main.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,24 @@ | |||
| <h2>Note</h2> | ||||
| <div class="wrap_content note"> | ||||
| 
 | ||||
| <?php | ||||
| 
 | ||||
| 	if ($notes->num_rows() > 0) | ||||
| 	{ | ||||
| 		echo "<ul class=\"notes_list\">"; | ||||
| 		foreach ($notes->result() as $row) | ||||
| 		{ | ||||
| 			echo "<li>"; | ||||
| 			echo "<a href=\"".site_url()."/notes/view/".$row->id."\">".$row->title."</a>"; | ||||
| 			echo "</li>"; | ||||
| 		} | ||||
| 		echo "</ul>"; | ||||
| 	} else { | ||||
| 		echo "<p>You have no notes, why not create one!</p>"; | ||||
| 	} | ||||
| 
 | ||||
| ?>
 | ||||
| 
 | ||||
| <p><a href="<?php echo site_url('notes/add'); ?>" title="Add Note">Create a Note</a></p> | ||||
| 
 | ||||
| </div> | ||||
|  | @ -0,0 +1,8 @@ | |||
| <?php foreach ($note->result() as $row) { ?>
 | ||||
| <h2>Note - <?php echo $row->title; ?></h2>
 | ||||
| <div class="wrap_content note"> | ||||
| <?php echo nl2br($row->note); ?>
 | ||||
| 
 | ||||
| <p>Options: <a href="<?php echo site_url('notes/edit'); ?>/<?php echo $row->id; ?>"><img src="<?php echo base_url(); ?>images/application_edit.png" width="16" height="16" alt="Edit" /></a> <a href="<?php echo site_url('notes/delete'); ?>/<?php echo $row->id; ?>"><img src="<?php echo base_url(); ?>images/delete.png" width="16" height="16" alt="Delete" /></a></p> | ||||
| </div> | ||||
| <?php } ?>
 | ||||
							
								
								
									
										52
									
								
								css/api.css
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										52
									
								
								css/api.css
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,52 @@ | |||
| body { | ||||
|   background: #eee; | ||||
|   font-family: Verdana, sans-serif; | ||||
|   font-size: 8px; | ||||
| } | ||||
| #results table { | ||||
|   border: 0px solid #000; | ||||
|   border-collapse: collapse; | ||||
| } | ||||
| #results th { | ||||
|   padding: 4px; | ||||
|   border: 1px solid #000; | ||||
|   background-color: #6AA57B; | ||||
|   font-size: 11px; | ||||
| } | ||||
| #results td { | ||||
|   padding: 4px; | ||||
|   border: 1px solid #000; | ||||
|   font-size: 11px; | ||||
| } | ||||
| #results tr.row0 { | ||||
|   background-color: #A3BDF5; | ||||
| } | ||||
| #results tr.row1 { | ||||
|   background-color: #9ADF9A; | ||||
| } | ||||
| img { | ||||
|   border: 0px; | ||||
| } | ||||
| #footer { | ||||
|   font-size: 8px; | ||||
| } | ||||
| #debug { | ||||
|   border: 1px dotted #fff; | ||||
|   background-color: #c00; | ||||
|   color: #fff; | ||||
|   font-size: 8px; | ||||
| } | ||||
| #debug td { | ||||
|   padding: 4px; | ||||
|   color: #fff; | ||||
|   font-size: 10px; | ||||
| } | ||||
| .blank { | ||||
|   background-color: transparent; | ||||
| } | ||||
| .sub { | ||||
|   background-color: #cfc; | ||||
| } | ||||
| .subattr { | ||||
|   background-color: #cfc; | ||||
| } | ||||
							
								
								
									
										66
									
								
								css/api.xsl
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										66
									
								
								css/api.xsl
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,66 @@ | |||
| <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
| <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | ||||
| 
 | ||||
| <xsl:template match="/"> | ||||
|   <html> | ||||
|   <head> | ||||
|   <title><xsl:value-of select="//queryInfo/@calledMethod"/></title> | ||||
|   <link rel="stylesheet" href="/css/api.css" type="text/css" /> | ||||
|   </head> | ||||
|   <body> | ||||
|   <h1>Output of '<xsl:value-of select="//queryInfo/@calledMethod"/>'</h1> | ||||
|   <table id="results"> | ||||
|         <tr> | ||||
|         <xsl:for-each select="//elements/element[1]/@*"> | ||||
|           <th><b><xsl:value-of select="name()"/></b></th> | ||||
|         </xsl:for-each> | ||||
|         </tr> | ||||
|         <xsl:for-each select="//elements/element"> | ||||
| 		  <tr class="row{position() mod 2}"> | ||||
|           <xsl:for-each select="@*"> | ||||
|             <td><xsl:value-of select="."/></td> | ||||
|           </xsl:for-each> | ||||
|           </tr> | ||||
| 		  <xsl:for-each select="*"> | ||||
| 			<tr> | ||||
| 			  <td class="blank"></td> | ||||
| 			  <td class="sub"><xsl:value-of select="name()"/></td> | ||||
| 			  <td class="blank" colspan="20"> | ||||
| 				<table> | ||||
| 				  <tr> | ||||
| 					<xsl:for-each select="@*"> | ||||
| 					  <td class="subattr"> | ||||
| 						<xsl:value-of select="name()"/> = <xsl:value-of select="."/> | ||||
| 					  </td> | ||||
| 					</xsl:for-each> | ||||
| 				  </tr> | ||||
| 				</table> | ||||
| 			  </td> | ||||
| 			</tr> | ||||
| 		  </xsl:for-each> | ||||
|         </xsl:for-each> | ||||
|   </table> | ||||
|   <p/> | ||||
|   <xsl:if test="//debugInfo"> | ||||
|   <div id="debug"> | ||||
| 	<table> | ||||
| 	  <tr> | ||||
| 		<td><b>requestURI</b></td><td><xsl:value-of select="//debugInfo/@requestURI" /></td> | ||||
| 	  </tr> | ||||
| 	  <tr> | ||||
| 		<td><b>dbQuery</b></td><td><xsl:value-of select="//debugInfo/@dbQuery" /></td> | ||||
| 	  </tr> | ||||
| 	  <tr> | ||||
| 		<td><b>clientVersion</b></td><td><xsl:value-of select="//debugInfo/@clientVersion" /></td> | ||||
| 	  </tr> | ||||
| 	</table> | ||||
|   </div> | ||||
|   <p/> | ||||
|   </xsl:if> | ||||
|   <div id="footer"> | ||||
| 	Retrieved from the <xsl:element name="a"><xsl:attribute name="href"><xsl:value-of select="//queryInfo/logbookURL"/>/index.php/api</xsl:attribute>HRD Web Frontend</xsl:element> API at <b><xsl:value-of select="//queryInfo/@timeStamp"/></b>. Query took <b><xsl:value-of select="//queryInfo/@executionTime"/></b> seconds.<br/>This is formatted XML using XSLT. | ||||
|   </div> | ||||
|   </body> | ||||
|   </html> | ||||
| </xsl:template> | ||||
| </xsl:stylesheet> | ||||
		正在加载…
	
		在新工单中引用