Skip to content

Commit 8e153a2

Browse files
committed
* New authorization and authentication delegates for usage in cb7
1 parent f36d4d2 commit 8e153a2

File tree

6 files changed

+167
-68
lines changed

6 files changed

+167
-68
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919

2020
### Added
2121

22+
* New authorization and authentication delegates for usage in cb7
2223
* New ability for the firewall to log all action events to a database table.
2324
* New visualizer that can visualize all settings and all firewall events via the log table if enabled.
2425
* New Basic Auth validator and basic auth user credentials storage system. This will allow you to secure your apps where no database interaction is needed or required.

models/auth/User.cfc

Lines changed: 21 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
/**
22
* This is a basic user object that can be used with CBSecurity.
33
*
4-
* It implements the following interfaces
4+
* It implements the following interfaces via it's delegates
55
* - cbsecurity.interfaces.jwt.IJwtSubject
66
* - cbsecurity.interfaces.IAuthUser
77
*/
8-
component accessors="true" {
8+
component
9+
accessors="true"
10+
delegates="Auth@cbSecurity,
11+
Authorizable@cbSecurity,
12+
JwtSubject@cbSecurity"
13+
{
914

15+
/**
16+
* Properties
17+
*/
1018
property name="id";
1119
property name="firstName";
1220
property name="lastName";
@@ -21,18 +29,16 @@ component accessors="true" {
2129
*/
2230
this.constraints = {
2331
firstName : { required : true, size : "1..255" },
24-
lastName : { required : true, size : "1..255" },
25-
username : { required : true, size : "1..255" },
26-
password : { required : true, size : "1..255" }
32+
lastName : { required : true, size : "1..255" },
33+
username : { required : true, size : "1..255" },
34+
password : { required : true, size : "1..255" }
2735
};
2836

2937
/**
3038
* Validation profiles
3139
* https://coldbox-validation.ortusbooks.com/overview/validating-constraints/validating-with-profiles
3240
*/
33-
this.constraintProfiles = {
34-
"update" : "firstName,lastName,username"
35-
};
41+
this.constraintProfiles = { "update" : "firstName,lastName,username" };
3642

3743
/**
3844
* Mementifier serialization
@@ -48,21 +54,20 @@ component accessors="true" {
4854
"roles"
4955
],
5056
// Default Exclusions
51-
defaultExcludes : [
52-
],
57+
defaultExcludes : [],
5358
// Never Include
54-
neverInclude : [ "password" ]
59+
neverInclude : [ "password" ]
5560
};
5661

5762
/**
5863
* Constructor
5964
*/
6065
function init(){
61-
variables.id = "";
62-
variables.firstName = "";
63-
variables.lastName = "";
64-
variables.username = "";
65-
variables.password = "";
66+
variables.id = "";
67+
variables.firstName = "";
68+
variables.lastName = "";
69+
variables.username = "";
70+
variables.password = "";
6671
variables.permissions = [];
6772
variables.roles = [];
6873

@@ -102,52 +107,4 @@ component accessors="true" {
102107
return ( !isNull( variables.id ) && len( variables.id ) );
103108
}
104109

105-
/**
106-
* A struct of custom claims to add to the JWT token
107-
*/
108-
struct function getJWTCustomClaims( required struct payload ){
109-
return { "role" : variables.roles.toList() };
110-
}
111-
112-
/**
113-
* This function returns an array of all the scopes that should be attached to the JWT token that will be used for authorization.
114-
*/
115-
array function getJWTScopes(){
116-
return variables.permissions;
117-
}
118-
119-
/**
120-
* Verify if the user has one or more of the passed in permissions
121-
*
122-
* @permission One or a list of permissions to check for access
123-
*/
124-
boolean function hasPermission( required permission ){
125-
if ( isSimpleValue( arguments.permission ) ) {
126-
arguments.permission = listToArray( arguments.permission );
127-
}
128-
129-
return arguments.permission
130-
.filter( function( item ){
131-
return ( variables.permissions.findNoCase( item ) );
132-
} )
133-
.len();
134-
}
135-
136-
/**
137-
* Verify if the user has one or more of the passed in roles
138-
*
139-
* @role One or a list of roles to check for access
140-
*/
141-
boolean function hasRole( required role ){
142-
if ( isSimpleValue( arguments.role ) ) {
143-
arguments.role = listToArray( arguments.role );
144-
}
145-
146-
return arguments.role
147-
.filter( function( item ){
148-
return ( variables.roles.findNoCase( item ) );
149-
} )
150-
.len();
151-
}
152-
153110
}

models/delegates/Auth.cfc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ component singleton accessors="true" {
1414
/**
1515
* Retrieve the Jwt Auth Service
1616
*/
17-
function jwtAuth() {
18-
return variables.jwtService;
17+
function jwtAuth(){
18+
return variables.jwtService;
1919
}
2020

2121
/**
2222
* Retrieve the CBSecurity Service Object
2323
*/
24-
function cbSecure() {
25-
return variables.cbsecurity;
24+
function cbSecure(){
25+
return variables.cbsecurity;
2626
}
2727

2828
/**

models/delegates/Authorizable.cfc

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* Copyright since 2016 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* This delegate allows for objects to verify permissions and roles on the $parent
6+
* This delegate expects the following functions to be exposed in the $parent
7+
* - getPermissions()
8+
* - getRoles()
9+
* - getId()
10+
*/
11+
component {
12+
13+
// DI
14+
property name="cbSecurity" inject="cbSecurity@cbSecurity";
15+
16+
/***************************************************************/
17+
/* IAuthUser Methods
18+
/***************************************************************/
19+
20+
/**
21+
* Verify if the parent has one or more of the passed in permissions
22+
*
23+
* @permission One or a list of permissions to check for access
24+
*/
25+
boolean function hasPermission( required permission ){
26+
return arrayWrap( arguments.permission )
27+
.filter( function( item ){
28+
return ( $parent.getPermissions().findNoCase( item ) );
29+
} )
30+
.len();
31+
}
32+
33+
/**
34+
* Verify if the parent has one or more of the passed in roles
35+
*
36+
* @role One or a list of roles to check for access
37+
*/
38+
boolean function hasRole( required role ){
39+
return arrayWrap( arguments.role )
40+
.filter( function( item ){
41+
return ( $parent.getRoles().findNoCase( item ) );
42+
} )
43+
.len();
44+
}
45+
46+
/**
47+
* Verify if the current user is logged in or not.
48+
*/
49+
function isLoggedIn(){
50+
return variables.cbSecurity.isLoggedIn();
51+
}
52+
53+
/***************************************************************/
54+
/* Verification Methods
55+
/***************************************************************/
56+
57+
/**
58+
* Verify that ALL the permissions passed must exist within the authenticated user
59+
*
60+
* @permissions One, a list or an array of permissions
61+
*
62+
* @throws NoUserLoggedIn
63+
*/
64+
boolean function hasAll( required permissions ){
65+
var aPerms = arrayWrap( arguments.permissions );
66+
67+
return aPerms
68+
.filter( function( item ){
69+
return $parent.hasPermission( arguments.item );
70+
} )
71+
.len() == aPerms.len();
72+
}
73+
74+
/**
75+
* Verify that NONE of the permissions passed must exist within the authenticated user
76+
*
77+
* @permissions One, a list or an array of permissions
78+
*
79+
* @throws NoUserLoggedIn
80+
*/
81+
boolean function hasNone( required permissions ){
82+
return arrayWrap( arguments.permissions )
83+
.filter( function( item ){
84+
return $parent.hasPermission( arguments.item );
85+
} )
86+
.len() == 0;
87+
}
88+
89+
/**
90+
* Verify that the passed in user object must be the same as the authenticated user
91+
* Equality is done by evaluating the `getid()` method on both objects.
92+
*
93+
* @user The user to test for equality
94+
*
95+
* @throws NoUserLoggedIn
96+
*/
97+
boolean function sameUser( required user ){
98+
return ( arguments.user.getId() == $parent.getId() );
99+
}
100+
101+
/**
102+
* convert one or a list of permissions to an array, if it's an array we don't touch it
103+
*
104+
* @items One, a list or an array
105+
*
106+
* @return An array
107+
*/
108+
private array function arrayWrap( required items ){
109+
return isArray( arguments.items ) ? arguments.items : listToArray( arguments.items );
110+
}
111+
112+
}

models/delegates/JwtSubject.cfc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Copyright since 2016 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* This delegate allows for objects to get JWT custom claims and Custom Scopes
6+
* This delegate expects the following functions to be exposed in the $parent
7+
* - getPermissions()
8+
* - getRoles()
9+
*/
10+
component {
11+
12+
/**
13+
* A struct of custom claims to add to the JWT token
14+
* By default we add the $parent's roles
15+
*/
16+
struct function getJWTCustomClaims( required struct payload ){
17+
return { "role" : $parent.getRoles().toList() };
18+
}
19+
20+
/**
21+
* This function returns an array of all the scopes that should be attached to the JWT token that will be used for authorization.
22+
* By default we add the $parent's permissions
23+
*/
24+
array function getJWTScopes(){
25+
return $parent.getPermissions();
26+
}
27+
28+
}

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Apache License, Version 2.0.
3838

3939
- Lucee 5+
4040
- ColdFusion 2018+
41+
- ColdBox 7+ for delegates and basic auth
4142

4243
## Installation
4344

0 commit comments

Comments
 (0)