grails / gorm-mongodb

GORM for MongoDB

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cascade: none still cascades on insert

jameskleeh opened this issue · comments

Given the following:

class ProductLine {
    String name
}
class Product {
    String name
    ProductLine productLine

    static mapping = {
        productLine cascade: 'none'
    }
}
class ProductController extends RestfulController<Product> {

    static responseFormats = ['json', 'xml']

    ProductController() {
        super(Product)
    }
}
@CompileStatic
class ProductLineController extends RestfulController<ProductLine> {

    static responseFormats = ['json', 'xml']

    ProductLineController() {
        super(ProductLine)
    }
}

When the following is executed

curl -XPOST localhost:8080/productLine/save  --data '{"name":"Little Stuff"}'   -H 'Content-type: application/json'

`{"id":1,"name":"Little Stuff"}`

curl -XPOST localhost:8080/product/save --data '{"productLine":{"id":"1","name":"messed up stuff!"},"name":"Ship"}' -H 'Content-type: application/json'

`{"id":1,"productLine":{"id":1},"name":"Ship"}`

A request to get the original product line with id 1 will result in the name being changed to messed up stuff!

Explicitly setting cascade to none should prevent the cascade behavior, as it does in the case when the product entity is being updated.

Thanks!

The reason this is impactful: suppose in the above example that you granted access to one class of users to create products, but only high-level administrators could create or modify product lines, and that you enforce this at the controller level:

import grails.plugin.springsecurity.annotation.Secured

@Secured("RegularUserRole")
class ProductController extends RestfulController<Product> {

    static responseFormats = ['json', 'xml']

    ProductController() {
        super(Product)
    }
}
@CompileStatic
@Secured("SuperPowerfulAdminRole")
class ProductLineController extends RestfulController<ProductLine> {

    static responseFormats = ['json', 'xml']

    ProductLineController() {
        super(ProductLine)
    }
}

The current behavior would allow a regular user to arbitrarily modify instances of the ProductLine class just by creating new instances of the Product class with the REST API.