Welcome!

Last updated: April 14th, 2020

Installation

The following requirements are mandatory for proper function of the script:

  • PHP: version > 5.4
  • MySQL Server: version > 5.5.x
  • Safe Mode: off
  • PHP Libraries:
    • OpenSSL Extension
    • JSON PHP Extension
    • MCRYPT PHP Extension
  • Mod_Rewrite apache module.

Installation Wizard

Script is packed with auto-installer to guide easily deploy and configure database tables and implement them inside your current database.
after uploading script files to your server, simply run the installer wizard from:

http://www.your-site.com/siteguard/install/index.php

screenshot
screenshot

Warning:

You MUST remove "install" folder from root directory after installing the script to avoid any security breaches

Including the script

after installation, include the application in your current website to start using it's powerful tools for user management.
please include this line in top of your curent PHP script.

<?php include_once("siteGuard/load.php"); ?>

Understanding Syntax

In this section we are going to discuss how to use SiteGuard syntax to familiarize with syntax and implement many functions in your script.

SiteGuard Object

The object called automatically when you include: load.php file inside your script. under the variable: $siteGuard

<?php $siteGuard = new SiteGuard(); ?>


$siteGuard->get_user ( status [optional] );

This function checks wheather current visitor is logged in or not, then return User object, or redirect the visitor to login page. Returns (object) User object

Parameter Description
check_logged_out Checks if user is logged out and redirects user to login page (Default) .
check_logged_in Checks if user is logged in and redirects user to index page.
<?php $current_user = $siteGuard->get_user(); ?>

$siteGuard->privilege ( privilege );

This function checks wheather curent user can do the requested privilege or not.
Returns (boolean) True/False

<?php if($siteGuard->privilege("profile.update")) {
	//Do Something.
} ?>

$siteGuard->page_access ( page_name [without.php] );

This function checks wheather curent user can access the requested page or not.
Returns (boolean) True/False

$siteGuard->only_for ( Access Level [ID - Name] );

This function ensures that specific users belong to an access level can see specific content inside any page, like when you need to make something visible only to (admins). Returns (boolean) True/False

Parameter Description
ID Numeric value of the target access level (Default).
Name Name of the target access level (case sensitive).
<?php if($siteGuard->only_for("Admin")) {
	//admin-specific content
} ?>

SiteGuard Session

The object called automatically when you include: load.php file inside your script. under the variable: $siteguard_session

<?php $siteguard_session = new new SessManager(); ?>


$siteguard_session->login ( User object );

Users can login to the app and session from here.

Parameter Description
User Must be a valid User object.

$siteguard_session->impersonate ( User object );

Admin can impersonate any user from this function.

Parameter Description
User Must be a valid User object.

$siteguard_session->deimpersonate ();

Admin can exit from impersonate mode from this function.

$siteguard_session->logout ();

User can logout from the application from this function.

$siteguard_session->is_logged_in ();

This function checks wheather a user is logged in or not. Returns (boolean) True/False

Writing your own classes

You can write your own Model class to use the app built in CRUD functions.
First, create a new class Extends OneClass like this:

<?php
require_once("Loader.php");
//File: "assets/includes/Library/TestClass.php"

class TestClass Extends OneClass {
	
	public static $table_name = "test_table";
	public static $db_fields = array( "id" , "name" , ...);
	
	public $id;
	public $name; 
	// ...etc
	
}
?>

Then include your new class in assets/includes/Library/Loader.php file like this:

<?php 
//File: "assets/includes/Library/Loader.php"
require_once(LIBRARY.DS."TestClass.php");
?>

This way you can use all built-in CRUD functions on your TestClass object in OOP way

<?php 
//Creating new TestClass object ..
$test = new TestClass();
$test->name = 'John';
$test->create();

//Updating TestClass object ..
$test = TestClass::get_specific_id($test_id);
$test->name = 'Jane';
$test->update();

//Deleting TestClass object ..
$test = TestClass::get_specific_id($test_id);
$test->delete();
?>

Fetching Data

