FEATURE: enforce admin password validation when signing up via developer email

This commit is contained in:
Arpit Jalan 2016-03-03 23:31:31 +05:30
parent 04990e7c5c
commit 36f82aa68c
4 changed files with 44 additions and 35 deletions

View File

@ -16,6 +16,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
rejectedPasswords: Em.A([]),
prefilledUsername: null,
userFields: null,
isDeveloper: false,
hasAuthOptions: Em.computed.notEmpty('authOptions'),
canCreateLocal: setting('enable_local_logins'),
@ -37,6 +38,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
rejectedEmails: [],
rejectedPasswords: [],
prefilledUsername: null,
isDeveloper: false
});
this._createUserFields();
},
@ -70,8 +72,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
}.property('authOptions.auth_provider'),
passwordInstructions: function() {
return I18n.t('user.password.instructions', {count: Discourse.SiteSettings.min_password_length});
}.property(),
return this.get('isDeveloper') ? I18n.t('user.password.instructions', {count: Discourse.SiteSettings.min_admin_password_length}) : I18n.t('user.password.instructions', {count: Discourse.SiteSettings.min_password_length});
}.property('isDeveloper'),
nameInstructions: function() {
return I18n.t(Discourse.SiteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions');
@ -228,41 +230,27 @@ export default Ember.Controller.extend(ModalFunctionality, {
const _this = this;
if (this.shouldCheckUsernameMatch()) {
return Discourse.User.checkUsername(this.get('accountUsername'), this.get('accountEmail')).then(function(result) {
_this.set('globalNicknameExists', false);
_this.set('isDeveloper', false);
if (result.available) {
if (result.global_match) {
_this.set('globalNicknameExists', true);
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
ok: true,
reason: I18n.t('user.username.global_match')
}));
} else {
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
ok: true,
reason: I18n.t('user.username.available')
}));
if (result.is_developer) {
_this.set('isDeveloper', true);
}
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
ok: true,
reason: I18n.t('user.username.available')
}));
} else {
if (result.suggestion) {
if (result.global_match !== void 0 && result.global_match === false) {
_this.set('globalNicknameExists', true);
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
failed: true,
reason: I18n.t('user.username.global_mismatch', result)
}));
} else {
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
failed: true,
reason: I18n.t('user.username.not_available', result)
}));
}
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
failed: true,
reason: I18n.t('user.username.not_available', result)
}));
} else if (result.errors) {
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
failed: true,
reason: result.errors.join(' ')
}));
} else {
_this.set('globalNicknameExists', true);
return _this.set('uniqueUsernameValidation', Discourse.InputValidation.create({
failed: true,
reason: I18n.t('user.username.enter_email')
@ -296,8 +284,16 @@ export default Ember.Controller.extend(ModalFunctionality, {
return Discourse.InputValidation.create({ failed: true });
}
// If too short
if (password.length < Discourse.SiteSettings.min_password_length) {
// If too short for Admin
if (this.get('isDeveloper') && password.length < Discourse.SiteSettings.min_admin_password_length) {
return Discourse.InputValidation.create({
failed: true,
reason: I18n.t('user.password.too_short')
});
}
// If too short for normal user
if (!this.get('isDeveloper') && password.length < Discourse.SiteSettings.min_password_length) {
return Discourse.InputValidation.create({
failed: true,
reason: I18n.t('user.password.too_short')
@ -330,7 +326,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
ok: true,
reason: I18n.t('user.password.ok')
});
}.property('accountPassword', 'rejectedPasswords.@each', 'accountUsername', 'accountEmail'),
}.property('accountPassword', 'rejectedPasswords.@each', 'accountUsername', 'accountEmail', 'isDeveloper'),
@on('init')
fetchConfirmationValue() {
@ -360,6 +356,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.set('formSubmitted', true);
return Discourse.User.createAccount(attrs).then(function(result) {
self.set('isDeveloper', false);
if (result.success) {
// Trigger the browser's password manager using the hidden static login form:
const $hidden_login_form = $('#hidden-login-form');
@ -369,6 +366,9 @@ export default Ember.Controller.extend(ModalFunctionality, {
$hidden_login_form.submit();
} else {
self.flash(result.message || I18n.t('create_account.failed'), 'error');
if (result.is_developer) {
self.set('isDeveloper', true);
}
if (result.errors && result.errors.email && result.errors.email.length > 0 && result.values) {
self.get('rejectedEmails').pushObject(result.values.email);
}

View File

@ -343,7 +343,8 @@ class UsersController < ApplicationController
errors: user.errors.full_messages.join("\n")
),
errors: user.errors.to_hash,
values: user.attributes.slice('name', 'username', 'email')
values: user.attributes.slice('name', 'username', 'email'),
is_developer: UsernameCheckerService.new.is_developer?(user.email)
}
end
rescue ActiveRecord::StatementInvalid

View File

@ -6,17 +6,21 @@ class UsernameCheckerService
if !validator.valid_format?
{errors: validator.errors}
else
check_username_availability(username)
check_username_availability(username, email)
end
end
end
def check_username_availability(username)
def check_username_availability(username, email)
if User.username_available?(username)
{ available: true }
{ available: true, is_developer: is_developer?(email) }
else
{ available: false, suggestion: UserNameSuggester.suggest(username) }
end
end
def is_developer?(value)
Rails.configuration.respond_to?(:developer_emails) && Rails.configuration.developer_emails.include?(value)
end
end

View File

@ -6,7 +6,7 @@ class PasswordValidator < ActiveModel::EachValidator
return unless record.password_required?
if value.nil?
record.errors.add(attribute, :blank)
elsif value.length < SiteSetting.min_admin_password_length && record.admin?
elsif value.length < SiteSetting.min_admin_password_length && (record.admin? || is_developer?(record.email))
record.errors.add(attribute, :too_short, count: SiteSetting.min_admin_password_length)
elsif value.length < SiteSetting.min_password_length
record.errors.add(attribute, :too_short, count: SiteSetting.min_password_length)
@ -19,4 +19,8 @@ class PasswordValidator < ActiveModel::EachValidator
end
end
def is_developer?(value)
Rails.configuration.respond_to?(:developer_emails) && Rails.configuration.developer_emails.include?(value)
end
end