Skip to content

Commit f4ac5c6

Browse files
committed
Merge branch 'development' into centralize-error-handling
2 parents 22f2425 + f8cb33e commit f4ac5c6

File tree

12 files changed

+96
-40
lines changed

12 files changed

+96
-40
lines changed

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ gem 'rails-api'
1010
gem 'spring', :group => :development
1111

1212
gem 'rack-cors'
13+
gem "paranoia", "~> 2.0"
1314

1415
gem 'pg'
1516
gem 'active_model_serializers', github: 'rails-api/active_model_serializers'
@@ -19,6 +20,7 @@ gem 'devise'
1920
gem 'simple_token_authentication', '~> 1.0'
2021
gem 'cancancan'
2122
gem 'stripe', '1.20.1'
23+
gem 'has_secure_token'
2224

2325
group :development, :test do
2426
gem 'pry-rails'

Gemfile.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ GEM
7272
railties (>= 3.0.0)
7373
globalid (0.3.5)
7474
activesupport (>= 4.1.0)
75+
has_secure_token (1.0.0)
76+
activerecord (>= 3.0)
7577
hashie (3.4.1)
7678
http-cookie (1.0.2)
7779
domain_name (~> 0.5)
@@ -95,6 +97,8 @@ GEM
9597
nokogiri (1.6.6.2)
9698
mini_portile (~> 0.6.0)
9799
orm_adapter (0.5.0)
100+
paranoia (2.1.2)
101+
activerecord (~> 4.0)
98102
pg (0.18.1)
99103
pry (0.10.1)
100104
coderay (~> 1.1.0)
@@ -199,7 +203,9 @@ DEPENDENCIES
199203
devise
200204
dotenv-rails
201205
factory_girl_rails
206+
has_secure_token
202207
hashie
208+
paranoia (~> 2.0)
203209
pg
204210
pry
205211
pry-rails

app/controllers/teams_controller.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'team_playbook/scenario/create_team'
2+
require 'team_playbook/scenario/delete_team'
23
require 'team_playbook/scenario/change_plan_for_team'
34
require 'team_playbook/scenario/add_card_to_team'
45
require 'errors/credit_card_required_error'
@@ -20,7 +21,12 @@ def create
2021
end
2122

2223
def show
23-
render json: current_team, status: 200
24+
if has_team_subdomain?
25+
authorize! :read, current_team
26+
render json: current_team, status: 200
27+
else
28+
forbidden
29+
end
2430
end
2531

2632
def destroy
@@ -45,4 +51,4 @@ def team_params
4551
def credit_card_required
4652
render json: {error: "A credit card is required for a paid plan."}, status: :unprocessable_entity
4753
end
48-
end
54+
end

app/models/ability.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ def initialize(user, team)
66

77
current_users_team_membership_in_current_team = TeamMembership.find_by(team: team, user: user)
88

9+
can :read, Team if current_users_team_membership_in_current_team.present?
910
can :destroy, Team, owner: user
1011

1112
can :create, TeamMembership, team: team if team.owner == user
@@ -15,4 +16,4 @@ def initialize(user, team)
1516
can :destroy, TeamMembership, team: team, user: user unless current_users_team_membership_in_current_team.owner?
1617
end
1718
end
18-
end
19+
end

app/models/team.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
class Team < ActiveRecord::Base
2+
acts_as_paranoid
3+
24
validates :subdomain, presence: true, exclusion: { in: Settings.reserved_subdomains,
35
message: "%{value} is not a valid subdomain." }
46
validates :name, presence: true
@@ -13,4 +15,4 @@ class Team < ActiveRecord::Base
1315
delegate :name, to: :plan, prefix: true
1416
delegate :slug, to: :plan, prefix: true
1517

16-
end
18+
end

app/models/user.rb

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,12 @@
11
class User < ActiveRecord::Base
2+
has_secure_token :authentication_token
23
acts_as_token_authenticatable
3-
4+
45
# Include default devise modules. Others available are:
56
# :confirmable, :lockable, :timeoutable and :omniauthable
67
devise :database_authenticatable, :registerable,
78
:recoverable, :trackable, :validatable
89

