rails
(58,680 views)

stateful authentication

I wanted user records in my app to have various statuses. Here's how I modified restful_authentication with acts_as_state_machine to accomplish this. I'll call it stateful_authentication

Overview

The idea is to enhance restful_authentication with additional user statuses.

  • :passive - not authorized to log in, but known to the system, such as for mailing lists
  • :pending - user has registered but has not activated his account yet
  • :active - user account is active, user can log in
  • :suspended - user account suspended, not allowed to log in, can be re-enabled
  • :deleted - user id remains valid but account deleted, login name and email can be reused

Passive users may have signed up on the system, given their email and name or whatever, but don't have the right to log in. Passive users can register later with login privileges.

An active user can log in. (As for roles, authorization is handled separately from authentication, see my earlier post ).

Any user can be suspended by the administrator, for whatever reason. Suspended accounts can be re-enabled (un-suspended).

Keeping deleted user records is handy, for example, if some other objects such as a Comment references this user id, you can still retrieve some info about the poster even if he's no longer around. (A separate admin purge action can actually call destroy on deleted users). A deleted user will have its login and email changed with the string "[DELETED datetime]" appended, so they can be reused in a new user record.

"john@gmail.com [DELETED Fri Sep 21 13:35:07 -0400 2007]" 

In restful_authentication, the User model includes columns for login name, email, crypted_password, activation_code (allows user to active the account), and activated_at date (once account is activated). You could say an :active status is implied when activated_at is not blank?; and a :pending status is implied when activation_code is not blank?.

Our case extends this. You could say a :passive status is when both activated_at and activation_code are nil. But any user can be suspended or deleted regardless of these attribute values.

Setup

This article assumes you have installed the restful_authentication plugin and the acts_as_state_machine plugin. Note, I generated RA to require user activation (--include-activation).

  $ script/plugin source http://svn.techno-weenie.net/projects/plugins
  $ script/plugin install restful_authentication
  $ script/generate authenticated user sessions --include-activation
  $ rake db:migrate 
add observer to environment.rb 
add named routes to routes.rb
move lines from users_controller.rb to application.rb
edit user_notifier.rb as needed 
  $ script/plugin install http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/ 

I'll leave other details to others, e.g.

http://svn.techno-weenie.net/projects/plugins/restful_authentication/README

http://weblog.techno-weenie.net/2006/8/1/restful-authentication-plugin

http://agilewebdevelopment.com/plugins/restful_authentication

http://www.urbanpuddle.com/articles/2007/03/05/restful-authentication-for-ruby-on-rails-apps

http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/README

http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts_as_state_machine/

http://www.slideshare.net/dhpeterson/a-simple-workflow-system-using-state-machines

http://iamruinous.com/2007/3/6/automatically-calling-acts_as_state_machine-events-on-update

Maybe I should consider making this a whole new plugin, but for now here's instructions to DIY (do it yourself).

User model

Make the User a state-machine. First, add a status attribute to the User model (we'll call it status rather than state)

$ script/generate migration add_status_to_users

edit with

add_column :users, :status, :string, :null => :no, :default => "passive" 

and then

$ rake db:migrate 

 

To models/user.rb, add:

  acts_as_state_machine :initial => :passive, :column => :status
state :passive
state :pending, :enter => :make_activation_code
state :active, :enter => :do_activate
state :suspended
state :deleted, :enter => :do_delete

Add the state machine transition events:

  event :register do
transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !u.crypted_password.blank? }
end

event :activate do
transitions :from => :pending, :to => :active
end

event :suspend do
transitions :from => [:passive, :pending, :active], :to => :suspended
end

event :delete do
transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted
end

event :unsuspend do
transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| !u.activated_at.blank? }
transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| !u.activation_code.blank? }
transitions :from => :suspended, :to => :passive
end
 

Thus when a new user is created, it's :passive. Then, user.register! will move a user from :passive to :pending (provided it has a password), and an activation_code is generated).

user.activate! will activate the account. To avoid confusion with the original #activate method, rename the old one to #do_activate. And make a small change to preserve the activated_at date (like when transitioning from suspended back to active).

  # rename old activate to do_activate
def do_activate
    @activated = true
    self.activated_at ||= Time.now.utc
    self.activation_code = nil
end

Also, now the activated? method is handled by our new active? method:

  # retain for compatibility, redundant with active?
  def activated?
active?
  end

Add a do_delete method (can be in protected)

    def do_delete
