1

grails プロジェクトで spring security core プラグインを使用しています。Person ドメインは次のようになります。

class User {

transient springSecurityService

//Mandatory Fields
String employeeId
String firstName
String lastName
String password
String emailId

//Other Fields
String department
String extn

String mobileNumber
String address
String city
String zipCode
String country

User manager

static hasMany = [previousPasswords: String]

boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired

static transients = ['springSecurityService']

static constraints = {
    employeeId blank: false, unique: true
    firstName blank: false
    lastName blank: false
    password blank: false, password: true, validator: {val, obj ->
        if(obj.previousPasswords) {
            println "-----------------------1-------------------------"
            println "obj.previousPasswords: " + obj.previousPasswords
            println "val: " + val
            if (obj.isDirty('password')) {
                println "-----------------------2-------------------------"
                if(obj.previousPasswords.contains(val)) {
                    obj.errors.rejectValue(
                        'password',
                        'user.password.duplicated',
                        'Repeat passwords are not allowed')
                    return false
                }
                println "-----------------------3-------------------------"
                obj.addToPreviousPasswords(val)
                return true
            }
        } else {
            println "-----------------------4-------------------------"
            obj.addToPreviousPasswords(val)
            return true
        }
    }
    emailId blank: false, email: true

    department nullable: true
    extn nullable: true

    mobileNumber nullable: true
    address nullable: true
    city nullable: true
    zipCode nullable: true
    country nullable: true

    manager nullable: true
}

static mapping = {
    password column: '`password`'
}

Set<Role> getAuthorities() {
    UserRole.findAllByUser(this).collect { it.role } as Set
}

def beforeInsert() {
    println "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
    encodePassword()
}

def beforeUpdate() {
    if (isDirty('password')) {
        println "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
        encodePassword()
    }
}

protected void encodePassword() {
    password = springSecurityService.encodePassword(password)
}
}

「パスワード」フィールドのカスタムバリデーターを作成したパスワードが繰り返されないようにする必要があります

私の統合テストは次のようになります

void "Test if previous passwords can be re-used"() {
    given:
    def user = new User(employeeId: "empId1", firstName: "f_name", lastName: "l_name", password: "password", emailId: "test@hptest.com", mobileNumber: "(111) 111-1111", address: "350 Fifth Avenue, 34th floor", city: "New York", zipCode: "10007")
    println "&&&&&&&&&&&&&&&&&&&  1  &&&&&&&&&&&&&&&&&&&&&&"
    user.springSecurityService = springSecurityService
    println "&&&&&&&&&&&&&&&&&&&  2  &&&&&&&&&&&&&&&&&&&&&&"
    user.save(flush: true, failOnError: true)

    when: 'password is repeated'
    user.password = "password"
    println "&&&&&&&&&&&&&&&&&&&  3  &&&&&&&&&&&&&&&&&&&&&&"
    user.save(flush: true)

    then: 'validation fails'
    !user.validate()
    user.errors.getFieldError("password").codes.contains("validator.invalid")

    when: 'password is not repeated'
    user.password = "password@123"

    then: 'validation succeeds'
    println "&&&&&&&&&&&&&&&&&&&  4  &&&&&&&&&&&&&&&&&&&&&&"
    user.validate()
    println "&&&&&&&&&&&&&&&&&&&  5  &&&&&&&&&&&&&&&&&&&&&&"
    user.save(flush: true)
}

そして、私が得ている出力はこのようなものです

&&&&&&&&&&&&&&&&&&&  1  &&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&  2  &&&&&&&&&&&&&&&&&&&&&&
-----------------------4-------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-----------------------1-------------------------
obj.previousPasswords: [password]
val: $2a$10$mxFM9S7mEoOdyRo6xJL9/uzVafUgc0.8r1rd4nzBYM45s2cE8TTDi
&&&&&&&&&&&&&&&&&&&  3  &&&&&&&&&&&&&&&&&&&&&&
-----------------------1-------------------------
obj.previousPasswords: [password]
val: password
-----------------------2-------------------------
-----------------------1-------------------------
obj.previousPasswords: [password]
val: password

コードと出力を注意深く調べると、保存操作ごとにバリデータ関数が 2 回呼び出されていることがわかります。

この理由を誰か教えてください。これは、バリデータ内で使用している addTo メソッドが原因でしょうか?

4

1 に答える 1