Browse Source

PHP API updates. registration, login

Login doesn't work yet.
Nathaniel van Diepen 11 years ago
parent
commit
ae6e45d851
10 changed files with 167 additions and 57 deletions
  1. 31 20
      api.php
  2. 15 2
      data/login.template.html
  3. 16 3
      data/register.template.html
  4. 0 1
      index.php
  5. 31 8
      js/index.js
  6. 1 0
      php/database.php
  7. 15 21
      php/functions.php
  8. 11 2
      php/include.php
  9. 19 0
      php/security.php
  10. 28 0
      php/user.php

+ 31 - 20
api.php

@@ -1,23 +1,5 @@
 <?php
-	@session_start();
 	require_once('php/include.php');
-	// MYSQL default bugs:bugs
-	function retj($json,$title){
-		$type=$_GET['type'];
-		$id=$_GET['id'];
-		$json['state'] = Array();
-		$json['state']['data'] = $_GET;
-		$json['state']['title'] = $title;
-		switch($type){
-			case 'user':$url='~'.$id;break;
-			case 'group':$url='+'.$id;break;
-			case 'issue':$url='!'.$id;break;
-			case 'template':$url='page-'.$id;break;
-			default:$url=$type.'-'.$id;
-		}
-		$json['state']['url'] = $url;
-		die(json_encode($json));
-	}
 	// TODO - Add API handling.
 	$method = $_SERVER['REQUEST_METHOD'];
 	$ret = Array();
@@ -45,8 +27,37 @@
 					$ret['context'] = json_decode(file_get_contents('data/'.$id.'.context.json'));
 					retj($ret,$id);
 				break;
-				case 'login':
-						// TODO - handle logins
+				case 'action':
+						switch($id){
+							case 'login':
+								if(isset($_GET['username'])&&isset($_GET['password'])){
+									$key = login($_GET['username'],$_GET['password']);
+									if($key){
+										$ret['key'] = $key;
+									}else{
+										$ret['error'] = "Login failed. Username or Password didn't match.";
+									}
+								}else{
+									$ret['error'] = "Please provide a valid username and password.";
+								}
+								retj($ret,$id);
+							break;
+							case 'register':
+								if(isset($_GET['username'])&&isset($_GET['password'])&&isset($_GET['email'])){
+									if(addUser($_GET['username'],$_GET['password'],$_GET['email'])){
+										$ret['key'] = securityKey($_GET['username'],salt());
+										setKey($ret['key']);
+									}else{
+										$ret['error'] = "Could not add user. ".$mysqli->error;
+									}
+								}else{
+									$ret['error'] = "That username already exists!";
+								}
+								retj($ret,$id);
+							break;
+							default:
+								die('invalid action');
+						}
 				break;
 				default:
 					die("invalid type");

+ 15 - 2
data/login.template.html

@@ -12,8 +12,21 @@
 	<input type="button" value="cancel" class="cancel"/>
 </form>
 <script>