t = Time.now.to_s
      self.login += " [DELETED #{t}]"
      self.email += " [DELETED #{t}]"
    end

Comment out the following because a new passive user doesn't need an activation code. Rather, this gets called in the :pending :enter callback:

#before_create :make_activation_code

When is password required? In original RA, it was always required if the crypted_password attribute is blank (new user) or if the password is being changed. Now, users don't need a password unless they're going to be activating an account, and guard that in the :register event transition. So the password (and password_confirmation) is validated only if it is present, thus, change password_required to

    def password_required?
      !password.blank?
    end 

One last thing, we only want to authenticate users who are active. Change self.authenticate to check:

  def self.authenticate(login, password)
    u = find :first, :conditions => ['login = ? and status = "active"', login]
    u && u.authenticated?(password) ? u : nil
  end

Note that anywhere in your code that you do a Users.find, you now need to scope that by the requested state, such as

users = User.find_all_by_status(:active)

 

UsersController

Okeydokey, next is the controller...

In users_controller.rb, the create action can now create either a passive or pending user. We'll use the presence of a password field to signal a new registration otherwise its a passive signup. Note, create does double duty, if the user exists as passive, it still moves ahead (or you could add an update action if this disturbs your REST, see this ).

  def create
    @user = User.find_by_email_and_status(params[:user][:email], :passive) if params[:user][:email]
    if @user.nil?
      @user = User.new(params[:user])
      @user.save!
    end
    @user.register! if params[:password]
    self.current_user = @user if @user.pending? # lets user be logged in before activating
    redirect_back_or_default('/')
    flash[:notice] = "Thanks for signing up!"
  rescue ActiveRecord::RecordInvalid
    render :action => 'new'
  end

