Skip to content

Commit b49ef20

Browse files
committed
Merge branch 'development'
2 parents 41c5d12 + b957815 commit b49ef20

File tree

6 files changed

+112
-9
lines changed

6 files changed

+112
-9
lines changed

.vscode/settings.json

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
11
{
2-
"cflint.enabled": false
3-
}
2+
"cflint.enabled": false,
3+
"sqltools.connections": [
4+
{
5+
"mysqlOptions": {
6+
"authProtocol": "xprotocol"
7+
},
8+
"previewLimit": 50,
9+
"server": "localhost",
10+
"port": 33060,
11+
"driver": "MySQL",
12+
"name": "local-mysql8",
13+
"group": "local",
14+
"database": "cbsecurity",
15+
"username": "root",
16+
"connectionTimeout": 1000
17+
}
18+
]
19+
}

box.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name":"ColdBox Security",
3-
"version":"3.0.0",
3+
"version":"3.1.0",
44
"location":"https://downloads.ortussolutions.com/ortussolutions/coldbox-modules/cbsecurity/@build.version@/[email protected]@.zip",
55
"author":"Ortus Solutions.com <[email protected]>",
66
"slug":"cbsecurity",
@@ -25,7 +25,7 @@
2525
"dependencies":{
2626
"jwt-cfml":"^1.0.0",
2727
"cbauth":"^6.0.0",
28-
"cbcsrf":"^2.0.0"
28+
"cbcsrf":"^3.0.0"
2929
},
3030
"devDependencies":{
3131
"commandbox-cfformat":"*",

changelog.md

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

88
----
99

10+
## [3.1.0] => 2023-FEB-17
11+
12+
### Added
13+
14+
* Added a new helper: `createPassword()` on the `CBSecurity` model to generate secure, random passwords with letters, symbols and numbers.
15+
* `cbcsrf` upgraded to version 3, we missed in the previous release.
16+
17+
----
18+
1019
## [3.0.0] => 2023-JAN-17
1120

1221
### Changed / COMPATIBILITY

models/CBSecurity.cfc

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ component threadsafe singleton accessors="true" {
2525
property name="settings" inject="coldbox:moduleSettings:cbsecurity";
2626
property name="log" inject="logbox:logger:{this}";
2727
property name="wirebox" inject="wirebox";
28+
property name="async" inject="coldbox:asyncManager";
2829
property name="moduleSettings" inject="coldbox:setting:modules";
2930
property name="DBLogger" inject="DBLogger@cbsecurity";
3031

@@ -435,7 +436,7 @@ component threadsafe singleton accessors="true" {
435436
* @message The error message to throw in the exception
436437
*
437438
* @throws NoUserLoggedIn
438-
* @throws NotAuthorized
439+
* @throws NotAuthorized
439440
*/
440441
CBSecurity function secureSameUser( required user, message = variables.DEFAULT_ERROR_MESSAGE ){
441442
if ( !sameUser( arguments.user ) ) {
@@ -470,7 +471,7 @@ component threadsafe singleton accessors="true" {
470471
*
471472
* They receive the currently logged in user and the permissions that where evaluated
472473
*
473-
* @permissions One, a list or an array of permissions
474+
* @permissions One, a list, an array of permissions or boolean evaluation
474475
* @success The closure/lambda/udf that executes if the context passes
475476
* @fail The closure/lambda/udf that executes if the context fails
476477
*/
@@ -622,6 +623,50 @@ component threadsafe singleton accessors="true" {
622623
return headers.keyExists( "host" ) ? headers[ "host" ] : "none";
623624
}
624625

626+
627+
/**
628+
* Generate a random, secure password using several options
629+
*
630+
* @length The length of the password. Defaults to 32 characters
631+
* @letters Use letters
632+
* @numbers Use numbers
633+
* @symbols Use symbols
634+
*
635+
* @return A secure random password
636+
*/
637+
function createPassword(
638+
numeric length = 32,
639+
boolean letters = true,
640+
boolean numbers = true,
641+
boolean symbols = true
642+
){
643+
var characters = [];
644+
645+
// cfformat-ignore-start
646+
_when( arguments.letters, () => characters.append( [
647+
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
648+
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
649+
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
650+
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
651+
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
652+
], true ) )
653+
._when( arguments.numbers, () => characters.append( [
654+
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
655+
], true ) )
656+
._when( arguments.symbols, () => characters.append( [
657+
'~', '!', '##', '$', '%', '^', '&', '*', '(', ')', '-',
658+
'_', '.', ',', '<', '>', '?', '/', '\', '{', '}', '[',
659+
']', '|', ':', ';'
660+
], true ) );
661+
// cfformat-ignore-end
662+
663+
return repeatString( "1", arguments.length )
664+
.listToArray( "" )
665+
.map( () => characters[ randRange( 1, characters.len() ) ] )
666+
.toList( "" );
667+
}
668+
669+
625670
/***************************************************************/
626671
/* Private Methods
627672
/***************************************************************/
@@ -635,4 +680,28 @@ component threadsafe singleton accessors="true" {
635680
return isArray( arguments.items ) ? items : listToArray( items );
636681
}
637682

683+
/**
684+
* TODO: Migrate from FlowHelpers once ColdBox 7 goes gold.
685+
* This function evaluates the target boolean expression and if `true` it will execute the `success` closure
686+
* else, if the `failure` closure is passed, it will execute it.
687+
*
688+
* @target The boolean evaluator, this can be a boolean value
689+
* @success The closure/lambda to execute if the boolean value is true
690+
* @failure The closure/lambda to execute if the boolean value is false
691+
*
692+
* @return Returns itself
693+
*/
694+
private function _when(
695+
required boolean target,
696+
required success,
697+
failure
698+
){
699+
if ( arguments.target ) {
700+
arguments.success();
701+
} else if ( !isNull( arguments.failure ) ) {
702+
arguments.failure();
703+
}
704+
return variables;
705+
}
706+
638707
}

test-harness/box.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
"description":"",
77
"dependencies":{
88
"coldbox":"^6.0.0",
9-
"cbauth":"^5.0.0",
9+
"cbauth":"^6.0.0",
1010
"BCrypt":"^2.0.0",
1111
"jwt-cfml":"^1.0.0",
12-
"cbcsrf":"^2.0.0+21",
13-
"cbdebugger":"^3.5.0+64"
12+
"cbcsrf":"^3.0.0"
1413
},
1514
"devDependencies":{
15+
"cbdebugger":"^3.5.0+64",
1616
"testbox":"*",
1717
"route-visualizer":"*"
1818
},

test-harness/tests/specs/unit/CBSecurityTest.cfc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ component extends="coldbox.system.testing.BaseModelTest" model="cbsecurity.model
1818
describe( "CBSecurity Model", function(){
1919
beforeEach( function( currentSpec ){
2020
cbsecurity = model.init();
21+
model.setAsync( new coldbox.system.async.AsyncManager() );
2122

2223
mockAuthService = createStub();
2324
mockUser = createMock( "root.models.User" ).init();
@@ -31,6 +32,14 @@ component extends="coldbox.system.testing.BaseModelTest" model="cbsecurity.model
3132
expect( cbsecurity ).toBeComponent();
3233
} );
3334

35+
it( "can create random passwords", function(){
36+
expect( cbsecurity.createPassword() ).toHaveLength( 32 );
37+
expect( cbsecurity.createPassword( 2 ) ).toHaveLength( 2 );
38+
expect( cbsecurity.createPassword( numbers: false ) ).notToMatch( "([0-9])+" );
39+
expect( cbsecurity.createPassword( letters: false ) ).notToMatch( "([a-zA-Z])+" );
40+
expect( cbsecurity.createPassword( symbols: false, numbers: false ) ).toMatch( "([a-zA-Z])+" );
41+
} );
42+
3443
describe( "verification via has()", function(){
3544
it( "can verify true if the user has one permission", function(){
3645
mockUser.$( "hasPermission", true );

0 commit comments

Comments
 (0)