-	$('#login').submit(function(){
-		// TODO - Handle login
+	$('form#login').submit(function(){
+		var data = $(this).serializeObject(),
+			State = History.getState();
+		for(var i in State.data){
+			data[i] = State.data;
+		}
+		data.type = 'action';
+		data.id = 'login';
+		apiCall(data,function(d){
+			if(!d.error){
+				loadState('page-index');
+			}else{
+				loadState('page-login');
+			}
+		});
 		return false;
 	}).children('.cancel').click(function(){
 		loadState('page-index');

+ 16 - 3
data/register.template.html

@@ -1,7 +1,7 @@
 <h1>
 	{{title}}
 </h1>
-<form id="login">
+<form id="register">
 	<div>
 		Email: <input name="email" type="text"/>
 	</div>
@@ -15,8 +15,21 @@
 	<input type="button" value="cancel" class="cancel"/>
 </form>
 <script>
-	$('#login').submit(function(){
-		// TODO - Handle register
+	$('form#register').submit(function(){
+		var data = $(this).serializeObject(),
+			State = History.getState();
+		for(var i in State.data){
+			data[i] = State.data;
+		}
+		data.type = 'action';
+		data.id = 'register';
+		apiCall(data,function(d){
+			if(!d.error){
+				loadState('page-index');
+			}else{
+				loadState('page-register');
+			}
+		});
 		return false;
 	}).children('.cancel').click(function(){
 		loadState('page-index');

+ 0 - 1
index.php

@@ -8,7 +8,6 @@
 			@rmdir('install');
 		}
 	}
-	session_start();
 	require_once('php/include.php');
 	if(isset($_GET['get'])){
 		$get = $_GET['get'];

+ 31 - 8
js/index.js

@@ -5,19 +5,27 @@
 		exists = function(v){
 			return typeof v != 'undefined';
 		},
-		api = function(data,callback){
+		api = window.apiCall = function(data,callback){
 			data.get = 'api';
+			data.timestamp = +new Date;
+			if(exists(State.data.key)){
+				data.key = State.data.key;
+			}
 			$.get(location.href,data,function(d){
-				if(location.href.substr(location.href.lastIndexOf('/')+1) != d.state.url){
-					History.pushState(d.state.data,d.state.title,d.state.url);
-				}
-				if(exists(callback)){
-					callback(d);
+				if(exists(d['error'])){
+					alert(d.error);
+				}else{
+					if(location.href.substr(location.href.lastIndexOf('/')+1) != d.state.url){
+						History.pushState(d.state.data,d.state.title,d.state.url);
+					}
+					if(exists(callback)){
+						callback(d);
+					}
 				}
 			},'json');
 		},
 		loadState = window.loadState = function(href,callback){
-			$.get(href,{get:'state'},function(d){
+			$.get(href,{get:'state',timestamp:+new Date},function(d){
 				History.pushState(d.state.data,document.title,href);
 				State = History.getState();
 				if(exists(callback)){
@@ -26,7 +34,7 @@
 			},'json');
 		},
 		apiState = window.apiState = function(href,callback){
-			$.get(href,{get:'state'},function(d){
+			$.get(href,{get:'state',timestamp:+new Date},function(d){
 				History.replaceState(d.state.data,document.title,href);
 				State = History.getState();
 				if(exists(callback)){
@@ -85,4 +93,19 @@
 			$(window).trigger('statechange');
 		});
 	});
+	$.fn.serializeObject = function(){
+		var o = {},
+			a = this.serializeArray();
+		$.each(a,function(){
+			if(o[this.name] !== undefined){
+				if(!o[this.name].push){
+					o[this.name] = [o[this.name]];
+				}
+				o[this.name].push(this.value || '');
+			}else{
+				o[this.name] = this.value || '';
+			}
+		});
+		return o;
+	};
 })(jQuery,History);

+ 1 - 0
php/database.php

@@ -4,4 +4,5 @@
 	if($mysqli->connect_errno){
 		echo "Failed to connect to MySQL: ".$mysqli->connect_error;
 	}
+	$mysqli->autocommit(true);
 ?>

+ 15 - 21
php/functions.php

@@ -1,26 +1,20 @@
 <?php
-	@session_start();
-	require_once(PATH_PHP.'database.php');
+	require_once(realpath(dirname(__FILE__)).'/config.php');
 	// TODO - create php functions for the api
-	function addUser($username,$password,$email){
-		$salt = $mysqli->escape_string(salt());
-		$email = $mysqli->escape_string($email);
-		$username = $mysqli->escape_string($username);
-		$hash = $mysqli->escape_string(saltedHash($password,$salt));
-		return $mysqli->query("INSERT INTO `bugs`.`users` (email,name,pass,salt) VALUES '{$email}','{$username}','{$password}','{$salt}'");
-	}
-	function salt(){
-		return uniqid(mt_rand(0,61), true);
-	}
-	function saltedHash($pass,$salt){
-		$hash = $pass.$salt;
-		for($i = 0;$i<50;$i++){
-			$hash = hash('sha512',$pass.$hash.$salt);
+	function retj($json,$title){
+		$type=$_GET['type'];
+		$id=$_GET['id'];
+		$json['state'] = Array();
+		$json['state']['data'] = $_GET;
+		$json['state']['title'] = $title;
+		switch($type){
+			case 'user':$url='~'.$id;break;
+			case 'group':$url='+'.$id;break;
+			case 'issue':$url='!'.$id;break;
+			case 'template':$url='page-'.$id;break;
+			default:$url=$type.'-'.$id;
 		}
-		return $hash;
-	}
-	function compareSaltedHash($pass,$salt,$hash){
-		return $hash == saltedHash($pass,$salt);
+		$json['state']['url'] = $url;
+		die(json_encode($json));
 	}
-	
 ?>

+ 11 - 2
php/include.php

@@ -1,5 +1,14 @@
 <?php
-	require_once(realpath(dirname(__FILE__)).'/'.'config.php');
-	require_once(PATH_PHP.'functions.php');
+	@session_start();
+	require_once(realpath(dirname(__FILE__)).'/config.php');
 	require_once(PATH_PHP.'database.php');
+	require_once(PATH_PHP.'functions.php');
+	require_once(PATH_PHP.'security.php');
+	require_once(PATH_PHP.'user.php');
+	if(isset($_GET['key'])&&isset($SESSION['key'])){
+		if($_GET['key'] != $SESSION['key']){
+			unset($SESSION['key']);
+			retj(Array('error'=>'Invalid key, you were logged out.'));
+		}
+	}
 ?>

+ 19 - 0
php/security.php

@@ -0,0 +1,19 @@
+<?php
+	function salt(){
+		return uniqid(mt_rand(0,61), true);
+	}
+	function saltedHash($pass,$salt){
+		$hash = $pass.$salt;
+		for($i = 0;$i<50;$i++){
+			$hash = hash('sha512',$pass.$hash.$salt);
+		}
+		return $hash;
+	}
+	function compareSaltedHash($pass,$salt,$hash){
+		die(saltedHash($pass,$salt)."\n".$hash);
+		return $hash == saltedHash($pass,$salt);
+	}
+	function securityKey($username,$salt){
+		return saltedHash($username,$salt);
+	}
+?>

+ 28 - 0
php/user.php

@@ -0,0 +1,28 @@
+<?php
+	require_once(realpath(dirname(__FILE__)).'/config.php');
+	require_once(PATH_PHP.'database.php');
+	require_once(PATH_PHP.'security.php');
+	$mysqli = $GLOBALS['mysqli'];
+	function addUser($username,$password,$email){
+		$mysqli = $GLOBALS['mysqli'];
+		$salt = $mysqli->escape_string(salt());
+		$email = $mysqli->escape_string($email);
+		$username = $mysqli->escape_string($username);
+		$hash = $mysqli->escape_string(saltedHash($password,$salt));
+		return $mysqli->query("INSERT INTO `".get("database")."`.`users` (email,name,password,salt) VALUES ('{$email}','{$username}','{$hash}','{$salt}')");
+	}
+	function login($username,$password){
+		$mysqli = $GLOBALS['mysqli'];
+		if($res = $mysqli->query("SELECT name,password,salt FROM `".get("database")."`.`users` WHERE name = '{$username}'")){
+			if($res->num_rows == 1){
+				$row = $res->fetch_assoc();
+				if(compareSaltedHash($password,$row['salt'],$row['password'])){
+					return securityKey($username,salt());
+				}			}
+		}
+		return false;
+	}
+	function setKey($key){
+		$SESSION['key'] = $key;
+	}
+?>