diff options
28 files changed, 461 insertions, 13 deletions
diff --git a/app/assets/javascripts/ajax.js b/app/assets/javascripts/ajax.js new file mode 100644 index 0000000..31578dd --- /dev/null +++ b/app/assets/javascripts/ajax.js @@ -0,0 +1,15 @@ +function populate() { + //populate optionArray + //make a form element + var e = document.getElementById("tournament_id"); + var gameType = e.options[e.selectedIndex].text; + if (gameType != "Select a Game Type") { + alert(gameType + " was Selected!"); + //populate optionArray via AJAX + //select * from tournament_settings where gametype = GameType + for(var option in optionArray){ + //identify the number of + ; + } + }; +}
\ No newline at end of file diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 3192ec8..35fe66b 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -11,3 +11,13 @@ *= require_self *= require_tree . */ + +#query{ + background-color: #888; + border: 2px solid #ED9C28; + border-radius: 5px; + color: #FFF; + font-weight: bold; + height: 30px; + +} diff --git a/app/assets/stylesheets/custom.css.scss b/app/assets/stylesheets/custom.css.scss new file mode 100644 index 0000000..cbd46a7 --- /dev/null +++ b/app/assets/stylesheets/custom.css.scss @@ -0,0 +1 @@ +@import "bootstrap"; diff --git a/app/assets/stylesheets/scaffolds.css.scss b/app/assets/stylesheets/scaffolds.css.scss index 6ec6a8f..2b8734e 100644 --- a/app/assets/stylesheets/scaffolds.css.scss +++ b/app/assets/stylesheets/scaffolds.css.scss @@ -1,11 +1,15 @@ body { - background-color: #fff; + background-color: #EEEEEE; color: #333; font-family: verdana, arial, helvetica, sans-serif; font-size: 13px; line-height: 18px; } +h1, h2, h3, h4, h5{ + color: #0f0f0f; +} + p, ol, ul, td { font-family: verdana, arial, helvetica, sans-serif; font-size: 13px; @@ -67,3 +71,19 @@ div { list-style: square; } } + +hr { + -moz-border-bottom-colors: none; + -moz-border-image: none; + -moz-border-left-colors: none; + -moz-border-right-colors: none; + -moz-border-top-colors: none; + border-color: #999 -moz-use-text-color #FFFFFF; + border-style: solid none; + border-width: 1px 0; + margin: 18px 0; +} + +#footer{ + text-align: center; +} diff --git a/app/assets/stylesheets/static.css.scss b/app/assets/stylesheets/static.css.scss index 5a803c8..d73e77d 100644 --- a/app/assets/stylesheets/static.css.scss +++ b/app/assets/stylesheets/static.css.scss @@ -1,3 +1,12 @@ // Place all the styles related to the static controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ + +.jumbotron { + background-color: #FFF; + + p { + line-height: 1.5em; + } + +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d83690e..7487f87 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,4 +2,7 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception + + #include sessionhelper for the session controller and view + include SessionsHelper end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 16d11b5..68cb949 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,2 +1,22 @@ class SessionsController < ApplicationController + + def new + end + + # find the user and create a new session + def create + user = User.find_by(email: params[:session][:email].downcase) + if user && user.authenticate(params[:session][:password]) + sign_in user + redirect_to root_path + else + render 'new' + end + end + + def destroy + sign_out + redirect_to root_path + end + end diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index c6df11e..6fc9490 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -1,2 +1,4 @@ class StaticController < ApplicationController + def homepage + end end diff --git a/app/controllers/tournaments_controller.rb b/app/controllers/tournaments_controller.rb index 720305f..27ba020 100644 --- a/app/controllers/tournaments_controller.rb +++ b/app/controllers/tournaments_controller.rb @@ -14,6 +14,7 @@ class TournamentsController < ApplicationController # GET /tournaments/new def new + @game_names = Game.all.collect @tournament = Tournament.new end @@ -21,6 +22,12 @@ class TournamentsController < ApplicationController def edit end + def selected + render :update do |page| + page.replace_html 'ajax-form', :partial => 'selected' + end + end + # POST /tournaments # POST /tournaments.json def create diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b18efed..f540dde 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -10,6 +10,7 @@ class UsersController < ApplicationController # GET /users/1 # GET /users/1.json def show + @user = User.find(param[:id]) end # GET /users/new @@ -28,7 +29,8 @@ class UsersController < ApplicationController respond_to do |format| if @user.save - format.html { redirect_to @user, notice: 'User was successfully created.' } + sign_in @user + format.html { redirect_to root_path, notice: 'User was successfully created.' } format.json { render action: 'show', status: :created, location: @user } else format.html { render action: 'new' } @@ -69,6 +71,6 @@ class UsersController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def user_params - params.require(:user).permit(:name, :email, :user_name) + params.require(:user).permit(:name, :email, :user_name, :password, :password_confirmation) end end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index 309f8b2..046ca6f 100644 --- a/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb @@ -1,2 +1,73 @@ module SessionsHelper + + def sign_in(user) + #create a new remember token + remember_token = User.new_remember_token + #place token inside of the browser + cookies.permanent[:remember_token] = remember_token + #save the hashed token to the database + user.update_attribute(:remember_token, + User.hash(remember_token)) + #set the current user to be the given user + self.current_user = user + end + +# The curret_user=(user) is the conversion of self.current_user = user + def current_user=(user) + @current_user = user + end + +# sets the @current_user instance virable to the user corresponding +# to the remember token, but only if @current_user is undefined +# since the remember token is hashed, we need to hash the cookie +# to find match the remember token + def current_user + remember_token = User.hash(cookies[:remember_token]) + @current_user ||= User.find_by(remember_token: remember_token) + end + + # checks if someone is currently signed in + def signed_in? + !current_user.nil? + end + + def sign_out + current_user.update_attribute(:remember_token, User.hash(User.new_remember_token)) + cookies.delete(:remember_token) + self.current_user = nil + end + +=begin + +This is for anyone that cares about how long a user is signed +in: + +Currently I have a user to be signed in forever unless they +log out (cookies.permanent....). + +If you want to change that, change line 7 to this: + +cookies[:remember_token] = { value: remember_token, + expires: 20.years.from_now.utc } + +which will expire the cookie in 20 years from its date of +creation. + +Oddly enough, this line above is equivalent to the: + +cookies.permanent + +This is just a short cut for this line since most people +create permanent cookies these days. + +Other times are: + +10.weeks.from_now + +5.days.ago + +etc... + +=end + end diff --git a/app/models/game.rb b/app/models/game.rb index a181c26..b3b6977 100644 --- a/app/models/game.rb +++ b/app/models/game.rb @@ -1,2 +1,3 @@ class Game < ActiveRecord::Base + has_many :game_attributes end diff --git a/app/models/user.rb b/app/models/user.rb index 4a57cf0..a4fafa0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,2 +1,121 @@ class User < ActiveRecord::Base + + before_save { self.email = email.downcase } + before_save { self.user_name = user_name.downcase } + + ## + # Rails looks for the create_remember_token and runs the method + # before anything else. + # + # This method cannot be called by a user since it is denoted + # as private. + before_create :create_remember_token + + ## + # VAILD_EMAIL is the regex used to valid a user given email. + # + # A break down of the regex is listed below. + # + # / -------------> Start of the regex + # \A ------------> match start of a string + # [\w+\-.]+ -----> at least one owrd character, plus, hyphen, + # or dot + # @ -------------> literal ampersand + # [a-z\d\-.]+ ---> at least one letter, digit, hyphen, or dot + # (?:\.[a-z]+) --> ensures that the error of example@foo..com + # does not occur + # \z ------------> match end of a string + # / -------------> end of the regex + # i -------------> case insensative + VALID_EMAIL_REG = /\A[\w+\-.]+@[a-z\d\-.]+(?:\.[a-z]+)\z/i + + ## + # VALID_USER_NAME checks to make sure a user's user_name + # is in the proper format. + VALID_USER_NAME_REG = /[a-zA-Z0-9\-]/ + + ## + # The following lines put a user accout through a series of + # validations in order to make sure all of their information + # is in the proper format. + # + # validates :symbol_to_be_valided + # + # - presence: determines whether or not a symbol is filled or not + # - length: ensures there is a length limit on the symbol + # - format: checks the format of given information to ensure + # validity + validates(:name, presence: true, length: { maximum: 50 }) + validates(:email, presence: true, format: {with: + VALID_EMAIL_REG}, + uniqueness: { case_sensitive: false }) + validates(:user_name, presence: true, length:{maximum: 50}, + format: {with: VALID_USER_NAME_REG }, + uniqueness: {case_sensitive: false }) + + ## + # Instead of adding password and password_confirmation + # attributes, requiring the presence of a password, + # requirin that pw and pw_com match, and add an authenticate + # method to compare an encrypted password to the + # password_digest to authenticate users, I can just add + # has_secure_password which does all of this for me. + has_secure_password + + validates :password, length: { minimum: 6 } + + ## + # Create a random remember token for the user. This will be + # changed every time the user creates a new session. + # + # By changing the cookie every new session, any hijacked sessions + # (where the attacker steals a cookie to sign in as a certain + # user) will expire the next time the user signs back in. + # + # The random string is of length 16 composed of A-Z, a-z, 0-9 + # This is the browser's cookie value. + def User.new_remember_token + SecureRandom.urlsafe_base64 + end + + ## + # Encrypt the remember token. + # This is the encrypted version of the cookie stored on + # the database. + # + # The reasoning for storing a hashed token is so that even if + # the database is compromised, the atacker won't be able to use + # the remember tokens to sign in. + def User.hash(token) + Digest::SHA1.hexdigest(token.to_s) + end + + ## + # SHA-1 (Secure Hash Algorithm) is a US engineered hash + # function that produces a 20 byte hash value which typically + # forms a hexadecimal number 40 digits long. + # The reason I am not using the Bcrypt algorithm is because + # SHA-1 is much faster and I will be calling this on + # every page a user accesses. + # + # https://en.wikipedia.org/wiki/SHA-1 + + + # Everything under private is hidden so you cannot call. + private + + ## + # Create_remember_token in order to ensure a user always has + # a remember token. + def create_remember_token + self.remember_token = User.hash(User.new_remember_token) + end + + ## + # In order to ensure that someone did not accidently submit + # two accounts rapidly (which would throw off the validates + # for user_name and email), I added an index to the Users + # email and user_name in the database to ensure uniqueness + # This also gives and index to the user_name and email + # so finding a user SHOULD be easier for the database. end diff --git a/app/views/games/index.html.erb b/app/views/games/index.html.erb index ccd0f63..2c178f5 100644 --- a/app/views/games/index.html.erb +++ b/app/views/games/index.html.erb @@ -1,6 +1,6 @@ <h1>Listing games</h1> -<table> +<table class="table table-hover"> <thead> <tr> <th>Name</th> @@ -32,4 +32,4 @@ <br> -<%= link_to 'New Game', new_game_path %> +<%= link_to 'New Game', new_game_path, {:class => "btn btn-warning"} %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index cefd1be..b36c0c5 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -5,10 +5,38 @@ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> + <%= yield :head %> </head> <body> +<div role="navigation" class="navbar navbar-inverse"> +<header> + <div class="navbar-brand no-dec"> + <%= link_to('Leaguer', '/', nil) %> + </div> + <div> + <%= form_tag("/search", method: "get", :class => "navbar-form navbar-right") do %> + <%= text_field_tag(:query, nil, :placeholder => "Search") %> + <%= submit_tag("Go", {:class => "btn btn-warning"}) %> + <% end %> + </div> + <% if signed_in? %> + <li> <%= current_user.user_name.upcase %> </li> + <% end %> + <li> + <%= if signed_in? do %> + <%= link_to "Sign out", signout_path, method: "delete" %> + <% end; end %> + </li> +</header> + </div> +<div class="container"> <%= yield %> - +</div> +<hr> +<footer id="footer"> +<p> Tomer Kimia Andrew Murrell Luke Shumaker Nathaniel Foy Davis Webb Guntas Grewal </p> +<p> The Leaguer System © <%= Time.now.year %> </p> </footer> + <%= debug(params) if Rails.env.development? %> </body> </html> diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 0000000..f942cf6 --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,18 @@ +<h1>Sign in</h1> + +<div class="row"> + <div class="span6 offset3"> + <%= form_for(:session, url: sessions_path) do |f| %> + + <%= f.label :email %> + <%= f.text_field :email %> + + <%= f.label :password %> + <%= f.password_field :password %> + + <%= f.submit "Sign in", class: "btn btn-large btn-primary" %> + <% end %> + + <p>New user? <%= link_to "Sign up now!", signup_path %></p> + </div> +</div> diff --git a/app/views/static/homepage.html.erb b/app/views/static/homepage.html.erb new file mode 100644 index 0000000..4d52e5b --- /dev/null +++ b/app/views/static/homepage.html.erb @@ -0,0 +1,10 @@ +<div role="main" class="container theme-showcase"> + + <!-- Main jumbotron for a primary marketing message or call to action --> + <div class="jumbotron"> + <h1>Welcome to Leaguer</h1> + <p>This is a tournment management system designed to be used for any team sport. Our peer review system ensures that the best players move on to the next round! Try creating a new tournament and having people sign up for it. </p> + <p id="jumbo-buttons"><%= link_to 'Log In / Sign Up', "signup", :class => "btn btn-warning btn-lg", :role => "button" %> <%= link_to 'See Ongoing Tournaments', tournaments_path, :class => "btn btn-warning btn-lg", :role => "button" %> </p> + </div> + + </div> diff --git a/app/views/tournaments/_selected.html.erb b/app/views/tournaments/_selected.html.erb new file mode 100644 index 0000000..302283d --- /dev/null +++ b/app/views/tournaments/_selected.html.erb @@ -0,0 +1,25 @@ +<form accept-charset="UTF-8" action="/users" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="6WQoPLFISlDYCsi4LhAgT0hgrht19yydD3w5TlKfb7I=" /></div> + <p> + <label for="GameType">Game</label><br> + <input id="GameType" name="League of Legends" type="text" /> + </p> + <p> + <label for="players_per_team">Number of Players</label><br> + <input id="players_per_team" name="5" type="text" /> + </p> + <p> + <label for="teams_per_match">Teams per Match</label><br> + <input id="teams_per_match" name="2" type="text" /> + </p> + <p> + <label for="set_rounds">Set Number of Rounds?</label><br> + <input id="set_rounds" name="1" type="text" /> + </p> + <p> + <label for="randomized_teams">Randomized Teams?</label><br> + <input id="randomized_teams" name="0" type="text" /> + </p> + <p> + <input name="create" type="submit" value="Create Tournament" /> + </p> +</form>
\ No newline at end of file diff --git a/app/views/tournaments/index.html.erb b/app/views/tournaments/index.html.erb index ad2b7cf..6006cad 100644 --- a/app/views/tournaments/index.html.erb +++ b/app/views/tournaments/index.html.erb @@ -3,7 +3,7 @@ <table> <thead> <tr> - <th>Game</th> + <th></th> <th></th> <th></th> <th></th> @@ -24,4 +24,4 @@ <br> -<%= link_to 'New Tournament', new_tournament_path %> +<%= link_to 'New Tournament', new_tournament_path, :class => "btn btn-warning btn-lg" %> diff --git a/app/views/tournaments/new.html.erb b/app/views/tournaments/new.html.erb index 2a60539..f1dec90 100644 --- a/app/views/tournaments/new.html.erb +++ b/app/views/tournaments/new.html.erb @@ -1,5 +1,11 @@ <h1>New tournament</h1> -<%= render 'form' %> +<%= select_tag 'tournament_id', options_for_select(["Select a Game Type"] + Game.all.collect {|game| game.name}), :onchange => 'populate()' %> + +<br /> +<div id='ajax-form'> + <% render :partial => "selected" %> +</div> +<br /><br /> <%= link_to 'Back', tournaments_path %> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index efc0404..2a745cc 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -1,5 +1,60 @@ -<h1>New user</h1> +<h1> Sign Up </h1> -<%= render 'form' %> +<% if false %> +<%= form_for :user do |f| %> + <p> + <%= f.label :name %><br> + <%= f.text_field :name %> + </p> + <p> + <%= f.label :email %><br> + <%= f.text_field :email %> + </p> + <p> + <%= f.label :user_name %><br> + <%= f.text_field :user_name %> + </p> + <p> + <%= f.label :password %><br> + <%= f.text_field :password %> + </p> + <p> + <%= f.label :password_confirm %><br> + <%= f.text_field :password_confirmation %> + </p> + <p> + <%= f.submit %> + </p> +<% end %> + + +<% end %> + +<form accept-charset="UTF-8" action="/users" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="6WQoPLFISlDYCsi4LhAgT0hgrht19yydD3w5TlKfb7I=" /></div> + <p> + <label for="user_name">Name</label><br> + <input id="user_name" name="user[name]" type="text" /> + </p> + <p> + <label for="user_email">Email</label><br> + <input id="user_email" name="user[email]" type="text" /> + </p> + <p> + <label for="user_user_name">User name</label><br> + <input id="user_user_name" name="user[user_name]" type="text" /> + </p> + <p> + <label for="user_password">Password</label><br> + <input id="user_password" name="user[password]" type="text" /> + </p> + <p> + <label for="user_password_confirm">Password confirm</label><br> + <input id="user_password_confirmation" name="user[password_confirmation]" type="text" /> + </p> + <p> + <input name="commit" type="submit" value="Save User" /> + </p> +</form> + +<%= link_to 'Already Have an Account? Log in', "signin", :class => "btn btn-warning btn-lg" %> -<%= link_to 'Back', users_path %> diff --git a/app/views/users/show.json.jbuilder b/app/views/users/show.json.jbuilder index 4919af3..1262e80 100644 --- a/app/views/users/show.json.jbuilder +++ b/app/views/users/show.json.jbuilder @@ -1 +1 @@ -json.extract! @user, :id, :name, :email, :user_name, :created_at, :updated_at +json.extract! @user, :id, :name, :pw_hash, :created_at, :updated_at diff --git a/config/routes.rb b/config/routes.rb index 3bad42d..bc995e3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,12 @@ Leaguer::Application.routes.draw do + + #creates sessions as a resource but limits it to these actions + resources :sessions, only: [:new, :create, :destroy] + + match 'signup', to: 'users#new', via: 'get' + match 'signin', to: 'sessions#new', via: 'get' + match 'signout', to: 'sessions#destroy', via: 'delete' + resources :users resources :games @@ -15,6 +23,8 @@ Leaguer::Application.routes.draw do resources :servers + root to: 'static#homepage' + # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". diff --git a/db/migrate/20140304043652_add_index_to_users_email.rb b/db/migrate/20140304043652_add_index_to_users_email.rb index b5f8a1a..934d23b 100644 --- a/db/migrate/20140304043652_add_index_to_users_email.rb +++ b/db/migrate/20140304043652_add_index_to_users_email.rb @@ -1,4 +1,8 @@ class AddIndexToUsersEmail < ActiveRecord::Migration + +# adding unique: true ensures there can be no duplicates def change + add_index :users, :email, unique: true end + end diff --git a/db/migrate/20140304043654_add_index_to_users_user_name.rb b/db/migrate/20140304043654_add_index_to_users_user_name.rb index 724cca5..22ca8c3 100644 --- a/db/migrate/20140304043654_add_index_to_users_user_name.rb +++ b/db/migrate/20140304043654_add_index_to_users_user_name.rb @@ -1,4 +1,7 @@ class AddIndexToUsersUserName < ActiveRecord::Migration + +# ensures that the username is unique def change + add_index :users, :user_name, unique: true end end diff --git a/db/migrate/20140304043656_add_password_digest_to_users.rb b/db/migrate/20140304043656_add_password_digest_to_users.rb index 0070da7..7ad1f62 100644 --- a/db/migrate/20140304043656_add_password_digest_to_users.rb +++ b/db/migrate/20140304043656_add_password_digest_to_users.rb @@ -1,4 +1,5 @@ class AddPasswordDigestToUsers < ActiveRecord::Migration def change + add_column :users, :password_digest, :string end end diff --git a/db/migrate/20140304043658_add_remember_token_to_users.rb b/db/migrate/20140304043658_add_remember_token_to_users.rb index 74c254f..6d84942 100644 --- a/db/migrate/20140304043658_add_remember_token_to_users.rb +++ b/db/migrate/20140304043658_add_remember_token_to_users.rb @@ -1,4 +1,8 @@ class AddRememberTokenToUsers < ActiveRecord::Migration + #add a remember me token to the database + #this keeps a user signed in until they sign out def change + add_column :users, :remember_token, :string + add_index :users, :remember_token end end diff --git a/db/seeds.rb b/db/seeds.rb index 4edb1e8..ab130a8 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,3 +5,7 @@ # # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) # Mayor.create(name: 'Emanuel', city: cities.first) +# +Game.create(name: "League of Legends", players_per_team: 5, teams_per_match: 2, set_rounds: 1, randomized_teams: 0) + + |