Disallow LDAP bind if trap is set; support setting trap from user form
This commit is contained in:
parent
64356d42d0
commit
decb83bdbb
@ -2,7 +2,4 @@
|
||||
- Forgot password handling
|
||||
- Admin password reset mechanism -> flag users as needing PW resets
|
||||
- OAuth2 -> support refresh tokens
|
||||
- Traps
|
||||
- Allow setting user trap from web UI
|
||||
- Don't allow external logins if trap is set
|
||||
- Trust token page -> force username of current user
|
||||
|
13
app/assets/app/resource/auth/Trap.resource.js
Normal file
13
app/assets/app/resource/auth/Trap.resource.js
Normal file
@ -0,0 +1,13 @@
|
||||
import CRUDBase from '../CRUDBase.js'
|
||||
|
||||
class TrapResource extends CRUDBase {
|
||||
endpoint = '/api/v1/auth/traps'
|
||||
required_fields = ['name', 'trap', 'redirect_to']
|
||||
permission_base = 'v1:auth:traps'
|
||||
|
||||
item = 'Trap'
|
||||
plural = 'Traps'
|
||||
}
|
||||
|
||||
const auth_trap = new TrapResource()
|
||||
export { auth_trap }
|
@ -99,6 +99,16 @@ class UserResource extends CRUDBase {
|
||||
placeholder: 'Password',
|
||||
required: ['insert'],
|
||||
},
|
||||
{
|
||||
name: 'Trap',
|
||||
field: 'trap',
|
||||
type: 'select.dynamic',
|
||||
options: {
|
||||
resource: 'auth/Trap',
|
||||
display: 'name',
|
||||
value: 'trap',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,24 @@ class AuthController extends Controller {
|
||||
return [...super.services, 'models', 'auth', 'MFA', 'output', 'configs', 'utility']
|
||||
}
|
||||
|
||||
async get_traps(req, res, next) {
|
||||
const trap_config = this.configs.get('traps')
|
||||
const data = [{ name: '(None)', trap: '', redirect_to: '/' }]
|
||||
for ( const name in trap_config.types ) {
|
||||
if ( !trap_config.types.hasOwnProperty(name) ) continue
|
||||
data.push({
|
||||
name: name.replace(/_/g, ' ')
|
||||
.split(' ')
|
||||
.map(x => x.charAt(0).toUpperCase() + x.substr(1))
|
||||
.join(' '),
|
||||
trap: name,
|
||||
redirect_to: trap_config.types[name].redirect_to
|
||||
})
|
||||
}
|
||||
|
||||
return res.api(data)
|
||||
}
|
||||
|
||||
async registration(req, res, next) {
|
||||
const User = this.models.get('auth:User')
|
||||
const required_fields = ['first_name', 'last_name', 'uid', 'email']
|
||||
@ -230,6 +248,15 @@ class AuthController extends Controller {
|
||||
if ( req.body.tagline )
|
||||
user.tagline = req.body.tagline
|
||||
|
||||
if ( req.body.trap ) {
|
||||
if ( !req.trap.trap_exists(req.body.trap) )
|
||||
return res.status(400)
|
||||
.message('Invalid trap type.')
|
||||
.api()
|
||||
|
||||
user.trap = req.body.trap
|
||||
}
|
||||
|
||||
await user.reset_password(req.body.password, 'create')
|
||||
await user.save()
|
||||
return res.api(await user.to_api())
|
||||
@ -340,6 +367,16 @@ class AuthController extends Controller {
|
||||
else
|
||||
user.tagline = ''
|
||||
|
||||
if ( req.body.trap ) {
|
||||
if ( !req.trap.trap_exists(req.body.trap) )
|
||||
return res.status(400)
|
||||
.message('Invalid trap type.')
|
||||
.api()
|
||||
|
||||
user.trap = req.body.trap
|
||||
} else
|
||||
user.trap = ''
|
||||
|
||||
await user.save()
|
||||
return res.api()
|
||||
}
|
||||
|
@ -90,6 +90,11 @@ class LDAPController extends Injectable {
|
||||
return next(new LDAP.InvalidCredentialsError())
|
||||
}
|
||||
|
||||
// Check if the resource has a trap. If so, deny access.
|
||||
if ( item.trap ) {
|
||||
return next(new LDAP.InvalidCredentialsError('This resource currently has a login trap set. Please visit the web UI to release.'))
|
||||
}
|
||||
|
||||
this.output.info(`Successfully bound resource as DN: ${req.dn.format(this.configs.get('ldap:server.format'))}.`)
|
||||
res.end()
|
||||
return next()
|
||||
|
@ -77,6 +77,7 @@ class User extends AuthUser {
|
||||
last_name: this.last_name,
|
||||
email: this.email,
|
||||
tagline: this.tagline,
|
||||
trap: this.trap,
|
||||
group_ids: (await this.groups()).map(x => x.id),
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@
|
||||
*/
|
||||
const Middleware = [
|
||||
"auth:Utility",
|
||||
"Traps",
|
||||
"auth:TrustTokenUtility",
|
||||
"Traps",
|
||||
"SAMLUtility",
|
||||
|
||||
// 'MiddlewareName',
|
||||
|
@ -48,6 +48,10 @@ class TrapUtility {
|
||||
else if ( this.user ) return this.user.trap
|
||||
}
|
||||
|
||||
trap_exists(name) {
|
||||
return !!this.configs[name]
|
||||
}
|
||||
|
||||
config() {
|
||||
return this.configs[this.get_trap()]
|
||||
}
|
||||
|
@ -8,6 +8,12 @@ const auth_routes = {
|
||||
get: {
|
||||
'/mfa/enable/date': ['middleware::auth:UserOnly', 'controller::api:v1:Auth.get_mfa_enable_date'],
|
||||
|
||||
'/traps': [
|
||||
'middleware::auth:APIRoute',
|
||||
['middleware::api:Permission', { check: 'v1:auth:traps:list'}],
|
||||
'controller::api:v1:Auth.get_traps',
|
||||
],
|
||||
|
||||
'/roles': [
|
||||
'middleware::auth:APIRoute',
|
||||
['middleware::api:Permission', { check: 'v1:auth:roles:list' }],
|
||||
|
Loading…
Reference in New Issue
Block a user