Browse Source

Make UID case-insensitive

master
Garrett Mills 2 years ago
parent
commit
97096f619f
Signed by: garrettmills GPG Key ID: D2BF5FBA8298F246
  1. 2
      app/classes/oidc/CoreIDAdapter.js
  2. 4
      app/classes/saml/FlitterProfileMapper.js
  3. 2
      app/controllers/OpenID.controller.js
  4. 13
      app/controllers/api/v1/Auth.controller.js
  5. 10
      app/controllers/api/v1/LDAP.controller.js
  6. 2
      app/controllers/saml/SAML.controller.js
  7. 6
      app/ldap/controllers/Users.controller.js
  8. 10
      app/models/auth/User.model.js
  9. 2
      app/models/iam/Policy.model.js
  10. 4
      app/models/ldap/Client.model.js
  11. 2
      app/routing/middleware/SAMLUtility.middleware.js
  12. 2
      app/services/MFA.service.js
  13. 2
      app/services/Vue.service.js
  14. 2
      app/unit/OpenIDConnectUnit.js

2
app/classes/oidc/CoreIDAdapter.js

@ -49,7 +49,7 @@ class CoreIDAdapter {
async findByUid(uid) {
const result = await this.coll().find(
{ 'payload.uid': uid },
{ 'payload.uid': uid.toLowerCase() },
{ payload: 1 },
).limit(1).next()

4
app/classes/saml/FlitterProfileMapper.js

@ -43,7 +43,7 @@ class FlitterProfileMapper {
getClaims() {
const claims = {}
claims[this.map.nameIdentifier] = this.user.uid
claims[this.map.nameIdentifier] = this.user.uid.toLowerCase()
claims[this.map.email] = this.user.email
claims[this.map.name] = `${this.user.first_name} ${this.user.last_name}`
claims[this.map.givenname] = this.user.first_name
@ -54,7 +54,7 @@ class FlitterProfileMapper {
}
getNameIdentifier() {
return { nameIdentifier: this.user.uid }
return { nameIdentifier: this.user.uid.toLowerCase() }
}
}

2
app/controllers/OpenID.controller.js

@ -126,7 +126,7 @@ class OpenIDController extends Controller {
return this.fail(res, 'Sorry, something has gone wrong.')
}
return this[name](req, res, { uid, prompt, params, session })
return this[name](req, res, { uid: uid.toLowerCase(), prompt, params, session })
}
async consent(req, res, { uid, prompt, params, session }) {

13
app/controllers/api/v1/Auth.controller.js

@ -71,7 +71,7 @@ class AuthController extends Controller {
const user = new User({
first_name: req.body.first_name,
last_name: req.body.last_name,
uid: req.body.uid,
uid: req.body.uid.toLowerCase(),
email: req.body.email,
trap: 'password_reset', // Force user to reset password
})
@ -297,7 +297,7 @@ class AuthController extends Controller {
.api()
const user = new User({
uid: req.body.uid,
uid: req.body.uid.toLowerCase(),
email: req.body.email,
first_name: req.body.first_name,
last_name: req.body.last_name,
@ -417,7 +417,7 @@ class AuthController extends Controller {
user.first_name = req.body.first_name
user.last_name = req.body.last_name
user.uid = req.body.uid
user.uid = req.body.uid.toLowerCase()
user.email = req.body.email
if ( req.body.tagline )
@ -493,7 +493,7 @@ class AuthController extends Controller {
if ( is_valid ) {
const User = this.models.get('auth:User')
const user = await User.findOne({uid: req.body.username})
const user = await User.findOne({uid: req.body.username.toLowerCase()})
if ( !user || !user.can_login ) is_valid = false
}
@ -511,7 +511,7 @@ class AuthController extends Controller {
const data = {}
if ( req.body.username ) {
const existing_user = await User.findOne({
uid: req.body.username,
uid: req.body.username.toLowerCase(),
})
data.username_taken = !!existing_user
@ -544,7 +544,8 @@ class AuthController extends Controller {
.message(req.T('auth.unable_to_complete'))
.api({ errors })
const login_args = await flitter.get_login_args(req.body)
const [username, ...other_args] = await flitter.get_login_args(req.body)
const login_args = [username.toLowerCase(), ...other_args]
const user = await flitter.login.apply(flitter, login_args)
if ( !user )

10
app/controllers/api/v1/LDAP.controller.js

@ -96,7 +96,7 @@ class LDAPController extends Controller {
// Make sure the uid is free
const User = this.models.get('auth:User')
const existing_user = await User.findOne({ uid: req.body.uid })
const existing_user = await User.findOne({ uid: req.body.uid.toLowerCase() })
if ( existing_user )
return res.status(400)
.message(req.T('api.user_already_exists'))
@ -113,7 +113,7 @@ class LDAPController extends Controller {
// Create the client
const Client = this.models.get('ldap:Client')
const client = await Client.create({
uid: req.body.uid,
uid: req.body.uid.toLowerCase(),
password: req.body.password,
name: req.body.name,
})
@ -210,16 +210,16 @@ class LDAPController extends Controller {
}
// Update the uid
if ( req.body.uid !== user.uid ) {
if ( req.body.uid.toLowerCase() !== user.uid ) {
// Make sure the UID is free
const User = this.models.get('auth:User')
const existing_user = await User.findOne({ uid: req.body.uid })
const existing_user = await User.findOne({ uid: req.body.uid.toLowerCase() })
if ( existing_user )
return res.status(400)
.message(req.T('api.user_already_exists'))
.api()
user.uid = req.body.uid
user.uid = req.body.uid.toLowerCase()
}
// Update the password

2
app/controllers/saml/SAML.controller.js

@ -67,7 +67,7 @@ class SAMLController extends Controller {
key: await this.saml.private_key(),
protocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
clearIdPSession: done => {
this.output.info(`${req.T('saml.clear_idp_session')} ${req.user.uid}`)
this.output.info(`${req.T('saml.clear_idp_session')} ${req.user.uid.toLowerCase()}`)
req.saml.participants.clear().then(async () => {
if ( this.saml.config().slo.end_coreid_session ) {
await req.user.logout(req)

6
app/ldap/controllers/Users.controller.js

@ -52,7 +52,7 @@ class UsersController extends LDAPController {
first_name: req_data.cn ? req_data.cn[0] : '',
last_name: req_data.sn ? req_data.sn[0] : '',
email: req_data.mail ? req_data.mail[0] : '',
username: req_data.uid ? req_data.uid[0] : '',
username: req_data.uid ? req_data.uid[0].toLowerCase() : '',
password: req_data.userpassword ? req_data.userpassword[0] : '',
}
@ -327,7 +327,7 @@ class UsersController extends LDAPController {
try {
if ( typeof dn === 'string' ) dn = LDAP.parseDN(dn)
return dn.rdns[0].attrs[uid_field].value
return dn.rdns[0].attrs[uid_field].value.toLowerCase()
} catch (e) {}
}
@ -335,7 +335,7 @@ class UsersController extends LDAPController {
const uid = this.get_uid_from_dn(dn)
if ( uid ) {
const User = this.models.get('auth:User')
return User.findOne({uid, ldap_visible: true})
return User.findOne({uid: uid.toLowerCase(), ldap_visible: true})
}
}
}

10
app/models/auth/User.model.js

@ -173,7 +173,7 @@ class User extends AuthUser {
const Policy = this.models.get('iam:Policy')
const ldap_data = {
uid: this.uid,
uid: this.uid.toLowerCase(),
uuid: this.uuid,
cn: this.first_name,
sn: this.last_name,
@ -213,7 +213,7 @@ class User extends AuthUser {
}
get dn() {
return LDAP.parseDN(`uid=${this.uid},${this.ldap_server.auth_dn().format(this.configs.get('ldap:server.format'))}`)
return LDAP.parseDN(`uid=${this.uid.toLowerCase()},${this.ldap_server.auth_dn().format(this.configs.get('ldap:server.format'))}`)
}
// The following are used by OpenID connect
@ -227,15 +227,15 @@ class User extends AuthUser {
given_name: this.first_name,
locale: 'en_US', // TODO
name: `${this.first_name} ${this.last_name}`,
preferred_username: this.uid,
username: this.uid,
preferred_username: this.uid.toLowerCase(),
username: this.uid.toLowerCase(),
}
}
static async findByLogin(login) {
return this.findOne({
active: true,
uid: login,
uid: login.toLowerCase(),
})
}

2
app/models/iam/Policy.model.js

@ -118,7 +118,7 @@ class PolicyModel extends Model {
if ( this.entity_type === 'user' ) {
const User = this.models.get('auth:User')
const user = await User.findById(this.entity_id)
entity_display = `User: ${user.last_name}, ${user.first_name} (${user.uid})`
entity_display = `User: ${user.last_name}, ${user.first_name} (${user.uid.toLowerCase()})`
} else if ( this.entity_type === 'group' ) {
const Group = this.models.get('auth:Group')
const group = await Group.findById(this.entity_id)

4
app/models/ldap/Client.model.js

@ -19,7 +19,7 @@ class ClientModel extends Model {
const user = new User({
first_name: name,
last_name: '(LDAP Agent)',
uid,
uid: uid.toLowerCase(),
roles: ['ldap_client'],
})
@ -58,7 +58,7 @@ class ClientModel extends Model {
id: this.id,
name: this.name,
user_id: user.id,
uid: user.uid,
uid: user.uid.toLowerCase(),
last_invocation: this.last_invocation,
permissions: [...user.permissions, ...role_permissions],
}

2
app/routing/middleware/SAMLUtility.middleware.js

@ -17,7 +17,7 @@ class SessionParticipantStore extends Injectable {
async issue({ service_provider }) {
const sp = new this.SessionParticipant({
service_provider_id: service_provider.id,
name_id: this.request.user.uid,
name_id: this.request.user.uid.toLowerCase(),
// session_index: this.get_index(),
slo_url: service_provider.slo_url,
// TODO sp_cert,

2
app/services/MFA.service.js

@ -10,7 +10,7 @@ class MFAService extends Service {
secret(user) {
return speakeasy.generateSecret({
length: this.configs.get('auth.mfa.secret_length') ?? 20,
name: `${this.configs.get('app.name')} (${user.uid})`,
name: `${this.configs.get('app.name')} (${user.uid.toLowerCase()})`,
})
}

2
app/services/Vue.service.js

@ -25,7 +25,7 @@ class VueService extends Service {
user: {
first_name: req.user.first_name,
last_name: req.user.last_name,
username: req.user.uid,
username: req.user.uid.toLowerCase(),
email: req.user.email,
tagline: req.user.tagline,
user_id: req.user.id,

2
app/unit/OpenIDConnectUnit.js

@ -28,7 +28,7 @@ class OpenIDConnectUnit extends Unit {
clients: [],
interactions: {
interactions,
url: (ctx, interaction) => `/openid/interaction/${ctx.oidc.uid}`,
url: (ctx, interaction) => `/openid/interaction/${ctx.oidc.uid.toLowerCase()}`,
},
cookies: {
long: { signed: true, maxAge: 24 * 60 * 60 * 1000 }, // 1 day, ms

Loading…
Cancel
Save