Grails2.0.2以降のbinding機構にハメられた件
ハマった。
Grails2.0.0で実装途中だったプロダクトを2.0.3に上げてみたらテストが通らなくなった。
半端なバージョンだけれども、例のgithubでもあったRailsの脆弱性と同じ問題に対処するために、Grails2.0.2からコントローラ上でhoge.properties = params や new Hoge(params)としたときにすべてのプロパティをがっつり反映しないように制御できるようになっています。
http://blog.springsource.org/2012/03/28/secure-data-binding-with-grails/
transientsなプロパティは明示的にbindable:trueしないと、そのプロパティはバインドされないようになってました。
In Grails 2.0.2 the data binding mechanism will by default exclude all properties which are static, transient or dynamically typed.
前述のブログにしっかり書いてた。staticとtransientと動的型はデフォルト除外(bindable=false)だそうな。
一度きちんと整理しないといけないなーとは思うけど、とりあえず試した結果をはっておく。
bindable:trueを設定した場合、これはグリーン
class Book { String name String author String transientField static transients = ['transientField'] static constraints = { transientField bindable:true } }
import grails.test.mixin.TestFor import org.junit.Test @TestFor(Book) class BookTests { @Before void setUp() { mockForConstraintsTests(Book) } @Test void constraintsOfTransientField() { def book = new Book(name: "NAME", author: "AUTHOR", transientField: "TRANSIENT!") assert book.name == "NAME" assert book.author == "AUTHOR" assert book.transientField == "TRANSIENT!" // 設定される } }
bindable:falseを設定した場合、これはグリーン
class Book { String name String author String transientField static transients = ['transientField'] static constraints = { transientField bindable:false } }
import grails.test.mixin.TestFor import org.junit.Test @TestFor(Book) class BookTests { @Before void setUp() { mockForConstraintsTests(Book) } @Test void constraintsOfTransientField() { def book = new Book(name: "NAME", author: "AUTHOR", transientField: "TRANSIENT!") assert book.name == "NAME" assert book.author == "AUTHOR" assert book.transientField == null // 反映されてない } }
constraintsで明示指定しない=transientなプロパティのデフォルトbindable:false、これはグリーン
class Book { String name String author String transientField static transients = ['transientField'] }
import grails.test.mixin.TestFor import org.junit.Test @TestFor(Book) class BookTests { @Before void setUp() { mockForConstraintsTests(Book) } @Test void constraintsOfTransientField() { def book = new Book(name: "NAME", author: "AUTHOR", transientField: "TRANSIENT!") assert book.name == "NAME" assert book.author == "AUTHOR" assert book.transientField == null // 反映されてない } }
constraintsで明示指定しない=通常のプロパティのデフォルトbindable:true、これはグリーン
class Book {
String name
String author
String transientField
}
import grails.test.mixin.TestFor import org.junit.Test @TestFor(Book) class BookTests { @Before void setUp() { mockForConstraintsTests(Book) } @Test void constraintsOfTransientField() { def book = new Book(name: "NAME", author: "AUTHOR", transientField: "TRANSIENT!") assert book.name == "NAME" assert book.author == "AUTHOR" assert book.transientField == "TRANSIENT!" // 反映された(まあname, authorとかわらんのだけど) } }