9-
before_save :ensure_authentication_token
10-
1110
has_many :team_memberships
1211
has_many :teams, through: :team_memberships
13-
14-
def ensure_authentication_token
15-
if authentication_token.blank?
16-
self.authentication_token = generate_authentication_token
17-
end
18-
end
19-
20-
private
21-
22-
def generate_authentication_token
23-
Devise.friendly_token
24-
end
25-
2612
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class AddDeletedAtToTeams < ActiveRecord::Migration
2+
def change
3+
add_column :teams, :deleted_at, :datetime
4+
add_index :teams, :deleted_at
5+
end
6+
end

db/schema.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212
# It's strongly recommended that you check this file into your version control system.
1313

14-
ActiveRecord::Schema.define(version: 20150515071915) do
14+
ActiveRecord::Schema.define(version: 20150518073824) do
1515

1616
# These are extensions that must be enabled in order to support this database
1717
enable_extension "plpgsql"
@@ -52,8 +52,11 @@
5252
t.integer "owner_id"
5353
t.string "stripe_customer_id"
5454
t.integer "status", default: 1
55+
t.datetime "deleted_at"
5556
end
5657

58+
add_index "teams", ["deleted_at"], name: "index_teams_on_deleted_at", using: :btree
59+
5760
create_table "users", force: :cascade do |t|
5861
t.string "email", default: "", null: false
5962
t.string "encrypted_password", default: "", null: false

spec/api/teams_spec.rb

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,55 @@
11
require 'rails_helper'
22

33
describe "Teams service" do
4-
describe "POST to create" do
4+
describe "GET /team" do
5+
it "should return a 403 Forbidden when called from non-team subdomain" do
6+
user = create(:user)
7+
team = create(:team)
8+
9+
host! "www.example.com"
10+
11+
get "/team", {}, {"X-User-Email" => user.email, "X-User-Token" => user.authentication_token}
12+
13+
expect(response.code).to eq "403"
14+
end
15+
16+
it "should return a 401 Not Authorized when called from a team subdomain by an unauthenticated user" do
17+
team = create(:team)
18+
19+
host! "#{team.subdomain}.example.com"
20+
21+
get "/team"
22+
23+
expect(response.code).to eq "401"
24+
end
25+
26+
it "should return a 401 Not Authorized when called from a team subdomain by an authenticated non-member of the team" do
27+
user = create(:user)
28+
team = create(:team)
29+
30+
host! "#{team.subdomain}.example.com"
31+
32+
get "/team", {}, {"X-User-Email" => user.email, "X-User-Token" => user.authentication_token}
33+
34+
expect(response.code).to eq "401"
35+
end
36+
37+
it "should fetch the team when called from a team subdomain by an authenticated team member" do
38+
member = create(:user)
39+
team = create(:team)
40+
team_membership = create(:team_membership, user: member, team: team, role: :member)
41+
42+
host! "#{team.subdomain}.example.com"
43+
44+
get "/team", {}, {"X-User-Email" => member.email, "X-User-Token" => member.authentication_token}
545

46+
expect(response.code).to eq "200"
47+
expect(json.data.subdomain).to eq team.subdomain
48+
expect(json.data.name).to eq team.name
49+
end
50+
end
51+
52+
describe "POST to create" do
653
before do
754
create(:plan, slug: "free_plan", name: "Free Plan", amount: 0)
855
create(:plan, slug: "pro_plan", name: "Pro Plan")
@@ -49,7 +96,6 @@
4996
get "/team", {}, {"X-User-Email" => user.email, "X-User-Token" => user.authentication_token}
5097
expect(json.data.plan_name).to eq "Free Plan"
5198
end
52-
5399
end
54100

55101
describe "Post to change_plan" do
@@ -186,6 +232,12 @@
186232
}
187233

188234
expect(response.code).to eq "204"
235+
236+
get "/team", {}, {
237+
"X-User-Email" => owner.email, "X-User-Token" => owner.authentication_token
238+
}
239+
240+
expect(response.code).to eq "404"
189241
end
190242
end
191-
end
243+
end

spec/factories/subscriptions.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
FactoryGirl.define do
22
factory :subscription do
3-
3+
association :plan
44
end
55

66
end

0 commit comments

Comments
 (0)