Owned

io.eezo.http.Owned
final class Owned[A, U](val ownerOf: OwnerOf[A, Id[U]], val currentUser: Request => Option[Id[U]], val covers: Set[Action], guarded: Guarded[A]) extends Guarded[A]

The declaration, made beside a model, that a row belongs to the user who created it and that some of its routes are that user's alone.

A Guarded and not a sibling of one, because owned implies guarded and never the reverse: the routes covered here are routes whose handler asks who is signed in, and a route that refuses nobody has nobody to compare a row's owner with. Being a subtype is also what keeps the route table's guard lookup and its mounting exactly as they were, and what lets a model declare given Owned[Post, User] and nothing else.

Data, like Guarded, and for the same reason: modules/auth ships one way of producing one and any other way has to produce one of these and nothing more.

covers is a second set beside the inherited actions, and the two are genuinely different questions. actions is which routes need a signed in user; covers is which of them read and write through that user's rows alone. A blog guards all seven and scopes five of them, so that everybody reads everybody's posts and nobody edits another's; a cart guards and scopes the same seven, so that a cart is invisible to anyone but its owner. Folding them into one set would make the blog's index private and the cart's enumerable, depending on which reading won.

Type parameters

U

the application's own user model, which appears only as the type of a key. Nothing here reads a user, and that is what keeps http free of a guard.

Attributes

Source
Owned.scala
Graph
Supertypes
class Guarded[A]
class Object
trait Matchable
class Any

Members list

Value members

Inherited methods

def mounting(route: Route): Seq[Route]

What one handwritten route becomes in the table: the guard's own pages, and that route wrapped.

What one handwritten route becomes in the table: the guard's own pages, and that route wrapped.

A handwritten route has no Action, so there is nothing to test actions against and the wrapper reaches it directly. A page is guarded or it is public, which is the same rule Guarded[Index.type] = Guarded.public states in the other direction, and public wraps nothing and carries nothing, so an unguarded application's table is exactly what it was.

The login page comes out of every declaration rather than being mounted once somewhere else, because the two have to arrive together: a route that redirects to a page nobody mounted is a 404 at the end of every refusal. The table takes distinct afterwards, which is safe only because one guard builds its routes once and hands the same instances to every declaration it makes.

Attributes

Inherited from:
Guarded
Source
Guarded.scala

Concrete fields

val covers: Set[Action]

Attributes

Source
Owned.scala
val currentUser: Request => Option[Id[U]]

Attributes

Source
Owned.scala
val ownerOf: OwnerOf[A, Id[U]]

Attributes

Source
Owned.scala

Inherited fields

val actions: Set[Action]

Attributes

Inherited from:
Guarded
Source
Guarded.scala
val carries: Seq[Route]

Attributes

Inherited from:
Guarded
Source
Guarded.scala

Attributes

Inherited from:
Guarded
Source
Guarded.scala
val through: Route => Route

Attributes

Inherited from:
Guarded
Source
Guarded.scala