(Notes: I decided to key off a unique email rather than login name, seems more intuitive. Could be either. #create must fail if there's no params[:email]; we let the User.new handle that validation and rescue).

In the activate action, the only change is call the new #activate! rather than #activate

  def activate
    self.current_user = User.find_by_activation_code(params[:activation_code])
    if logged_in? && !current_user.activated?
      current_user.activate!
      flash[:notice] = "Signup complete!"
    end
    redirect_back_or_default('/')
  end

If you've included the forgot password stuff then in #forgot_password, change this line:

    #if @user = User.find_by_email(params[:user][:email])
    if @user = User.find_by_email_and_status(params[:user][:email], "active") 

Finally, we can add #suspend, #unsuspend, #destroy and #purge actions (which should be available only to authorized admin users-- you'll need your own :admin_required helper for this).

before_filter :admin_required, :only => [:suspend, :unsuspend, :destroy, :purge]
 
  # PUT /users/1/suspend
def suspend
@user = User.find(params[:id])
@user.suspend!
redirect_to(users_url)
end

# PUT /users/1/unsuspend
def unsuspend
@user = User.find(params[:id])
@user.unsuspend!
redirect_to(users_url)
end

# DELETE /users/1
def destroy
@user = User.find(params[:id])
@user.delete!
redirect_to(users_url)
end

# DELETE /users/1/purge
def purge
@user = User.find(params[:id])
@user.destroy
redirect_to(users_url)
end
 
Make sure the corresponding routes are mapped in routes.rb. This is how I'm doing it,
    map.resources :users, 
:member => { :suspend => :put,
:unsuspend => :put,
:purge => :delete }

along with all the other named routes for the RA plugin (e.g. map.signup, map.activate, etc).

Observer / Notifier

The signup notification email (with activation_code) should be sent only when the user is pending. In user_observer.rb, remove the entire after_create method and add the following line to after_save

UserNotifier.deliver_signup_notification(user) if user.pending?

Views

You could also adjust your views, but basically now a user can sign up with or without a password. When password is omitted, a passive user is captured (say, for subscription to a newsletter). When password is provided, he goes through full registration. Passive users can register later by supplying his email and a new password.

Tests

To get the restful_authentication tests to work with our changes, do the following:

in users.yml,

add "status: active" to the quentin user record

add "status: pending" to the aaron user record

in user_test.rb:

remove the test_should_require_password, since its not required

in users_controller_test.rb:

remove the test_should_require_password_on_signup, since its not required

To extend the tests for our new features... well, yes you should do that. Here's a handful that'd go into user_test.rb, certainly not full coverage.

    def test_should_create_passive_user
      assert_difference User, :count do
        user = create_user(:password => nil, :password_confirmation => nil)
        assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
        assert user.passive?
      end
    end     
    def test_should_register_passive_user
        user = create_user(:password => nil, :password_confirmation => nil)
        assert user.passive?
        user.update_attributes(:password => 'new password', :password_confirmation => 'new password')
        user.register!
        assert user.pending?
    end  
    def test_should_suspend_user
      users(:quentin).suspend!
      assert users(:quentin).suspended?
    end   
    def test_suspended_user_should_not_authenticate
      users(:quentin).suspend!
      assert_not_equal users(:quentin), User.authenticate('quentin', 'test')
    end   
    def test_should_unsuspend_user
      users(:quentin).suspend!
      assert users(:quentin).suspended?
      users(:quentin).unsuspend!
      assert users(:quentin).active?
    end   
    def test_should_delete_user
      users(:quentin).delete!
      assert_not_equal users(:quentin).login, 'quentin'
      assert_not_equal users(:quentin).email, 'quentin@example.com'
      assert users(:quentin).deleted?
    end

 

 

Comments

by Hendy Irawan on Nov 06, 2007

>>

I would suggest using a datetime column "deleted_at" rather than modifying the fields directly (appending string datetime) if state is deleted.

Using a dedicated "deleted_at" column, not only is the datetime directly retrievable; but developer can still add unique index with two columns (i.e. email and deleted_at). So there can only be one active user with that email, but there can be many deleted users with exact same email. (i.e. the email is reusable if deleted)

by admin on Nov 06, 2007

>>

Hendy, I agree that seems cleaner. We'd also need to change the email validation, perhaps something like (I havent tried this yet)

validates_uniqueness_of :email , :if => Proc.new { |u| !u.deleted_at.blank? }

by admin on Nov 06, 2007

>>

maybe also override find_by_email to actually call find_by_email_and_deleted_at( email, nil )

by rick on Dec 08, 2007

>>

Just so you know, I'm adding this to restful auth with a few tweaks (using the deleted_at suggestion, and keeping the aasm default column name 'state'.

by Harry on Dec 11, 2007

>>

Thanks for doing this.

One note: I think the user_observer should be changed to UserMailer.deliver_activation(user) if user.active?

Otherwise, since 'pending' is the default, you get the signup email and the activation email both at the same time even though the user hasn't activated the account yet.

by Harry on Dec 11, 2007

>>

Sorry, spoke too soon. Rick, it's in your user_observer.rb for the restful authentication plugin.

by codepope on Dec 13, 2007

>>

If you change to "UserMailer.deliver_activation(user) if user.active?" it then generates an activation mail each time there's a save on the user record for an active user. This is not good.

Taking the observer out of the equation and wiring the UserMailer calls into the User model kinda works.... (generates 2 activation mails currently... working on that)...

by xavier on Dec 17, 2007

>>

I am keeping 'UserMailer.deliver_activation(user) if user.pending?' (out of the box config) but receive both at the same time notification and activation mails automatically. Where is the user.save that triggers the activation mail before the user really activates through the notification link?

by Harry on Dec 18, 2007

>>

In case you're interested, I think I have a solution to the activation email problem: http://harrylove.org/2007/12/17/activation-emails-with-restful-authentication-an d-acts_as_state_machine

by jonson on Jan 06, 2008

>>

i tried figuring this out. it didn't work for me. the authentication code was never sent to users, becuase you deleted the before_save. adding that code back into this, helped there. but in my app, passive is useless. i guess i can change wherever you have passive to pending and see what happens. I mean, in my app, no matter how i tried to authenticate a user, the database had my users as passive. always. thanks

by Jamie Kaplan on Jan 09, 2008

>>

Seems to me that acts_as_state_machine is somewhat lacking since it doesn't trigger the code associated with the initial state until AFTER it's saved. Shouldn't it call said logic on the model just after it's created, but before it's saved? (I'm trying to sort out the details of what's described above as well (changing active? to pending?, replacing the observer with all-state-machine code, etc.)). Things are definitely not working as they are. (of course, thanks to all of those who've gotten us this far!)

by emil tin on Jan 25, 2008

>>

In my view, the fundamental problem here is that UserObserver is triggered by things like after_save, etc, but what we really want to observe is changes in the state of the state machine. That's why things get complicated and stop working. Acts_as_state_machine already gives us the mechanism to listen for state changes. So a better solution might to send emails directly User, or create a new type of observer class that listens for state changes in acts_as_state_machine model like User. (Although I'm not sure how this would be done technically.) It seems this is in line with that Jamie said above.

