API-work for kassa.neuf.no
* Starts /api/register.php as primary endpoint for kassa * Started work on simple card number updates in cardnumber.php * Reworded sms/register.php * Update README with markdown syntax
This commit is contained in:
1 parent
6170baef22
commit
2615f7154d
10 files changed
+310
-110
No files matched your search
@@ -0,0 +1,12 @@
|
||||
## Konfigurasjon
|
||||
Du må endre instillinger for database, migrering (key og server), payex betaling og snapporder-integrasjon.
|
||||
cp inside/credentials-sample.php inside/credentials.php
|
||||
cp inside/migration/config.example.php inside/migration/config.php
|
||||
cp includes/payex2/payex_defines.example.php includes/payex2/payex_defines.php
|
||||
cp snapporder/config-sample.php snapporder/config.php
|
||||
|
||||
Du trenger kanskje å endre ting i includes/Ldap_defines.php også.
|
||||
|
||||
## Installasjon
|
||||
Legg inn Apache, MySQL og PHP. Du trenger også noen utvidelser til PHP.
|
||||
sudo apt-get install php5-mysql php5-ldap
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
== Konfigurasjon ==
|
||||
Du må endre instillinger for database, migrering (key og server), payex betaling og snapporder-integrasjon.
|
||||
$ cp inside/credentials-sample.php inside/credentials.php
|
||||
$ cp inside/migration/config.example.php inside/migration/config.php
|
||||
$ cp includes/payex2/payex_defines.example.php includes/payex2/payex_defines.php
|
||||
$ cp snapporder/config-sample.php snapporder/config.php
|
||||
|
||||
Du trenger kanskje å endre ting i includes/Ldap_defines.php også.
|
||||
|
||||
== Installasjon ==
|
||||
Legg inn Apache, MySQL og PHP. Du trenger også noen utvidelser til PHP.
|
||||
$ sudo apt-get install php5-mysql php5-ldap
|
||||
+35
-19
@@ -1,15 +1,26 @@
|
||||
<?php
|
||||
set_include_path("../includes/");
|
||||
set_include_path("../includes/".PATH_SEPARATOR.get_include_path());
|
||||
require_once("../includes/DB.php");
|
||||
require_once("../inside/credentials.php");
|
||||
|
||||
|
||||
/* Set HTTP response code */
|
||||
function set_response_code($code) {
|
||||
if(!is_int($code)) {
|
||||
return false;
|
||||
if( !function_exists('set_response_code') ) {
|
||||
function set_response_code($code)
|
||||
{
|
||||
if (!is_int($code)) {
|
||||
return false;
|
||||
}
|
||||
header('X-Ignore-This: something', true, $code);
|
||||
}
|
||||
header('X-Ignore-This: something', true, $code);
|
||||
}
|
||||
|
||||
|
||||
function return_json_response($data, $response_code=200) {
|
||||
if($response_code != 200) {
|
||||
set_response_code($response_code);
|
||||
}
|
||||
die(json_encode($data));
|
||||
}
|
||||
|
||||
|
||||
@@ -40,24 +51,29 @@ function get_db_connection($fetch_mode=NULL, $options=NULL) {
|
||||
}
|
||||
|
||||
|
||||
function clean_phonenumber($pn) {
|
||||
$pn = preg_replace('/[^0-9\+]/', '', $pn); // remove everything except valid chars
|
||||
$pn = preg_replace('/^00/','+', $pn); // replace starting 00 with +
|
||||
// norwegian phone numbers
|
||||
if( strlen($pn) === 8 && ($pn[0] === "4" || $pn[0] === "9") ) {
|
||||
$pn = "+47".$pn;
|
||||
if( !function_exists('clean_phonenumber') ) {
|
||||
function clean_phonenumber($pn) {
|
||||
$pn = preg_replace('/[^0-9\+]/', '', $pn); // remove everything except valid chars
|
||||
$pn = preg_replace('/^00/', '+', $pn); // replace starting 00 with +
|
||||
// norwegian phone numbers
|
||||
if (strlen($pn) === 8 && ($pn[0] === "4" || $pn[0] === "9")) {
|
||||
$pn = "+47" . $pn;
|
||||
}
|
||||
// ...without +
|
||||
if (strlen($pn) === 10 && $pn[0] === "4" && $pn[1] === "7" && ($pn[2] === "4" || $pn[2] === "9")) {
|
||||
$pn = "+" . $pn;
|
||||
}
|
||||
|
||||
return $pn;
|
||||
}
|
||||
// ...without +
|
||||
if( strlen($pn) === 10 && $pn[0] === "4" && $pn[1] === "7" && ($pn[2] === "4" || $pn[2] === "9") ) {
|
||||
$pn = "+".$pn;
|
||||
}
|
||||
return $pn;
|
||||
}
|
||||
|
||||
|
||||
// E.164
|
||||
function valid_phonenumber($phone) {
|
||||
return preg_match('/^\+?\d{8,15}$/i', $phone);
|
||||
if( !function_exists('valid_phonenumber') ) {
|
||||
// E.164
|
||||
function valid_phonenumber($phone) {
|
||||
return preg_match('/^\+?\d{8,15}$/i', $phone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+63
-62
@@ -10,79 +10,80 @@ $conn = get_db_connection(DB_FETCHMODE_ORDERED);
|
||||
|
||||
|
||||
if( !isset($_GET['apikey']) ) {
|
||||
set_response_code(400);
|
||||
echo json_encode(array('error' => "Missing param apikey."));
|
||||
die();
|
||||
return_json_response(array('error' => "Missing param apikey."), 400);
|
||||
}
|
||||
/* Valid API KEY (defined in credentials.php) ? */
|
||||
if( $_GET['apikey'] !== USER_API_KEY && $_GET['apikey'] !== USER_API_KEY_KASSA ) {
|
||||
set_response_code(400);
|
||||
echo json_encode(array('error' => "Invalid apikey: '".$_GET['apikey']."'."));
|
||||
die();
|
||||
return_json_response(array('error' => "Invalid apikey: '".$_GET['apikey']."'."), 400);
|
||||
}
|
||||
if($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$body = file_get_contents('php://input');
|
||||
$data = json_decode($body, true);
|
||||
|
||||
/* Validate params */
|
||||
if(!isset($_GET['q'])) {
|
||||
set_response_code(400);
|
||||
echo json_encode(array('error' => "Missing param q"));
|
||||
die();
|
||||
/* Validate params */
|
||||
if( !isset($data['card_number']) ) {
|
||||
return_json_response(array('error' => "Missing param card_number"), 400);
|
||||
}
|
||||
$card_number = $data['card_number'];
|
||||
|
||||
if( !is_numeric($card_number) ) {
|
||||
return_json_response(array('error' => "Value card_number must be numeric: '".$card_number."'"), 400);
|
||||
}
|
||||
|
||||
/* Validate user_id */
|
||||
if( !isset($data['user_id']) ) {
|
||||
return_json_response(array('error' => "Missing param user_id"), 400);
|
||||
}
|
||||
if( !is_numeric($data['user_id']) ) {
|
||||
return_json_response(array('error' => "Value user_id must be numeric: '".$data['user_id']."'"), 400);
|
||||
}
|
||||
/* TODO: If user does not exist, bail */
|
||||
/* TODO: If user relationship to card exists, bail */
|
||||
/* TODO: Either Add card relationship OR remove old relationsip and add new */
|
||||
return_json_response(array('error' => 'TODO: Not implemented'));
|
||||
}
|
||||
else {
|
||||
/* Validate params */
|
||||
if( !isset($_GET['card_number']) && !isset($_POST['card_number']) ) {
|
||||
return_json_response(array('error' => "Missing param card_number: ".var_export($_POST, true)), 400);
|
||||
}
|
||||
$card_number = $_GET['card_number'];
|
||||
|
||||
$card_number = $_GET['q'];
|
||||
if( !is_numeric($card_number) ) {
|
||||
return_json_response(array('error' => "Value card_number must be numeric: '".$card_number."'"), 400);
|
||||
}
|
||||
|
||||
if( !is_numeric($card_number) ) {
|
||||
set_response_code(400);
|
||||
echo json_encode(array('error' => "Value q must be numeric: '".$card_number."'"));
|
||||
die();
|
||||
}
|
||||
// Search query
|
||||
$card_number = $conn->quoteSmart($card_number);
|
||||
$sql = "SELECT mc.userId FROM din_membercard AS mc
|
||||
LEFT JOIN din_user AS u ON mc.userId=u.id
|
||||
WHERE mc.id=$card_number";
|
||||
|
||||
$card_number = $conn->quoteSmart($card_number);
|
||||
$res = $conn->getAll($sql);
|
||||
|
||||
// Search query
|
||||
$sql = "
|
||||
SELECT mc.userId FROM din_membercard AS mc
|
||||
LEFT JOIN din_user AS u ON mc.userId=u.id
|
||||
WHERE mc.id=$card_number";
|
||||
error_reporting(0);
|
||||
if( DB::isError($res) ) {
|
||||
return_json_response(array('error' => $res->message), 500);
|
||||
}
|
||||
$card_number_exists = count($res) === 0;
|
||||
|
||||
$res = $conn->getAll($sql);
|
||||
/* Invalid card number? */
|
||||
if($card_number_exists) {
|
||||
return_json_response(array('user' => NULL, 'valid' => false));
|
||||
}
|
||||
|
||||
if( DB::isError($res) ) {
|
||||
set_response_code(500);
|
||||
echo json_encode(array('error' => $res->message));
|
||||
die();
|
||||
}
|
||||
$user_id = $res[0][0];
|
||||
/* Free card_number? */
|
||||
if($user_id === "") {
|
||||
return_json_response(array('user' => NULL, 'valid' => true));
|
||||
}
|
||||
|
||||
/* Invalid card number*/
|
||||
if(count($res) === 0) {
|
||||
echo json_encode(array(
|
||||
'user' => NULL,
|
||||
'valid' => false
|
||||
));
|
||||
die();
|
||||
}
|
||||
/* Existing user with card_number. */
|
||||
try{
|
||||
$user_data = get_user_data($user_id, $conn);
|
||||
} catch(Exception $e) {
|
||||
return_json_response(array('error' => $e->getMessage()), 500);
|
||||
return; // Note: Help IntelliJ code inspection.
|
||||
}
|
||||
|
||||
$user_id = $res[0][0];
|
||||
/* Free card_number? */
|
||||
if($user_id === "") {
|
||||
echo json_encode(array(
|
||||
'user' => NULL,
|
||||
'valid' => true
|
||||
));
|
||||
die();
|
||||
}
|
||||
|
||||
/* Existing user with card_number. */
|
||||
try{
|
||||
$user_data = get_user_data($user_id, $conn);
|
||||
} catch(Exception $e) {
|
||||
set_response_code(500);
|
||||
echo json_encode(array('error' => $e->getMessage()));
|
||||
die();
|
||||
}
|
||||
echo json_encode(array(
|
||||
'user' => $user_data,
|
||||
'valid' => $res !== NULL
|
||||
));
|
||||
|
||||
?>
|
||||
return_json_response(array('user' => $user_data, 'valid' => $res !== NULL));
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/*
|
||||
* Registers a user in the user table
|
||||
*
|
||||
* Request (new):
|
||||
*
|
||||
* $ curl /api/register.php
|
||||
* {
|
||||
* "phone": "+4742345678",
|
||||
* "purchased": "2004-02-12" // optional, format: ISO-8601 date
|
||||
* "source": "physical" // optional, possible values: "physical", "web" or "manual"
|
||||
* "membership_trial": "buddy" // optional, gives free membership in autumn, possible value: "buddy"
|
||||
* }
|
||||
*
|
||||
* Response:
|
||||
*
|
||||
* {
|
||||
* "phone": "+4742345678",
|
||||
* "membership_status": 1, // 0: registrert, 1: medlem, 2: aktivt medlem
|
||||
* "expires": "2015-04-23",
|
||||
* "memberid": "4331",
|
||||
* "firstname": "Jon",
|
||||
* "lastname": "Hansen",
|
||||
* "email": "jon@uio.no",
|
||||
* "birthdate": "1985-03-01",
|
||||
* "registration_status": "partial" // "partial" means show link
|
||||
* "membership_trial": "buddy" // possible value: "buddy", user has a trial membership, unset if not
|
||||
* "registration_url": "/snapporder/register_partial.php?userid=4331&token=lol"
|
||||
* }
|
||||
*
|
||||
* Request (renewal):
|
||||
*
|
||||
* $ curl /api/register.php
|
||||
* {
|
||||
* "phone": "+4742345678",
|
||||
* "purchased": "2004-02-12" // optional, format: ISO-8601 date
|
||||
* "type": "renewal" // optional, possible values: "renewal"
|
||||
* "source": "physical" // optional, possible values: "physical", "web" or "manual"
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
/* Pull in Inside */
|
||||
set_include_path("../includes/".PATH_SEPARATOR."../inside/".PATH_SEPARATOR."../snapporder");
|
||||
require_once("functions.php");
|
||||
require_once("User.php");
|
||||
|
||||
/* Pull in some nifty stuff from snapporder integration */
|
||||
require_once("api_functions.php");
|
||||
require_once("lib/functions.php");
|
||||
require_once("config.php");
|
||||
|
||||
/* Validate request */
|
||||
$body = file_get_contents('php://input');
|
||||
if(strlen($body) === 0) {
|
||||
return_json_response(array('error' => 'Invalid request'), 400);
|
||||
}
|
||||
|
||||
/* Decode body */
|
||||
$data = json_decode($body, true);
|
||||
if($data === NULL) {
|
||||
return_json_response(array('error' => 'Can\'t decode body'), 400);
|
||||
}
|
||||
/* Check type of registration and set valid fields */
|
||||
$reg_type = "new";
|
||||
if( isset($data['type']) && $data['type'] === "renewal" ) {
|
||||
/* Renewal */
|
||||
$reg_type = $data['type'];
|
||||
}
|
||||
|
||||
$required_keys = array('apikey', 'phone');
|
||||
$valid_keys = $required_keys;
|
||||
$valid_keys = array_merge($valid_keys, array('purchased', 'source', 'type', 'membership_trial', 'cardno'));
|
||||
|
||||
$valid_sources = array('physical', 'web', 'manual');
|
||||
|
||||
/* Validate supplied data */
|
||||
foreach($required_keys as $key) {
|
||||
if(!array_key_exists($key, $data)) {
|
||||
return_json_response(array('error' => 'missing required field \''.$key.'\''), 400);
|
||||
}
|
||||
}
|
||||
foreach($data as $key => $value) {
|
||||
if(!in_array($key, $valid_keys)) {
|
||||
return_json_response(array('error' => 'unknown field \''.$key.'\''), 400);
|
||||
}
|
||||
}
|
||||
|
||||
/* Valid API KEY (defined in credentials.php) ? */
|
||||
if( $data['apikey'] !== USER_API_KEY_KASSA ) {
|
||||
return_json_response(array('error' => "Invalid apikey: '".$data['apikey']."'."), 400);
|
||||
}
|
||||
|
||||
$data['phone'] = clean_phonenumber($data['phone']);
|
||||
if( !valid_phonenumber($data['phone']) ) {
|
||||
return_json_response(array('error' => "Not a phone number: '".$data['phone']."'"), 400);
|
||||
}
|
||||
|
||||
$conn = get_db_connection(DB_FETCHMODE_ASSOC);
|
||||
|
||||
/* Existing user? */
|
||||
$user_id = getUseridFromPhone($data['phone']);
|
||||
if( $reg_type === "new" && $user_id !== false ) {
|
||||
return_json_response(array('error' => 'Existing user with phone: '.$data['phone']), 409);
|
||||
}
|
||||
/* Renewal of membership? */
|
||||
if( $reg_type === "renewal" && $user_id === false ) {
|
||||
return_json_response(array('error' => 'Could not find user with phone: '.$data['phone']), 409);
|
||||
}
|
||||
|
||||
$data['user_id'] = $user_id;
|
||||
if( $reg_type === "renewal") {
|
||||
$user = get_user($user_id);
|
||||
/* Don't allow renewal of an existing valid membership. */
|
||||
if( $user['membership_status'] !== 0 ) {
|
||||
if($user['expires'] === '') {
|
||||
// Life long
|
||||
return_json_response(array('error' => 'Cannot renew, user with phone '.$data['phone'].' has a life long membership.'), 409);
|
||||
}
|
||||
return_json_response(array('error' => 'Cannot renew, user with phone '.$data['phone'].' has a valid membership until: '.$user['expires']), 409);
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate optional purchase_date */
|
||||
if( isset($data['purchased']) ) {
|
||||
$purchased = clean_date($data['purchased']) ;
|
||||
if($purchased === false) {
|
||||
return_json_response(array('error' => 'Could not parse date from field purchased: '.$data['purchased']), 400);
|
||||
}
|
||||
$data['purchased'] = $purchased;
|
||||
}
|
||||
|
||||
/* Validate optional source */
|
||||
if( isset($data['source']) && !in_array($data['source'], $valid_sources) ) {
|
||||
return_json_response(array('error' => 'Invalid value in field source: '.$data['source']), 400);
|
||||
}
|
||||
|
||||
/* Validate optional membership_trial */
|
||||
if( isset($data['membership_trial']) && $data['membership_trial'] !== "buddy") {
|
||||
return_json_response(array('error' => 'Invalid value in field membership_trial: '.$data['membership_trial']), 400);
|
||||
}
|
||||
|
||||
/* Create user */
|
||||
try {
|
||||
if( $reg_type === "new" ) {
|
||||
$user_id = add_user($data, $data['source']);
|
||||
} else {
|
||||
renew_user($data);
|
||||
}
|
||||
} catch(InsideDatabaseException $e) {
|
||||
error_log($e->getMessage());
|
||||
return_json_response(array('error' => 'db_error', 'error_message' => $e->getMessage()), 500);
|
||||
}
|
||||
|
||||
/* Get and format user */
|
||||
$user = NULL;
|
||||
try {
|
||||
$user = get_user($user_id);
|
||||
} catch(InsideDatabaseException $e) {
|
||||
error_log($e->getMessage());
|
||||
return_json_response(array('error' => 'db_error', 'error_message' => $e->getMessage()), 500);
|
||||
}
|
||||
|
||||
/* Add register url */
|
||||
if($user['registration_status'] === "partial") {
|
||||
$user['registration_url'] = generate_registration_url($user, SECRET_KEY);
|
||||
}
|
||||
|
||||
/* Add back phone number from query */
|
||||
$user['phone'] = $data['phone'];
|
||||
|
||||
if( isset($data['membership_trial']) ) {
|
||||
/* Add back membership_trial from query */
|
||||
$user['membership_trial'] = $data['membership_trial'];
|
||||
}
|
||||
|
||||
/* Send welcome email */
|
||||
if($reg_type === "new") {
|
||||
send_activation_email($data, $user);
|
||||
// TODO: send_activation_sms($data, $user);
|
||||
}
|
||||
|
||||
/* Return encrypted user object */
|
||||
return_json_response($user);
|
||||
@@ -1710,6 +1710,11 @@ function clean_phonenumber($pn) {
|
||||
if( strlen($pn) === 8 && ($pn[0] === "4" || $pn[0] === "9") ) {
|
||||
$pn = "+47".$pn;
|
||||
}
|
||||
// ...without +
|
||||
if( strlen($pn) === 10 && $pn[0] === "4" && $pn[1] === "7" && ($pn[2] === "4" || $pn[2] === "9") ) {
|
||||
$pn = "+".$pn;
|
||||
}
|
||||
|
||||
return $pn;
|
||||
}
|
||||
// ISO-8601 Y-m-d
|
||||
@@ -1788,5 +1793,3 @@ function hash_ldap_password($raw_password) {
|
||||
|
||||
return '{SSHA}' . base64_encode(sha1( $raw_password.$salt, TRUE ). $salt);
|
||||
}
|
||||
|
||||
?>
|
||||
+2
-2
@@ -81,10 +81,10 @@ if( isset($_POST['submit']) ) {
|
||||
|
||||
<?php include("../snapporder/header.php"); ?>
|
||||
<div class="container">
|
||||
<h1 class="title">Registrering av medlemskap kjøpt på SMS</h1>
|
||||
<h1 class="title">Registrering av medlemskap kjøpt på SMS eller på Chateau Neuf</h1>
|
||||
<em class="subtitle">på Det Norske Studentersamfund</em>
|
||||
<header class="about">
|
||||
<p>Hei, for at medlemskapet du har kjøpt på SMS skal være gyldig, så <strong>må</strong> du registerere deg.</p>
|
||||
<p>Hei, for at medlemskapet du har kjøpt på SMS eller på Chateau Neuf skal være gyldig, så <strong>må</strong> du registerere deg.</p>
|
||||
<p class="imperative">Gå videre med registreringen ved å angi <em>telefonnummer, aktiveringskode, fornavn</em> og <em>epost</em>.</p>
|
||||
</header>
|
||||
<section class="register-sms">
|
||||
|
||||
@@ -87,6 +87,4 @@ if($user['registration_status'] === "partial") {
|
||||
|
||||
/* Return encrypted user object */
|
||||
echo $crypt->json_encode_and_encrypt($user);
|
||||
//echo json_encode($user);
|
||||
|
||||
?>
|
||||
//echo json_encode($user);
|
||||
@@ -236,5 +236,3 @@ if($reg_type === "new") {
|
||||
|
||||
/* Return encrypted user object */
|
||||
echo $crypt->json_encode_and_encrypt($user);
|
||||
|
||||
?>
|
||||
@@ -67,8 +67,9 @@ function add_user($data, $source) {
|
||||
$user_id = get_user_id_by_username($data['username']);
|
||||
|
||||
/* Phonenumber table */
|
||||
$phone_number_validated = $source === 'snapporder' ? 1 : 0;
|
||||
$cols = array('user_id', 'number', 'validated');
|
||||
$values = array($user_id, $phone, 1);
|
||||
$values = array($user_id, $phone, $phone_number_validated);
|
||||
|
||||
$sth = $conn->autoPrepare("din_userphonenumber", $cols, DB_AUTOQUERY_INSERT);
|
||||
$res = $conn->execute($sth, $values);
|
||||
@@ -195,11 +196,12 @@ function renew_user($data) {
|
||||
|
||||
/* Phonenumber table, set validated */
|
||||
$fields_values = array('validated' => 1);
|
||||
if($source === "snapporder") {
|
||||
$res = $conn->autoExecute("din_userphonenumber", $fields_values, DB_AUTOQUERY_UPDATE, "user_id=$user_id AND number='$phone'");
|
||||
|
||||
$res = $conn->autoExecute("din_userphonenumber", $fields_values, DB_AUTOQUERY_UPDATE, "user_id=$user_id AND number='$phone'");
|
||||
|
||||
if( DB::isError($res) ) {
|
||||
throw new InsideDatabaseException($res->getMessage().". DEBUG: ".$res->getDebugInfo());
|
||||
if( DB::isError($res) ) {
|
||||
throw new InsideDatabaseException($res->getMessage().". DEBUG: ".$res->getDebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if( isset($data['membership_trial']) && $in_autumn) {
|
||||
@@ -688,6 +690,4 @@ function send_confirmation_email($data, $user) {
|
||||
$message .= "</body></html>";
|
||||
|
||||
@mail($sendto, $subject, $message, $headers);
|
||||
}
|
||||
?>
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user