Giter VIP home page Giter VIP logo

sinatra-secure-password-lab's Introduction

Secure Password Lab

Objectives

  1. Use bcrypt, a gem that works to encrypt passwords.
  2. Use Active Record's has_secure_password method.
  3. Sign up and Sign in a user with a secure, encrypted password.

The Challenge

You're back at Flatiron Bank, where the executive staff has been alerted that the developers who built the authentication system forgot to use password encryption. That means that all of the bank's user passwords are easily available to hackers and bad actors. The CTO has called you in to implement secure passwords in the bank's system.

Use the bcrypt gem, to implement this strategy.

Starter Code

We've got a basic Sinatra MVC application for our bank. In our application_controller we have two helper methods defined; logged_in? returns true or false based on the presence of a session[:user_id] and current_user returns the instance of the logged in user, based on the session[:user_id].

We have five actions defined:

  • get "/" do renders an index.erb file with links to signup or login.
  • get '/signup' renders a form to create a new user. The form includes fields for username and password.
  • get '/login' renders a form for logging in.
  • get '/account' renders an account.erb page, which should be displayed once a user successfully logs in.
  • get '/failure' renders a failure.erb page. This will be accessed if there is an error logging in or signing up.
  • get '/logout' clears the session data and redirects to the home page.

The Helper Methods at the bottom of the controller are part of Sinatra's configurations for helper methods. These are methods that allow us to add logic to our views. Views automatically have access to all helper methods thanks to Sinatra.

We've also stubbed out a user model in app/models/user.rb which inherits from ActiveRecord::Base.

Fork and clone this repository and run bundle install to get started. Preview your work by running shotgun and navigating to http://localhost:9393 in your browser.

To Do

Get the tests to pass. You'll need to use 'bcrypt' to salt your password and make sure that it is encrypted.

You'll also need to create a users table. A user should have a username and password.

Bonus

Add a migration that gives the user model a balance (should start for any user at $0), and add functionality on the account page to make deposits and withdrawals. A user should never be able to withdraw more money than they have in their account.

sinatra-secure-password-lab's People

Contributors

annjohn avatar brennenawana avatar danielseehausen avatar dfenjves avatar drakeltheryuujin avatar ihollander avatar jakebrady5 avatar maxwellbenton avatar pletcher avatar sophiedebenedetto avatar tddycks avatar victhevenot avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sinatra-secure-password-lab's Issues

To Do

"To Do
Get the tests to pass. You'll need to use 'bcrypt' to salt your password and make sure that it is encrypted. You'll also need to create a users table. A user should have a username and password."

Above is the ReadMe To Do. The user according to the test should have username and password_digest not password.

Fix solution

Update solution code to use session[:user_id] and memoization.

lab is working but is not passing one test

  1. App Logging In displays the user's account page if username and password is given
    Failure/Error: expect(page.current_path).to eq('/account')

    expected: "/account"
    got: "/login"

    (compared using ==)

    ./spec/secure_password_spec.rb:73:in `block (3 levels) in <top (required)>'

wrong controller

the starter code on this lab comes with an '/success' controller that redirects to success.erb when it's supposed to be a '/account' controller going to account.erb.

My guess is that it was simply copied from the previous lab (sinatra-password-security-v-000) and wasn't updated accordingly.

Lab Is Missing user.authenticate check

The post '/login' route, doesn't require a user.authenticate.

It should have 'user.authenticate(params[:password])' in there since that seems to be an important part of the lecture preceding this, password security. Currently, that route's spec only checks to see if the inputs aren't empty but doesn't ask to see if the password has been authenticated.

False Positive on Spec #4

Tests can pass where the User can access the Login page from signup without a valid password if they leave the field blank.

if (@user.username != "" ? true : false ) && (@user.password != "" ? true : false ) @user.save redirect to '/login' end redirect to '/failure'

Will pass the tests even if the field is blank because it will evaluate as true.

ActiveRecord version to be updated in the gemfile

Bundler loads version 5.2 which raises the following error:

config.ru:3:in block in

': undefined methodneeds_migration?' for ActiveRecord::Migrator:Class (NoMethodError)

Update gemfile (as follows) to resolve the error-
gem "activerecord", '<= 5.1'

Need to move pry up in gemfile

When running learn and shotgun, you can't hit pry unless you move it up in the gemfile as shown:

gem 'shotgun'
gem 'pry'

group :development do
  gem 'sqlite3'
  gem 'rspec'
  gem 'tux'
end

Thank you.

One of the tests for the "/login" route can return a false positive

Hi. Currently, one of the tests for the "/login" route looks like this:

describe "Logging In" do
...
it "displays the failure page if no password is given" do
      visit '/login'
      fill_in "username", with: "sophie"
      fill_in "password", with: ""
      click_button "Log In"
      expect(page.body).to include('Flatiron Bank Error')
      expect(page.current_path).to eq("/failure")
      expect{page.get_rack_session_key("user_id")}.to raise_error(KeyError)
    end
...
end

As I discovered, though, this test passes even if I don't call the authenticate method on the password. In other words, this code passes the above test (as well as all of the other tests):

post "/login" do
    user = User.find_by(username: params[:username])
    
    if user
      session[:user_id] = user.id
      redirect "/account"
    else
      redirect "/failure"
    end
  end

The reason for this, is that in the test above, the User with the username of "sophie" is never saved into the "users" database. This means that when params[:username] is set to "sophie", user = User.find_by(username: params[:username]) returns nil; thus, the "/login" route redirects to the "/failure" route because of a nil user instead of a blank password. This then leads to the test passing with a false positive.

There are at least two solutions to this problem:

  1. Change fill_in "username", with: "sophie" to fill_in "username", with: "avi" (since one of the earlier tests saved "avi" into the "users" database)

or

  1. Add this line of code to the start of the test (before visit '/login'): @user = User.create(:username => "sophie", :password => "random_password")

I tried out both solutions, and the test failed correctly each time.

I know that this is probably an edge case, but thanks for looking into it!

---Sdcrouse

solution to this lab doesnt save user info

In the solution to this lab, it passes the test but doesn't actually save the users info so you can login with the new sign up info that was created.

Code Snippet of solution provided:

  post "/signup" do
    if params[:username] == "" || params[:password] == ""
      redirect '/failure'
    else
      User.create(username: params[:username], password: params[:password])
      redirect '/login'
    end

  end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.