SiteGuard uses custom written code that makes it very easy to fetch data of any Model class.

Model::get_everything ( MySQL WHERE clause );

Here you can list all items in database that match given search criteria.
Returns group of (Model) Objects, or False.

<?php 
$users = User::get_everything(" AND deleted = 0 ");
?>

Model::count_everything ( MySQL WHERE clause );

Here you can count all items in database that match given search criteria.
Returns Integer value of number of Objects, or False.

<?php 
$users = User::count_everything(" AND pending = 1 ");
?>

Model::get_specific_id( Integer );

Here you can select only one item based on given id.
Returns (Model) Object, or False.

<?php 
$user = User::get_specific_id(1);
?>

Model::find( Search_term , column_name , [LIMIT] );

You can search your database table (column) for a (term) in LIKE '%%' manner, if you want exact search you can use the method Model::find_exact( Search_term , column_name , [LIMIT] );
plus you can pass LIMIT or ORDER BY clause to control how given results are fetched.
Returns group of (Model) Objects, or False.

<?php 
$user = User::find("michael" , "name" , " ORDER BY id LIMIT 2 ");
?>

Model::check_existance( column_name, value );

Check if your database table (column) contains a (value) in exact manner, if you want check only for ID you can use the method Model::check_id_existance( Integer);.
Returns (boolean) True/False.

<?php 
if(User::check_existance("email" , "michael.zohney@gmail.com")) {
	//Email Exists!
}
?>

Application Layout

Login Screen

screenshot
screenshot

Your visitors can register new accounts from this screen, also have Social Login options that will be discussed in details later.

Your Terms & Conditions content can be found at : assets/includes/terms-of-service.php if you want to change it.

After registration, user account will be marked as pending till you approve them from admin panel.

Your Dashboard

screenshot
screenshot

Application dashboard is very informative, you've some shortcuts for application basic functions, also a graph that shows how many registrations in last 6 months, wheather direct registration or social logins.

Visitors see different dashboard with some basic shortcuts and a graph for their activity on the site.

Users Page

screenshot
screenshot

You can view and manage your site users from this screen, here you can:

  • Add New User
  • Delete User
  • Update User:
    • Activate Pending accounts
    • Add avatar (with cropper)
    • Enable/Disable two factor authentication
    • Ban Users
  • Impersonate Users

Usage Reports

screenshot

Users can view all reports and filter them when they have the privilege (usage_reports.power) only.

Active Sessions

screenshot

Online users are displayed here, you can monitor which page they're viewing and end any session.

General Settings

screenshot

From this section you can control all of your script's settings, enable registrations, API and more.

Update Privileges

screenshot

Here you can view default privileges and add new pages / privileges so they can appear in (Access Levels) privileges choices page.
Also note that you can add new pages to your navigation menu from here and script will create them in your application folder using same app styling.

Access Levels

screenshot
screenshot

You can add access levels and update current default levels, all custom privileges and pages added in (Privileges) page will appear in the options.

API Explorer

screenshot

Here you can test application API to view each function and return values. refer to SiteGuard API section for more information about API calls.

User Profile

screenshot
screenshot

Profile page contains some basic information about the user, users can edit their info and close their accounts from here. special privileges like profile.change_username, profile.change_email are disabled by default for visitors and you can enable them from (access levels) section.

Two Factor Authentication

screenshot

User can enable two factor authentication from his (profile) page, script will generate 5 backup codes for him and a QR Code will be generated which can be read by the Google Authenticator application to generate OTP codes on any android or iphone device.

SiteGuard API

Enabling API Calls

screenshot

First, Enable API Calls from (General Settings) and set unique SECRET & SALT Keys. This key will not be sent in calls instead you will user the PUBLIC key which will be decrypted according to the secret SALT which will never be shared outside the script.
Now you can go and explore API Functions in (Settings Api Explorer) page.


API Call Anatomy

API Functions are called using GET method, while API Key and other sensitive information are sent using Headers and POST method.
You can make successful request using $.ajax JQuery function.

Using JWT