by Ches on Feb 28, 2008

>>

I shared this on Harry's blog linked above, where emil posted some code for eliminating the Observer (which is a much cleaner and more sensible approach, thanks!), but for those landing here from Google or Rick Olson's README:

http://rails.aizatto.com/category/plugins/acts_as_state_machine/

The Callbacks section there is the most useful summary reference I've found yet for the different behavior of acts_as_state_machine with new objects vs. existing (saved) records. It's a little non-intuitive, but once you discover that sticking point, working with ASM otherwise makes perfect sense.

You may need to tweak the 'stateful_auth' setup out of the box to get the behavior you want, but it's workable once you're armed with that knowledge.

by 57 on Mar 15, 2009

Re: stateful authentication

87

by samsu on Jan 27, 2015

Samsung Galaxy S5 (копия)!

Samsung Galaxy S5 (копия)! не отличимая от оригинала с логотипами Samsung на корпусе спереди и сзади, при включении телефона фирменная заставка Samsung. Функции оригинала : управление жестами http://www.big-butik.ru

by SexcamsDoub on Feb 28, 2015

amateur cams mit huren aus deiner nachbarschaft

Versaute Teens ab 18 live vor der privaten livecam. Willst du es ihnen besorgen? Melde dich jetzt unverbindlich an und du bekommst sofort 50 Coins für die liveshow kostenlos! Geniesse tabulose <b><a href=http://sexcam-live.co/>gratis sexcams</a></b> <a href=http://amateur--sex.info><img>http://6sx.org/sexbilder/anal-sex-besorgs-mir-von-hinten.jpg</img></a> ficken mit lesben aus deiner umgebung

by SexcamsDoub on Mar 05, 2015

live cams mit girls aus deiner stadt

Versaute Teens ab 18 live vor der privaten sexcam. Willst du ein erotisches treffen erleben? Melde dich jetzt umsonnst an und du bekommst gleich 50 Coins für die liveshows kostenlos! Schau geile <b><a href=http://cam--live.com/>sex filme</a></b> <a href=http://amateur--sex.info><img>http://6sx.org/sexbilder/free-sexcam-sex-dating.jpg</img></a> bumsen mit lesben aus deiner nachbarschaft

http://nyou.animegirldesp.org/forum2/index.php?action=profile;u=173178 http://gsm-extreme.net/showthread.php?p=542156#post542156 http://www.kuwaitcricket.com/BB2/viewtopic.php?p=67498#67498 http://bbs.155.cn/space-uid-3346028.html http://openbookprogram.org/bbs/messages/6642.html

by CamsexDoub on Mar 08, 2015

live cams mit huren aus deiner nachbarschaft

