Chris Flipse wrote:
I've actually been okay with it at the unit testing / rspec level -- I've had it stubbed as you describe for a while.

The pain point came in as I was trying to setup data for Cucumber ... Which, listening to my tests, tells me that the current structure is bad. I was more curious to see how others are handling that sort of situation.

If you are seeing state from one scenario bleed over to the next I would suggest something like this in your env.rb:

After do
User.reset_current
end

I want to get *away* from the global variable, I'm just not entirely sure what the target should be. There doesn't seem to be a whole lot of talk about actual implementation specifics around model level authorization.

I generally have a current_user method defined of my controller to return the logged in user. Assuming that your app is only using User.current in your controllers you could try to move towards something like that... If you have models accessing User.current then it truly is being used as a global. :/ The user will then have some permissions methods that may take other objects or symbols. The method will simply return a boolean telling if the user is authorized or not. That logic usually is based on the role(s) of that user or relationship with the passed in object. Having this logic in the user could be viewed as a responsibility issue- should the user really be responsible for telling if it is authorized for everything? In general I do this for most simple cases. Only when it starts to get complex do I move it out into a Manager-like object.

HTH,
Ben




On Sat, Feb 28, 2009 at 2:16 PM, David Chelimsky <dchelim...@gmail.com <mailto:dchelim...@gmail.com>> wrote:

    On Sat, Feb 28, 2009 at 12:51 PM, Chris Flipse <cfli...@gmail.com
    <mailto:cfli...@gmail.com>> wrote:
    >
    >
    > On Sat, Feb 28, 2009 at 1:38 PM, David Chelimsky
    <dchelim...@gmail.com <mailto:dchelim...@gmail.com>>
    > wrote:
    >>
    >> On Sat, Feb 28, 2009 at 11:52 AM, Chris Flipse
    <cfli...@gmail.com <mailto:cfli...@gmail.com>> wrote:
    >> > I've been going back over some legacy code, backfilling
    tests, and I'm
    >> > encountering something that is causing no small amount of
    pain.  This is
    >> > in
    >> > a mature Rails app, that's  lived and migrated from 1.1
    through to 2.1,
    >> > so
    >> > there's a lot of ancient cruft built up in the corners that
    I've been
    >> > trying
    >> > to clean up.
    >> >
    >> > My question/pain point revolves around authorization.  In at
    least two
    >> > different models in the system  -- areas that are core to the
    >> > functionality
>> > -- there are models that run through a state transition. Only certain
    >> > users
    >> > are allowed to make those transitions, however.  You're basic
    "only an
    >> > admin
    >> > can publish an article" kind of restrictions.
    >> >
    >> > These models show up across most of the app -- several different
    >> > controllers.  As such, long, long ago, someone patched
    updated the site
    >> > authentication code to assign a User.current singleton inside the
    >> > login_required filter.
    >>
    >> Unless I'm missing something, this seems like the problem is wider
    >> than testability.
    >>
    >> Let's say I log in. Right now I am User.current. Now you log
    in, and
    >> become User.current. Now I got to view some resource that I am not
    >> permitted to see, but I get to see it because you are permitted and
    >> YOU are the User.current.
    >>
    >> Am I missing something?
    >
    > The login filter is called at the beginning of every request, from
    > application controller.  It resets the value, nilling it out if
    you're not
    > logged in, at the start of each request.  So long as Rails
    remains single
    > threaded, the scenario you describe isn't possible.  One
    process, one
    > request at a time.  No bleed there.
    >
    > Of course, they're supposedly working on making it not-so single
    threaded,
    > so that may eventually become a problem.  All the more reason to
    find
    > something that doesn't suck.

    :)

    >> > This is then used by several models, sometimes to
    >> > populate an updated_by stamp, sometimes it's actually used
    within a
    >> > models
    >> > validations(!), and it's definately used within some of the
    >> > state-transition
    >> > guards.
    >> >
    >> > Now, this is really just a global variable by another name,
    and it's
    >> > pretty
    >> > well embedded after two years.  I've come upon a whole bunch of
    >> > different
    >> > pain points in trying to setup data (real data) within the
    cucumber
    >> > steps
    >> > I've been backfilling.  Lacking any support of injection, I
    end up doing
    >> > a
    >> > lot of juggling of the User.current value

    You can stub this in your code examples:

     User.stub!(:current).and_return(mock_model(User, :authorized? =>
    true))

    or

     User.stub!(:current).and_return(mock_model(User, :authorized? =>
    false))

    etc.

    Replace "authorized? => true/false" with whatever is necessary for the
    authorization to pass or fail as needed in each example.

    Stubs are cleared out after each example, so you don't have to use any
    additional injection techniques.

    HTH,
    David

    >>just to get some test data
    >> > built
    >> > and in the right set of states ... and while I can bury the
    temporary
    >> > reassignments necessary inside a block, it still feels like
    it's an
    >> > intractable mess.
    >> >
    >> > I know *why* this was originally done -- to avoid having to
    pass User
    >> > objects around all the time, and it does _appear_ to keep the
    API clean
    >> > --
    >> > but the hidden dependancy isn't really clean.
    >> >
    >> > So, does anyone have any suggestions of how to easily manage
    model level
    >> > user authorization?




    >> >
    >> > --
    >> > // anything worth taking seriously is worth making fun of
    >> > // http://blog.devcaffeine.com/
    >> >
    >> > _______________________________________________
    >> > rspec-users mailing list
    >> > rspec-users@rubyforge.org <mailto:rspec-users@rubyforge.org>
    >> > http://rubyforge.org/mailman/listinfo/rspec-users
    >> >
    >> _______________________________________________
    >> rspec-users mailing list
    >> rspec-users@rubyforge.org <mailto:rspec-users@rubyforge.org>
    >> http://rubyforge.org/mailman/listinfo/rspec-users
    >
    >
    >
    > --
    > // anything worth taking seriously is worth making fun of
    > // http://blog.devcaffeine.com/
    >
    > _______________________________________________
    > rspec-users mailing list
    > rspec-users@rubyforge.org <mailto:rspec-users@rubyforge.org>
    > http://rubyforge.org/mailman/listinfo/rspec-users
    >
    _______________________________________________
    rspec-users mailing list
    rspec-users@rubyforge.org <mailto:rspec-users@rubyforge.org>
    http://rubyforge.org/mailman/listinfo/rspec-users




--
// anything worth taking seriously is worth making fun of
// http://blog.devcaffeine.com/
------------------------------------------------------------------------

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to