SiteGuard supports JWT for securing API calls with temporary tokens.
You can write your own JWT (for better security) or request a token from the API server before calling any method.
JWT are sent in the header Authorization: Bearer xxx Like this:
$.ajax({
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  type: 'POST',
  url: "http://www.your-site.com/siteguard/api/user/get/1/name",
  dataType: 'json',
  success: function (data) {
	//Returns JSON Object
	console.log(data);
  }
});

Prepare-JWT functions

API   /prepare-public-jwt/

Encode public key to JWT to be used in all calls except (user update, password-reset) functions.
Returns (String) Encoded JWT.

Method Function Target
GET api/prepare-public-jwt/
POST (string) api_key Your Public API Key

You can find it in (general_settings) page

$.ajax({
  type: 'POST',
  url: 'http://www.your-site.com/siteguard/api/prepare-public-jwt',
  data: { api_key: 'YOUR_PUBLIC_API_KEY' },
  dataType: 'json',
  success: function (data) {
	//Returns encoded JWT
	console.log(data);
  }
});

API   /prepare-user-jwt/

Encode user key to JWT to be used in (user update, password-reset) functions.
Returns (String) Encoded JWT.

Method Function Target
GET api/prepare-user-jwt/
POST (string) api_key User API Key

You can find it in (user profile) page

$.ajax({
  type: 'POST',
  url: 'http://www.your-site.com/siteguard/api/prepare-user-jwt',
  data: { api_key: 'YOUR_USER_API_KEY' },
  dataType: 'json',
  success: function (data) {
	//Returns encoded JWT
	console.log(data);
  }
});

Writing your own JWT functions

You can write your own JWT tokens programmatically to make more secure calls without exposing api_key, this way you will pass an encoded JWT that cannot be decoded without the hidden secret_key
Visit https://jwt.io/ and choose your platform and start coding your own JWT functions, in this example I used firebase/php-jwt syntax:
$token = array(
	"iss" => "Your_SiteName",
	"iat" => time(),
	"exp" => time() + 60,
	"api_key" => "PUBLIC_API_KEY -or- USER_API_KEY"
);
$jwt = JWT::encode($token, "YOUR_SECRET_KEY", "HS256");


User functions

API   /user/get/[ id - all - active - banned ]/ property

Here you can get users data according to filter (ID - All users - Active only - Pending approval only - Banned only).
Returns (JSON Object) Group of items, or False.

Method Function Target Property
GET api/user/get (integer) user_id

get specific user by ID


(string) all

get all users


(string) active

get currently active users


(string) pending

get users pending admin approval


(string) banned

get banned users

(Optional) Return specific property
instead of whole object
name
email
username
phone
address
about
registeration_date
access_level
avatar
currently vieweing (active users only)
ip (active users only)
Header Authorization: Bearer xxx Your encoded JWT
(Public api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/user/get/banned',
  dataType: 'json',
  success: function (data) {
	//Returns JSON Object containing all banned users
	console.log(data);
  }
});

API   /user/update/ (int) id / property

Users can update their profile via API calls.
Returns two-factor-athentication QR Link -or- Message.

Method Function Target Property
GET api/user/update (integer) user_id

get specific user by ID

POST (string) name
(string) phone
(string) address
(string) email
(string) password

Mandatory, user password


(boolean) banned (1 or 0)
(boolean) tfa (1 or 0)

Two factor authentication, if value = 1 the function will return the QR image code for google authenticator

Header Authorization: Bearer xxx Your encoded JWT
(User api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/user/update/12',
  data: { name: 'NAME',
		phone: 'PHONE',
		address: 'ADDRESS' ,
		email: 'EMAIL' ,
		password: 'USER_PASSWORD' ,
		banned: 'BANNED' ,
		tfa: 'TFA' 
  },
  dataType: 'json',
  success: function (data) {
	//Returns two-factor-athentication QR Link -or- Success/Error Message.
	console.log(data);
  }
});

API   /user/find/[ keyword ]/ property

Here you can get group of users based on keyword search
Returns (JSON Object) Group of items, or False.

