-
Notifications
You must be signed in to change notification settings - Fork 40
Rupert bitly #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Rupert bitly #33
Changes from all commits
17411e4
68ee32e
8725044
5afed00
a6fe70d
cd56b61
5d0649b
770b884
91eaf7c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| continue | ||
| next | ||
| @url | ||
| next | ||
| @url | ||
| continue | ||
| @url.errors.first.essage | ||
| @url.errors.full_messages | ||
| @url.errors.each { |error| puts error.full_messages } | ||
| @url.errors.each do |error| | ||
| @url.errors | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,28 @@ | ||
| class UrlsController < ApplicationController | ||
| include UrlsHelper | ||
|
|
||
| def index | ||
| @urls = Url.all | ||
| @url = Url.new(address: "https://") | ||
| end | ||
|
|
||
| def create | ||
| @url = Url.new(url_params) | ||
| if @url.save | ||
| redirect_to root_path | ||
| else | ||
| @urls = Url.all | ||
| render 'index' | ||
| end | ||
| end | ||
|
|
||
| def show | ||
| @url = Url.find_by(slug: params[:slug]) | ||
| if @url | ||
| Url.increment_counter(:click_count, @url.id) | ||
| redirect_to @url.address | ||
| else | ||
| redirect_to root_path | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,5 @@ | ||
| module UrlsHelper | ||
| def url_params | ||
| params.require(:url).permit(:address) | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| class Url < ActiveRecord::Base | ||
| require 'net/http' | ||
| require 'securerandom' | ||
|
|
||
| before_save :generate_shortened_url | ||
|
|
||
| validates :address, presence: true | ||
| validates :address, format: { with: /\Ahttps?:\/\/.*/, message: "must begin with 'http://' or 'https://'" } | ||
| validates :address, uniqueness: true | ||
| validate :url_is_correct_format, :url_responds_to_http_request | ||
|
|
||
| def url_is_correct_format | ||
| unless address =~ /\A#{URI.regexp}\z/ | ||
| errors.add(:address, "is not a valid url format") | ||
| end | ||
| end | ||
|
|
||
| def url_responds_to_http_request | ||
| url = URI.parse(address) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could a bad actor use this logic to DOS another site possibly?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jaybobo Yeah, they could. Are there any specific safe practices I could look up? Most of my generic searches just send me to security companies. |
||
| begin | ||
| response = Net::HTTP.get_response(url) | ||
|
|
||
| if response.code == "404" | ||
| errors.add(:address, "is not accessible via HTTP(S)") | ||
| end | ||
| rescue | ||
| errors.add(:address, "is not accessible via HTTP(S)") | ||
| end | ||
| end | ||
|
|
||
| def generate_shortened_url | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In most cases, we'd use a random string generator with the length we desire instead of mutating the original address. It's cleaner, easier & more secure.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! |
||
| #This ensures that if a slug exists then a new one is not created | ||
| temp_slug = self.slug || SecureRandom.base64(4) | ||
| #Creates a slug if one doesn't exist | ||
| while !self.slug && Url.find_by(slug: temp_slug) | ||
| temp_slug = SecureRandom.base64(4) | ||
| end | ||
| self.slug = temp_slug | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <p>Index Page</p> | ||
|
|
||
| <% if @url.errors %> | ||
| <ul> | ||
| <% @url.errors.each do |attr, error| %> | ||
| <li><%= error %></li> | ||
| <% end %> | ||
| </ul> | ||
| <% end %> | ||
|
|
||
| <% @urls.each do |url| %> | ||
| <p><%= url.address %> - <%= "#{request.base_url}/#{url.slug}" %> - Clicks: <%= url.click_count %></p> | ||
| <% end %> | ||
|
|
||
| <%= form_for @url do |f| %> | ||
| <%= f.text_field :address %> | ||
| <%= f.submit "Shorten URL" %> | ||
| <% end %> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,56 +1,7 @@ | ||
| Rails.application.routes.draw do | ||
| # The priority is based upon order of creation: first created -> highest priority. | ||
| # See how all your routes lay out with "rake routes". | ||
| root "urls#index" | ||
|
|
||
| # You can have the root of your site routed with "root" | ||
| # root 'welcome#index' | ||
| resources :urls, only: [:index, :create] | ||
|
|
||
| # Example of regular route: | ||
| # get 'products/:id' => 'catalog#view' | ||
|
|
||
| # Example of named route that can be invoked with purchase_url(id: product.id) | ||
| # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase | ||
|
|
||
| # Example resource route (maps HTTP verbs to controller actions automatically): | ||
| # resources :products | ||
|
|
||
| # Example resource route with options: | ||
| # resources :products do | ||
| # member do | ||
| # get 'short' | ||
| # post 'toggle' | ||
| # end | ||
| # | ||
| # collection do | ||
| # get 'sold' | ||
| # end | ||
| # end | ||
|
|
||
| # Example resource route with sub-resources: | ||
| # resources :products do | ||
| # resources :comments, :sales | ||
| # resource :seller | ||
| # end | ||
|
|
||
| # Example resource route with more complex sub-resources: | ||
| # resources :products do | ||
| # resources :comments | ||
| # resources :sales do | ||
| # get 'recent', on: :collection | ||
| # end | ||
| # end | ||
|
|
||
| # Example resource route with concerns: | ||
| # concern :toggleable do | ||
| # post 'toggle' | ||
| # end | ||
| # resources :posts, concerns: :toggleable | ||
| # resources :photos, concerns: :toggleable | ||
|
|
||
| # Example resource route within a namespace: | ||
| # namespace :admin do | ||
| # # Directs /admin/products/* to Admin::ProductsController | ||
| # # (app/controllers/admin/products_controller.rb) | ||
| # resources :products | ||
| # end | ||
| get '/:slug', to: 'urls#show' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like it. |
||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| class CreateUrls < ActiveRecord::Migration | ||
| def change | ||
| create_table :urls do |t| | ||
| t.string :address | ||
|
|
||
| t.timestamps | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class AddClickCountToUrls < ActiveRecord::Migration | ||
| def change | ||
| add_column :urls, :click_count, :integer | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class AddShortenedAddressSuffixToUrl < ActiveRecord::Migration | ||
| def change | ||
| add_column :urls, :shortened_address_suffix, :string | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class ChangeShortenedAddressSuffixToSlug < ActiveRecord::Migration | ||
| def change | ||
| rename_column :urls, :shortened_address_suffix, :slug | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class AddIndexToSlug < ActiveRecord::Migration | ||
| def change | ||
| add_index :urls, :slug | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class AddDefaultValueToClickCount < ActiveRecord::Migration | ||
| def change | ||
| change_column :urls, :click_count, :integer, default: 0 | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # encoding: UTF-8 | ||
| # This file is auto-generated from the current state of the database. Instead | ||
| # of editing this file, please use the migrations feature of Active Record to | ||
| # incrementally modify your database, and then regenerate this schema definition. | ||
| # | ||
| # Note that this schema.rb definition is the authoritative source for your | ||
| # database schema. If you need to create the application database on another | ||
| # system, you should be using db:schema:load, not running all the migrations | ||
| # from scratch. The latter is a flawed and unsustainable approach (the more migrations | ||
| # you'll amass, the slower it'll run and the greater likelihood for issues). | ||
| # | ||
| # It's strongly recommended that you check this file into your version control system. | ||
|
|
||
| ActiveRecord::Schema.define(version: 20180130212955) do | ||
|
|
||
| create_table "urls", force: true do |t| | ||
| t.string "address" | ||
| t.datetime "created_at" | ||
| t.datetime "updated_at" | ||
| t.integer "click_count", default: 0 | ||
| t.string "slug" | ||
| end | ||
|
|
||
| add_index "urls", ["slug"], name: "index_urls_on_slug" | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| require 'rails_helper' | ||
|
|
||
| RSpec.describe Url, :type => :model do | ||
| pending "add some examples to (or delete) #{__FILE__}" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how would you test the feature that you wrote? |
||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file should probably go in .gitignore - no reason for it to be part of the history of the repo.