Access control with ProtoUser and CRUDify

81 views
Skip to first unread message

Kuba Neumann

unread,
Dec 28, 2010, 8:26:40 PM12/28/10
to Lift
Hi,

In our project the prototype phase has been finished. In some part of
our simple application the functionality offered by CRUDify is
sufficient. Because of this we consider to use CRUDify in production,
but there are some doubt (rather lack of knowledge) concerning
security and access control. This is the said part of our application.
User management is done by *ProtoUser. Users can have accounts (model
Account with CRUDify has the foreign key field "owner"). SiteMap
controls if the user is logged in. CRUDify lists only accounts owned
by the user and properly does other crud actions.

But nothing prevents other logged in users to edit (view, delete)
other user's accounts (simply by c&p crudify actions url).
So, how we can easily protect accounts in this situation (I mean using
CRUDify and *ProtoUser)? We considered AuthRole and
Http*Authentication but it's not obvious for us how to use it with
*ProtoUser.

Besides of our access problem, is it generally a good idea to use
CRUDify in production? Could you please share your experience and
thoughts?

Best regards
Kuba

David Pollak

unread,
Dec 28, 2010, 11:26:32 PM12/28/10
to lif...@googlegroups.com
On Tue, Dec 28, 2010 at 5:26 PM, Kuba Neumann <kuba.n...@gmail.com> wrote:
 Hi,

In our project the prototype phase has been finished. In some part of
our simple application the functionality offered by CRUDify is
sufficient. Because of this we consider to use CRUDify in production,
but there are some doubt (rather lack of knowledge) concerning
security and access control. This is the said part of our application.
User management is done by *ProtoUser. Users can have accounts (model
Account with CRUDify has the foreign key field "owner"). SiteMap
controls if the user is logged in. CRUDify lists only accounts owned
by the user and properly does other crud actions.

But nothing prevents other logged in users to edit (view, delete)
other user's accounts (simply by c&p crudify actions url).
So, how we can easily protect accounts in this situation (I mean using
CRUDify and *ProtoUser)? We considered AuthRole and
Http*Authentication but it's not obvious for us how to use it with
*ProtoUser.


Just override Crufidy's findForList (only present the user with a list of records they are allowed to see) and findForParam (only return a Full if the user has the right to see the record).

You can override the obscurePrimaryKey method to create session-specific primary keys such that the primary keys are not repeated except during the current session.

Does this help or do you need something more concrete?
 

Besides of our access problem, is it generally a good idea to use
CRUDify in production? Could you please share your experience and
thoughts?

Best regards
 Kuba

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics

Kuba Neumann

unread,
Dec 29, 2010, 3:07:41 AM12/29/10
to Lift
David, thanks for your fast response
On Dec 29, 5:26 am, David Pollak <feeder.of.the.be...@gmail.com>
wrote:
> On Tue, Dec 28, 2010 at 5:26 PM, Kuba Neumann <kuba.neum...@gmail.com>wrote:
> >  Hi,
>
> > In our project the prototype phase has been finished. In some part of
> > our simple application the functionality offered by CRUDify is
> > sufficient. Because of this we consider to use CRUDify in production,
> > but there are some doubt (rather lack of knowledge) concerning
> > security and access control. This is the said part of our application.
> > User management is done by *ProtoUser. Users can have accounts (model
> > Account with CRUDify has the foreign key field "owner"). SiteMap
> > controls if the user is logged in. CRUDify lists only accounts owned
> > by the user and properly does other crud actions.
>
> > But nothing prevents other logged in users to edit (view, delete)
> > other user's accounts (simply by c&p crudify actions url).
> > So, how we can easily protect accounts in this situation (I mean using
> > CRUDify and *ProtoUser)? We considered AuthRole and
> > Http*Authentication but it's not obvious for us how to use it with
> > *ProtoUser.
>
> Just override Crufidy's findForList (only present the user with a list of
> records they are allowed to see) and findForParam (only return a Full if the
> user has the right to see the record).

This is what I did before. It works but doesn't prevent logged in
users to do CRUDify actions of other users.
Unfortunately all examples and previous topics I found test only if
the user is logged in. But with CRUDify it is insufficient.

> You can override the obscurePrimaryKey method to create session-specific
> primary keys such that the primary keys are not repeated except during the
> current session.
Ok, I didn't think about it. It could solve the problem.

> Does this help or do you need something more concrete?
Could you please give a few details how to obfuscate pk in a secure,
acceptable in production way?
I guess it could be difficult because we need an invertible (insecure)
function.

Best regards
Kuba
>
> > Besides of our access problem, is it generally a good idea to use
> > CRUDify in production? Could you please share your experience and
> > thoughts?
>
> > Best regards
> >  Kuba
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Lift" group.
> > To post to this group, send email to lif...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/liftweb?hl=en.
>
> --
> Lift, the simply functional web frameworkhttp://liftweb.net
> Beginning Scalahttp://www.apress.com/book/view/1430219890

andrea

unread,
Dec 29, 2010, 9:23:01 AM12/29/10
to Lift

David Pollak

unread,
Dec 29, 2010, 7:19:56 PM12/29/10
to lif...@googlegroups.com
Sure it does.  If another user can't access a record, they can't view, remove, edit it.

Here's the singleton code:


object Frog extends Frog with LongKeyedMetaMapper[Frog] with
CRUDify[Long, Frog] 
{
  override def createMenuLocParams: List[Loc.AnyLocParam] = 
    List(If(User.loggedIn_? _, "Not logged in"))
  
  override def findForList(start: Long, cnt: Int): List[Frog] = 
    findAll(StartAt(start), MaxRows(cnt), By(owner, User.currentUser))


  override def findForParam(in: String): Box[Frog] = 
    for {
      user <- User.currentUser
      id <- Helpers.asLong(in)
      frog <- find(By(this.id, id), By(owner, user))
    } yield frog
}

 
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890

Kuba Neumann

unread,
Dec 31, 2010, 10:31:12 AM12/31/10
to Lift
On Dec 30, 1:19 am, David Pollak <feeder.of.the.be...@gmail.com>
wrote:
> A whole running example is here:https://github.com/dpp/starting_point/commit/5ae429c087ad60fa7adc5c72...

David, thanks a lot.

Your example (with Frog) let me find a bug in my findForParam method.
Now everything concerning access control is ok!

But when I use the following (as in your example):
override def defaultValue = User.currentUser.open_!.id.is
in object owner (both in your Frog and in my Account) I get:
DEBUG net.liftweb.mapper.MetaMapper - Not a valid mapped field: owner,
got exception: java.lang.reflect.InvocationTargetException

Generally, I had some problems with defaultValue, so I did the
following:

object owner MappedLongForeignKey(this, User) with LifecycleCallbacks
override def beforeSave = {
User.currentUser match {
case Full(u: User) => this(u.id)
case _ => throw new IllegalStateException("Only logged in user
can create an account")
}
}

Best regards
Kuba
Reply all
Reply to author
Forward
0 new messages