Method Function Variable Property
GET api/user/find (string) Keyword

Search for (name, email, username, mobile)

(Optional) Return specific property
instead of whole object
name
email
username
phone
address
about
registeration_date
access_level
avatar
Header Authorization: Bearer xxx Your encoded JWT
(Public api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/user/find/michael/avatar',
  dataType: 'json',
  success: function (data) {
	//Returns JSON array containing avatars of users named (michael)
	console.log(data);
  }
});

API   /user/privilege/ user_id / privilege

This function checks whether a specific user can access specific privilege or not
Returns (boolean) True/False.

Method Function Variable Property
GET api/user/privilege (integer) user_id

Check this user for a specific privilege

(string) Privilege
Header Authorization: Bearer xxx Your encoded JWT
(Public api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/user/privilege/14/profile_changeusername',
  dataType: 'json',
  success: function (data) {
	//Returns whether the user can change username. (BOOLEAN) either true or false.	
	console.log(data);
  }
});

API   /user/page/ user_id / pageName

This function checks whether a specific user can access specific page or not
Returns (boolean) True/False.

Method Function Variable Property
GET api/user/page (integer) user_id

Check if this user can access specific page

(string) Page Name
Header Authorization: Bearer xxx Your encoded JWT
(Public api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/user/page/14/general_settings',
  dataType: 'json',
  success: function (data) {
	//Returns whether the user can access (general_settings) page.  BOOLEAN either true or false.	
	console.log(data);
  }
});

Authentication functions

API   auth/login/

Login users via API.
Returns (boolean) True/False.

Method Function Variables
POST api/auth/login (string) username


(string) password


(string) (optional) otp

OTP for users with two factor authentication activated


Header Authorization: Bearer xxx Your encoded JWT
(Public api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/auth/login/',
  data: {	  username: 'USERNAME',
			  password: 'PASSWORD',
			  otp: '' 
			},
  dataType: 'json',
  success: function (data) {
	//Returns Success/Error message.
console.log(data);
  }
});

API   auth/logout/

End active user session via API.
Returns (boolean) True/False.

Method Function Variables
GET api/auth/logout
Header Authorization: Bearer xxx Your encoded JWT
(Public api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/auth/logout/',
  dataType: 'json',
  success: function (data) {
	//Returns Success/Error message.
console.log(data);
  }
});

API   auth/reset-password/

Reset user password via API.
Returns (string) Success/Error message.

Method Function Variables
GET api/auth/reset-password (integer) user_id
POST (string) current_password
(string) new_password
(string) confirm_new_password
(integer) otp

(optional - if two factor authentication activated)


Header Authorization: Bearer xxx Your encoded JWT
(User api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/auth/reset-password/28',
  data: { current_password: 'USER_PASS',
		  new_password: 'NEW_PASSWORD',
		  confirm_new_password: 'RETYPE_NEW_PASSWORD',
		  otp: 'OTP'
			},
	dataType: 'json',
	success: function (data) {
	//Returns Success/Error message.
	console.log(data);
  }
});

API   auth/register/

Register new user via API.
Returns (string) Success/Error message.

Method Function Variables
POST api/auth/register (string) name
(string) email
(string) username
(string) password
(string) confirm_password
(string) g-recaptcha-response

ReCaptcha V2 response

Header Authorization: Bearer xxx Your encoded JWT
(Public api_key)
$.ajax({
  type: 'POST',
  beforeSend: function(xhr) {
  	xhr.setRequestHeader('Authorization', 'Bearer xxxxx';
  },
  url: 'http://www.your-site.com/siteguard/api/auth/register/',
  data: { 	  name: 'NAME',
			  email: 'EMAIL',
			  username: 'USERNAME',
			  password: 'PASSWORD',
			  confirm_password: 'PASSWORD', 
			  g-recaptcha-response: 'RECAPTCHA V2' 
			},
  dataType: 'json',
  success: function (data) {
	//Returns Success/Error message.
console.log(data);
  }
});
Feel free to contact me on michael.zohney@gmail.com for any comments or suggestions, Thanks!