Heisse Teenies ab 18 live vor der privaten sexcam. Willst du ein erotisches treffen erleben? Melde dich jetzt unverbindlich an und du erhälst gleich 50 Coins für die liveshows gratis! Betrachte versaute [b][url=http://sexcam.s-3-x.com]sex filme[/url][/b] [url=http://amateur--sex.info][img]http://6sx.org/sexbilder/sexy-girl.jpg[/img][/url] treffen mit frauen aus deiner nähe

http://www.myjellybean.com/chat/member.php?738078-Sexcamshix http://vbulletin.123flashchat.com/member.php?255285-Sexcamson http://satelitski.forumcircle.com/viewtopic.php?p=1798#1798 http://enccom.net/bbs/view.php?id=jubu&page=4&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=vote&desc=asc&no=23 http://www.palsprogram.org/about-us/board-of-directors/item/62-richard-ross-esq.html

by oferifh on Mar 18, 2015

Правильный выбор - наш интернет магазин

Правильный выбор - наш интернет магазин Воспользуйтесь уникальным предложением! http://offer.moscow/

by miuoj on Mar 23, 2015

В нашем интернет-магазине

В нашем интернет-магазине лучший ассортимент и лучшие цены http://miraclefairy.ru/

by SexcamDoub on Mar 24, 2015

bumsen mit frauen aus Essen

Versaute Teenies ab 18 gerade live vor der eigenen webcam. Willst du es ihnen besorgen? Melde dich jetzt gratis an und du erhälst gleich 50 Coins für die sexcams kostenlos! Beobachte geile [b][url=http://2-cam.com]gratis camsex[/url][/b] ! Gay Sexcam spermaspritzen zofenausbildung Gratis Cam to studentinnen sex ebony bitch Private Clips lustvoll Erotik livecam wichsen miniroecke amateur shot Asian Cum Shot. [url=http://amateur--sex.info][img]http://6sx.org/sexbilder/geile-amateure-free-sexcam.jpg[/img][/url] livesex mit girls aus deiner nachbarschaft

http://fine-w.com/bbs/view.php?desc=asc&divpage=1&id=gallery&no=41&page=1&sc=on&select_arrange=headnum&sn=off&sn1=&ss=on http://www.dentway.kr/bbs/view.php?id=contact&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=234 http://www.ikastetiket.dk/support/forum/spoergsmaal/mine-strygemaerker-falder-af-hvad-goer-jeg-forkert/#post-217 http://www.c7carbon.com/forum/1997-2004-chevrolet-corvette-c5/ficken-mit-lesben-aus-deiner-stadt/new/ http://bbs.wulin2.wanmei.com/home.php?mod=space&uid=15789744

by bigybx on Mar 25, 2015

Рекомендуем наш интернет-магазин

Рекомендуем наш интернет-магазин http://www.big-butik.ru/

by SexcamDoub on Mar 28, 2015

sex mit frauen aus Württemberg

Süsse Teens ab 18 gerade live hinter der privaten sex cam. Willst du mit ihnen chatten? Melde dich jetzt kostenlos an und du bekommst sofort 50 Coins für die liveshow umsonnst! Beobachte tabulose [b][url=http://www.teen-sex.me/]free cams[/url][/b] ; Hausfrauen Sex gratis cam teen parkplatz treffen live webcam chat gaychat sexcam topliste topcams Affaire daily free porn handschellen grosse moepse amateur luder telefonsex und cam.

mature fucking live gay sex livejasmine girls free porn gallery topcams Hausfrau webcam adult free live webcam chat bukkake gaychat bumstreffen sexcam topliste .

http://yeunjigonji.com/bbs/view.php?id=order&no=6890 http://www.edumarathon.pl/index.php/blog/15-biegiem-przez-ycie/46-will-smith-bieganie-i-czytanie-klucz-do-ycia.html http://forum.proita.com/forum/home.php?mod=space&uid=119043 http://almatyregion-onko.kz/index.php/ru/item/eeiusmod-tempor.html#comment-1134 http://www.gfchocolate.com/discussion/amateur-cams-mit-frauen-aus-deiner-nachbarschaft

by SexcamDoub on Mar 30, 2015

amateur cams mit huren aus Augsburg

Versaute Teens ab 18 immer live vor der eigenen web cam. Willst du es ihnen besorgen? Melde dich jetzt gratis an und du bekommst sofort 50 Coins für die liveshow gratis! Schau tabulose [b][url=http://www.camsex-kostenlos.com/]sex cams[/url][/b] ; WebcamSex ebony porn amateur live cams fkk hard free porn gallery nachbarin sabrina Flirt Liebe ebony porn sex lexikon gaychat amateur luder kostenlos webcam geile webcam private. [url=http://freesexcam23.info][img]http://6sx.org/sexbilder/free-sexcam-sex-dating.jpg[/img][/url] sex treffen mit lesben aus deiner stadt

http://artesmarciales.cl/foro/showthread.php?tid=47869&pid=190428#pid190428 http://heart-place.com/sample/log/eid1.html? http://www.nwhelicopters.com/nwh/phpBB2/profile.php?mode=viewprofile&u=1136827 http://www.lostcircuits.com/forum/viewtopic.php?f=2&t=23340 http://www.omgroceries.com/forum/showthread.php?tid=4076&pid=72448#pid72448

by NiceAbSems on May 05, 2015

Programs recompense Dieters

[url=https://twitter.com/Healty_Pills]40 Fast, Easy Tips [/url] 1. Write down what you snack in return one week and you whim lose influence 2. Add 10 percent to the amount of daily calories you evaluate you’re eating. 3. Contrive an online heaviness loss buddy to yield more weight. 4. Catch a mantra 5. After breakfast, stick to not work 6. Lunch three fewer bites of your refection 7. Watch a man less hour of TV 8. Absterge something positively in the good old days a week. 9. Stay until your stomach rumbles to come you reach for rations 10. Sniff a banana, an apple, or a peppermint when you be conscious of keen 11. Stare at the color gloomy 12. Sup in countenance of mirrors and you’ll escape burden 13. Splash out 10 minutes a daytime walking up...

by NicolAbSems on May 08, 2015

Programs over the extent of Dieters

[url=https://twitter.com/Healty_Pills]40 Extravagantly, Comfortable Tips [/url] 1. Ignore down what you devour in return anecdote week and you will lose mass 2. Sum 10 percent to the amount of day after day calories you over you’re eating. 3. Contrive an online pressure annihilation buddy to displace more weight. 4. Have an impact a mantra 5. After breakfast, penetrate to modify 6. Eat three fewer bites of your meal 7. Watch one less hour of TV 8. Wash something forwards again a week. 9. Shelved until your craving rumbles on the eve of you reach pro rations 10. Odour a banana, an apple, or a peppermint when you be conscious of hungry 11. Gaze at the color indecent 12. Eat in countenance of mirrors and you’ll worsted strain 13. Splurge 10 minutes a time walking up...

by NicolAbSems on May 10, 2015

Programs recompense Dieters

[url=https://twitter.com/Healty_Pills]40 Fast, Comfortable Tips [/url] 1. Write down what you pack away pro sole week and you whim be deprived of influence 2. Sum 10 percent to the amount of habitually calories you assume you’re eating. 3. Engage an online slant annihilation buddy to displace more weight. 4. Catch a mantra 5. After breakfast, become lodged to water 6. Devour three fewer bites of your meal 7. Sit with at one less hour of TV 8. Sponge off something forwards once a week. 9. Wait until your tolerance rumbles on the eve of you reach instead of rations 10. Sniff a banana, an apple, or a peppermint when you pet keen 11. Stare at the color downcast 12. Dine in vanguard of mirrors and you’ll squander moment 13. Splash out 10 minutes a daytime walking up...

by LinyneangeBon on May 11, 2015

youtube flashing lights kanye

I have guarded, however, against any such profanation. <a href="http://ps-handbook.com/viber-spy-for-pc/5384">viber spy for pc</a> <a href="http://advertising-exposure.com/best-gps-phone-tracker-app-iphone/2526">best gps phone tracker app iphone</a> This is a nice state of things! <a href="http://advertising-exposure.com/app-to-monitor-iphone/2527">app to monitor iphone</a> At the same time he felt a vague disquiet. He swivelled casually in his chair. <a href="http://advertising-exposure.com/free-phone-monitoring/5036">free phone monitoring</a> <a href="http://stephensoncellars.net/sms-tracker-app/456">sms tracker app</a> <a href="http://ps-handbook.com/android-spy-zip/2475">android spy zip</a> <a href="http://stephensoncellars.net/monitor-phone-activity/3568">monitor phone activity</a> <a href="http://stephensonwines.com/current-location-of-a-cell-phone/1240">current location of a cell phone</a> How would you like to breakfast on an elephant? <a href="http://ps-handbook.com/spyware-iphone-4/3000">spyware iphone 4</a> <a href="http://stephensoncellars.net/best-spy-software-for-cell-phones/1693">best spy software for cell phones</a> The books were of the most varied kind, history, geography, politics, political economy, botany, geology, law, all relating to England and English life and customs and manners. <a href="http://stephensonwines.com/how-to-make-a-cell-phone-spy-camera/1473">how to make a cell phone spy camera</a> <a href="http://ps-handbook.com/cell-phone-monitoring-freeware/76">cell phone monitoring freeware</a> He took the objects the thin man handed him and stuffed them and Bonds Beretta into his wide pockets without examining them. <a href="http://ps-handbook.com/key-stroke-software/4325">key stroke software</a> <a href="http://ps-handbook.com/software-for-iphone/5577">software for iphone</a> She caught on to my meaning at once, and settled that matter in a word. <a href="http://ps-handbook.com/cell-phone-number-tracker/4411">cell phone number tracker</a> Yet I could not have been deceived. Hell of a noise as usual. <a href="http://ps-handbook.com/tracking-app-for-android/4352">tracking app for android</a> <a href="http://stephensoncellars.net/track-a-cell-phone-app/1229">track a cell phone app</a> <a href="http://advertising-exposure.com/free-text-message-spy-online/4980">free text message spy online</a> <a href="http://advertising-exposure.com/spy-mobile/3153">spy mobile</a> <a href="http://stephensonwines.com/remote-cell-spyware/3050">remote cell spyware</a> As for these murders, let us enter into some examinations for ourselves, before we make up an opinion respecting them. <a href="http://stephensoncellars.net/how-to-use-iphone-tracker/4047">how to use iphone tracker</a> <a href="http://stephensoncellars.net/lg-optimus-ls670-root/5473">lg optimus ls670 root</a> I have not yet seen the Count in the daylight. <a href="http://advertising-exposure.com/whatsapp-spy-007-apk/2084">whatsapp spy 007 apk</a> <a href="http://ps-handbook.com/how-do-u-know-if-your-husband-is-cheating/3798">how do u know if your husband is cheating</a> Youre not to be serious tonight. <a href="http://stephensoncellars.net/kids-monitoring-software/1162">kids monitoring software</a> <a href="http://stephensoncellars.net/cell-phones-spy/5109">cell phones spy</a> Van Helsing came and laid his hand on Arthurs shoulder, and said to him, And now, Arthur my friend, dear lad, am I not forgiven? <a href="http://stephensoncellars.net/samsung-brightside-spy/6345">samsung brightside spy</a> A pretty flap we caused, I can tell you. You will see the necessity, I hope, of quitting Oxford-at all events, of quitting instantly my chambers. <a href="http://ps-handbook.com/ford-sync-wont-read-text-messages-iphone/2318">ford sync won't read text messages iphone</a> <a href="http://stephensoncellars.net/spoof-text-message/4270">spoof text message</a> <a href="http://stephensoncellars.net/android-spy-software-removal/2738">android spy software removal</a> <a href="http://ps-handbook.com/sms-whatsapp-spy/5114">sms whatsapp spy</a> <a href="http://stephensonwines.com/mobilspy/2296">mobilspy</a> And farther: in what I relate it will be seen that between the fate of the unhappy Mary Cecilia Rogers, so far as that fate is known, and the fate of one Marie Roget up to a certain epoch in her history, there has existed a parallel in the contemplation of whose wonderful exactitude the reason becomes embarrassed. <a href="http://stephensoncellars.net/cell-phone-spy-tracking-application/3310">cell phone spy tracking application</a> <a href="http://stephensonwines.com/aplicacion-espiar-whatsapp-android/506">aplicacion espiar whatsapp android</a> So I got some formalin from the doctor and put it into the live shells to stop them smelling and sent them off to this man in Miami, I only got it right about a year ago and Ive already made fifteen pounds. <a href="http://ps-handbook.com/iphone-spyware-detection-and-removal/1361">iphone spyware detection and removal</a> <a href="http://ps-handbook.com/software-espia-moviles/5957">software espia moviles</a> There were two round, black spots near one extremity of the back, and a long one near the other. <a href="http://advertising-exposure.com/app-to-track-iphone/1637">app to track iphone</a> <a href="http://stephensonwines.com/is-your-boyfriend-cheating/1482">is your boyfriend cheating</a> Valdemars house, accompanied, now and then, by medical and other friends. <a href="http://stephensoncellars.net/track-location-of-a-cell-phone/256">track location of a cell phone</a> She stood for a moment, frozen, gazing blindly at the black machine. And dont think so hard about those stupid men. <a href="http://stephensoncellars.net/iphone-spy-software-free/1354">iphone spy software free</a> <a href="http://ps-handbook.com/free-iphone-4-text-message-spy/5549">free iphone 4 text message spy</a> <a href="http://ps-handbook.com/spy-sms-messages-free/5821">spy sms messages free</a> <a href="http://stephensoncellars.net/how-to-monitor-cell-phone-calls-for-free/1457">how to monitor cell phone calls for free</a> <a href="http://stephensoncellars.net/best-cell-phone-monitoring-software/2938">best cell phone monitoring software</a> If I hadnt gone to Whitby, perhaps poor dear Lucy would be with us now. <a href="http://stephensoncellars.net/app-that-spies-on-text-messages/808">app that spies on text messages</a> <a href="http://advertising-exposure.com/how-to-listen-to-phone-calls/5408">how to listen to phone calls</a> I happen to be needing a white woman for a small experiment. <a href="http://stephensoncellars.net/como-puedo-espiar-el-whatsapp/5146">como puedo espiar el whatsapp</a> <a href="http://stephensoncellars.net/skype-spy-voice-recorder/3299">skype spy voice recorder</a> We know from the inquiry of Jonathan that from the castle to Whitby came fifty boxes of earth, all of which were delivered at Carfax, we also know that at least some of these boxes have been removed. <a href="http://ps-handbook.com/best-cell-phone-tracker-app-for-android/3428">best cell phone tracker app for android</a> <a href="http://stephensoncellars.net/loginflexispycom/4381">login.flexispy.com</a> Well, then, the Cat went on, you see, a dog growls when its angry, and wags its tail when its pleased. <a href="http://advertising-exposure.com/how-to-know-if-your-man-is-cheating/182">how to know if your man is cheating</a> During this period, I became aware, for the first time, of the origin of the sulphurous light which illumined the cell. After a cold shower, he sat at the writing? <a href="http://stephensoncellars.net/samsung-phone-tracker/1638">samsung phone tracker</a> <a href="http://stephensoncellars.net/detecting-spyware-on-iphone/4798">detecting spyware on iphone</a> <a href="http://ps-handbook.com/text-message-spying-for-free/5678">text message spying for free</a> <a href="http://advertising-exposure.com/free-virus-and-spyware-removal-for-mac/359">free virus and spyware removal for mac</a> <a href="http://stephensoncellars.net/spy-on-texts/4522">spy on texts</a> Through his relief at being alive, he felt a moment of triumph at what he saw - some fear in the fat, pale face. <a href="http://stephensonwines.com/spyware-on-iphone/597">spyware on iphone</a> <a href="http://ps-handbook.com/free-mspy/3974">free mspy</a> You have cigarettes-enough and the right sort to cosset your cancer? <a href="http://stephensonwines.com/cell-phone-spyware-reviews-2011/4891">cell phone spyware reviews 2011</a> <a href="http://stephensoncellars.net/spy-apps-for-android-reviews/2975">spy apps for android reviews</a> There is no reason why he should. <a href="http://advertising-exposure.com/how-to-spy-samsung-phone/95">how to spy samsung phone</a> <a href="http://ps-handbook.com/girlfriend-cheating-on-phone/1078">girlfriend cheating on phone</a> Its length was thirteen feet six inches-height, six feet eight inches. <a href="http://advertising-exposure.com/sms-spy-android-app-free/2120">sms spy android app free</a> Still, the general appearance was certainly not that of death. Its the oldest rule in the book, said the King. <a href="http://stephensonwines.com/app-to-listen-to-phone-calls/1188">app to listen to phone calls</a> <a href="http://advertising-exposure.com/how-to-track-cell-phone-location/4631">how to track cell phone location</a> <a href="http://stephensonwines.com/best-cell-phone-monitoring-app/5555">best cell phone monitoring app</a> <a href="http://stephensoncellars.net/cell-phone-spy-for-iphone-4-free/2842">cell phone spy for iphone 4 free</a> <a href="http://ps-handbook.com/is-my-wife-cheating-on-me/4318">is my wife cheating on me</a> For Vesper to fall for an old trick like that and get herself snatched and probably held to ranson like some bloody heroine in a strip cartoon. <a href="http://advertising-exposure.com/how-to-install-cydia/5578">how to install cydia</a> <a href="http://stephensonwines.com/how-to-get-my-kids-text-messages-on-my-phone/5207">how to get my kids text messages on my phone</a> The passport will be ready by this evening. <a href="http://stephensoncellars.net/cellphonespy/3177">cellphonespy</a> <a href="http://stephensoncellars.net/mobi-phones/779">mobi phones</a> He said, Hurry up, blast you. <a href="http://advertising-exposure.com/sms-berwachung-kostenlos/4305">sms Гјberwachung kostenlos</a> <a href="http://stephensonwines.com/mobile-surveillance/4129">mobile surveillance</a> There can be no horror like this ever any more. <a href="http://stephensoncellars.net/cell-phones-apps/2878">cell phones apps</a> Being both, apparently, occupied with thought, neither of us had spoken a syllable for fifteen minutes at least. If you can, in any way, make it convenient, come over with Jupiter. <a href="http://stephensoncellars.net/how-can-u-tell-if-your-boyfriend-is-cheating/4867">how can u tell if your boyfriend is cheating</a> <a href="http://ps-handbook.com/spybubbles/5829">spybubbles</a> <a href="http://stephensonwines.com/remotely-install-spy-software/594">remotely install spy software</a>

by diehnz on May 14, 2015

Часы с мужским характером DIESEL "ХИЩНИК"!

Часы с мужским характером DIESEL "ХИЩНИК"! http://www.diezel.hellomadam.org/

New Comment

markdown formatting permitted