com.lightningkite.lightningdb.UpdateRestrictions.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of server-core Show documentation
Show all versions of server-core Show documentation
A set of tools to fill in/replace what Ktor is lacking in.
The newest version!
package com.lightningkite.lightningdb
import kotlinx.serialization.Serializable
/**
* Permission rules regarding updating items per-field.
*/
@Serializable
data class UpdateRestrictions(
/**
* If the modification matches paths, then the condition is applied to the update
*/
val fields: List> = listOf()
) {
@Serializable
data class Part(val path: DataClassPathPartial, val limitedIf: Condition, val limitedTo: Condition)
operator fun invoke(on: Modification): Condition {
val totalConditions = ArrayList>()
for(field in fields) {
if(on.affects(field.path)) {
totalConditions.add(field.limitedIf)
if(field.limitedTo !is Condition.Always) {
if(!field.limitedTo.guaranteedAfter(on)) return Condition.Never()
}
}
}
return when(totalConditions.size) {
0 -> Condition.Always()
1 -> totalConditions[0]
else -> Condition.And(totalConditions)
}
}
class Builder(
val fields: ArrayList> = ArrayList()
) {
val it = path()
/**
* Makes a field unmodifiable.
*/
fun DataClassPath.cannotBeModified() {
fields.add(Part(this, Condition.Never(), Condition.Always()))
}
/**
* Makes a field only modifiable if the item matches the [condition].
*/
infix fun DataClassPath.requires(condition: Condition) {
fields.add(Part(this, condition, Condition.Always()))
}
/**
* Makes a field only modifiable if the item matches the [condition].
* In addition, the value it is being changed to must match [valueMust].
*/
fun DataClassPath.requires(requires: Condition, valueMust: (DataClassPath)->Condition) {
fields.add(Part(this, requires, this.condition(valueMust)))
}
/**
* The value is only allowed to change to a value that matches [valueMust].
*/
fun DataClassPath.mustBe(valueMust: (DataClassPath)->Condition) {
fields.add(Part(this, Condition.Always(), this.condition(valueMust)))
}
fun build() = UpdateRestrictions(fields)
fun include(mask: UpdateRestrictions) { fields.addAll(mask.fields) }
}
}
/**
* DSL for defining [UpdateRestrictions]
*/
inline fun updateRestrictions(builder: UpdateRestrictions.Builder.()->Unit): UpdateRestrictions {
return UpdateRestrictions.Builder().apply(builder).build()
}