Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
W
webbasics
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Taddeüs Kroes
webbasics
Commits
80bec815
Commit
80bec815
authored
12 years ago
by
Taddeus Kroes
Browse files
Options
Downloads
Patches
Plain Diff
Started implementing Security class, and added some documentation on what the result should be
parent
6fb07ae5
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
security.php
+195
-0
195 additions, 0 deletions
security.php
tests/test_security.php
+13
-0
13 additions, 0 deletions
tests/test_security.php
with
208 additions
and
0 deletions
security.php
0 → 100644
+
195
−
0
View file @
80bec815
<?php
/**
* Security functions for user authentication and authorization.
*
* Usage example:
* <code>
* try {
* $security = webbasics\Security::getInstance();
*
* // Authentication: can the origin of the request be trusted?
*
* // Verify that a user is logged in
* $security->requireLogin();
*
* // Use a security token to verify that the request originated from a
* // trusted page. This is recommended if, for example, the script makes
* // changes to the database
* $security->requireToken($_REQUEST['token']);
*
* // Authorization: is the user allowed to request this page?
* $security->requireUserRole('admin');
*
* ...
*
* // Pass token to template so that it can be used in a submitted form or
* // AJAX request
* $template->set('token', $auth->generateToken());
*
* ...
*
* } catch(webbasics\AuthenticationFailed $e) {
* die('Get lost hacker!');
* } catch(webbasics\AuthorizationFailed $e) {
* http_response_code(403);
* die('You are not authorized to view this page.');
* }
* </code>
*
* Corresponding login controller example:
* <code>
* // Find the user using ActiveRecord (not part of the WebBasics library)
* $user = User::first(array('username' => $_POST['username']));
*
* if (!$user)
* die('Invalid username');
*
* // Current user is part of the
* $security = webbasics\Security::getInstance();
* $security->setUser($user);
*
* // Simple: use a plain password
* if (!$security->attemptPassword($user, $_POST['password']))
* die('Invalid password');
*
* // More secure: hash the password in a javascript function before
* // submitting the login form
* if (!$security->attemptPasswordHash($user, $_POST['password_hash']))
* die('Invalid password');
* </code>
*
* And the User model implementation used in the example above:
* <code>
* use PHPActiveRecord\Model;
* use webbasics\AuthenticatedUser;
* use webbasics\AuthorizedUser;
*
* class User extends Model implements AuthenticatedUser, AuthorizedUser {
* function getUsername() {
* return $this->username;
* }
*
* function getPasswordHash() {
* return $this->password;
* }
*
* function getCookieToken() {
* return $this->cookie_token;
* }
*
* function setCookieToken($token) {
* $this->update_attribute('cookie_token', $token);
* }
*
* function getRegistrationToken() {
* return $this->registration_token;
* }
*
* function setRegistrationToken($token) {
* $this->update_attribute('registration_token', $token);
* }
*
* function getRole() {
* return $this->role;
* }
* }
* </code>
*
* @author Taddeus Kroes
* @date 05-10-2012
*/
namespace
webbasics
;
require_once
'base.php'
;
interface
AuthenticatedUser
{
function
getUsername
();
function
getPasswordHash
();
function
getCookieToken
();
function
setCookieToken
(
$token
);
function
getRegistrationToken
();
function
setRegistrationToken
(
$token
);
}
interface
AuthorizedUser
{
function
getRole
();
}
class
Security
{
const
SESSION_TOKEN_NAME
=
'auth_token'
;
const
SESSION_NAME_USERDATA
=
'auth_userdata'
;
private
static
$instance
;
private
$user
;
static
function
getInstance
()
{
if
(
self
::
$instance
===
null
)
self
::
$instance
=
new
self
;
return
self
::
$instance
;
}
private
function
__construct
()
{}
function
generateToken
()
{
$session
=
Session
::
getInstance
();
$token
=
sha1
(
self
::
generateRandomString
(
10
));
$session
->
set
(
self
::
SESSION_TOKEN_NAME
,
$token
);
return
$token
;
}
function
requireToken
(
$request_token
)
{
if
(
$request_token
!=
$this
->
getSavedToken
())
throw
new
AuthenticationFailed
(
'invalid token "%s"'
,
$request_token
);
}
private
function
getSavedToken
()
{
$session
=
Session
::
getInstance
();
if
(
!
$session
->
isRegistered
(
self
::
SESSION_TOKEN_NAME
))
throw
new
AuthenticationError
(
'no token saved in session'
);
return
$session
->
get
(
self
::
SESSION_TOKEN_NAME
);
}
function
sessionDataExists
()
{
return
Session
::
getInstance
()
->
areRegistered
(
array
(
self
::
SESSION_TOKEN_NAME
,
self
::
SESSION_NAME_USERDATA
));
}
function
requireLogin
()
{
}
function
requireUserRole
()
{
}
//function setUser(AuthenticatedUser $user) {
// $this->user = $user;
//}
static
function
generateRandomString
(
$length
)
{
$CHARS
=
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUWXYZ01234567890123456789'
;
$string
=
''
;
srand
(
time
());
for
(
$i
=
0
;
$i
<
$length
;
$i
++
)
$string
.
=
$CHARS
[
rand
(
0
,
strlen
(
$CHARS
)
-
1
)];
return
$string
;
}
}
class
AuthenticationError
extends
FormattedException
{}
class
AuthenticationFailed
extends
FormattedException
{}
class
AuthorizationError
extends
FormattedException
{}
class
AuthorizationFailed
extends
FormattedException
{}
?>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
tests/test_security.php
0 → 100644
+
13
−
0
View file @
80bec815
<?php
require_once
'SingletonTestCase.php'
;
require_once
'security.php'
;
use
webbasics\Security
;
class
SecurityTest
extends
SingletonTestCase
{
function
getClassName
()
{
return
'webbasics\Security'
;
}
}
?>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment