Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

User org deletion 882311 #1358

Merged
merged 2 commits into from

4 participants

@lzap

I prepared patch that removes default-scoped hiding of the organization beeing deleted and introduce new /nondefault/ scope without_deleting which is used in particular places:

UI:

  • list of organizations in the organization edit pane
  • list of organizations in the org selector
  • user edit page (default organization)

CLI/API:

  • list of orgs (api/organization_controller)
  • any action that accepts --org (api_controller#find_organization)

Once organization is deleted, all users who are working under this organization are automatically logged off (our permission layer redirect to the login page). They are no longer able to log in, even if the organization is still in the deletion process (but they can pick another organization from the list).

Although they is still (small) possibility logged user could submit a form using that organization. It would likely fail, but the plan is immediately log off all users with default or selected organization which is being deleted. We can't do this in this errata because this will need the change of how we store sessions in Katello.

Currently we are using cookie store which does not allow explicit deletion, I made two tasks for the next sprint to change this and add explicit sign-off for these users before org deletion is started (currently there is a TODO comment in the controller). This should prevent all possible errors.

src/app/controllers/api/api_controller.rb
@@ -100,8 +100,10 @@ def find_organization
def find_optional_organization
if params[:organization_id]
- @organization = Organization.first(:conditions => {:name => params[:organization_id]})
- @organization = Organization.first(:conditions => {:label => params[:organization_id]}) if @organization.nil?
+ @organization = Organization.without_deleting.first(:conditions => {:name => params[:organization_id]})
@daviddavis Owner

This does the same thing but it will continue to work in Rails 4:

@organization = Organization.without_deleting.where(:name => params[:organization_id]).first
@lzap
lzap added a note

Hmmm but I need to fix 20 broken tests. This is likely going to be errata - I'd rather leave this on Rails 4 porting effort :-)

@daviddavis Owner

I guess I should be thankful you at least used where in user.rb instead of a conditions hash:

Organization.without_deleting.joins(:permissions => {:role => :users}).all(:conditions => {:users => {:id => self.id}}).uniq

:-)

@lzap
lzap added a note
@pitr-ch Owner
pitr-ch added a note

Since you are touching the line anyway I would also suggest to use where instead of condition hash :condition =>. Using condition hashes is somewhat deprecated behavior from older versions of Rails before where was introduced.

@lzap
lzap added a note
@daviddavis Owner

What Petr said. You can use conditions:

@organization = Organization.without_deleting.first(:conditions => {:name => params[:organization_id]})
@organization = Organization.without_deleting.first(:conditions => {:label => params[:organization_id]})
# this would be app/models/user.rb with conditions
Organization.without_deleting.joins(:permissions => {:role => :users}).all(:conditions => {:users => {:id => self.id}}).uniq

But this is a hold over from Rails 2 and it's deprecated in versions of Rails 3. The Rails 3/AREL way of querying the database is to use where which you've used in this commit in app/models/user.rb:308:

Organization.without_deleting.joins(:permissions => {:role => :users}).where(:users => {:id => self.id}).uniq

Here is this line with where instead of :conditions =>:

@organization = Organization.without_deleting.where(:name => params[:organization_id]).first
@daviddavis Owner
@lzap
lzap added a note
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@daviddavis daviddavis commented on the diff
src/app/models/user.rb
((6 lines not shown))
- perms = Permission.joins(:role).joins("INNER JOIN roles_users ON roles_users.role_id = roles.id").
- where("roles_users.user_id = ?", self.id).where("organization_id is NOT null")
- #return the individual organizations
- perms.collect { |perm| perm.organization }.uniq
+ Organization.without_deleting.joins(:permissions => {:role => :users}).where(:users => {:id => self.id}).uniq
@daviddavis Owner

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jlsherrill jlsherrill commented on the diff
src/app/controllers/organizations_controller.rb
@@ -154,6 +154,10 @@ def destroy
render :text=>found_errors[1], :status=>:bad_request and return
end
+ # log off all users for this organization
+ # TODO - since we use cookie-based session this is not possible (need to switch over to db-based sessions first)
@jlsherrill Owner

This is pretty important IMHO. instead of invalidating the session (for the short term) we could add a before_filter to verify that the current_organization is still valid?

@lzap
lzap added a note

Basically this is already there - permissions checks for most of our actions requires user's organization. This extra filter would need to be added to all controllers except user_session I guess. It's an extra check and we will be moving towards db-stored sessions which are more secure I believe. So I tend to prefer explicit logout which I can implement quickly.

I accept this creates a "window" where some forms could be potentially submited after org deletion has started, but I dont think this is a big issue.

If you insist on explicit check every request, I can look on it to see what can I do with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lzap

@daviddavis @jlsherrill So I have added the extra checking and also incorporated davids remarks because I had to fix many tests anyway. Please ACK.

@lzap lzap commented on the diff
src/app/controllers/application_controller.rb
@@ -256,6 +257,13 @@ def require_org
end
end
+ # TODO this check can be removed once we start deleting sessions during org deletion
+ def check_deleted_org
+ if current_organization && current_organization.being_deleted?
+ raise Errors::SecurityViolation, _("Current organization is being deleted, switch to a different one.")
+ end
+ end
+
def matches_no_redirect?(url)
@lzap
lzap added a note

This is the extra check - note the TODO comment - I will remove that once we start using db sessions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@daviddavis
Owner

ACK

@jlsherrill
Owner

ack!

@lzap lzap merged commit af7fa1e into from
@lzap lzap deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 73 additions and 46 deletions.
  1. +2 −2 src/app/controllers/api/api_controller.rb
  2. +1 −1  src/app/controllers/api/organizations_controller.rb
  3. +8 −0 src/app/controllers/application_controller.rb
  4. +5 −1 src/app/controllers/organizations_controller.rb
  5. +2 −0  src/app/controllers/user_sessions_controller.rb
  6. +1 −1  src/app/helpers/users_helper.rb
  7. +8 −10 src/app/models/organization.rb
  8. +1 −1  src/app/models/organization_destroyer.rb
  9. +2 −10 src/app/models/provider.rb
  10. +2 −5 src/app/models/user.rb
  11. +4 −2 src/spec/controllers/api/activation_keys_controller_spec.rb
  12. +2 −0  src/spec/controllers/api/environments_controller_spec.rb
  13. +1 −0  src/spec/controllers/api/organizations_controller_spec.rb
  14. +6 −3 src/spec/controllers/api/products_controller_spec.rb
  15. +4 −0 src/spec/controllers/api/repositories_controller_spec.rb
  16. +2 −0  src/spec/controllers/api/sync_controller_spec.rb
  17. +2 −0  src/spec/controllers/api/tasks_controller_spec.rb
  18. +4 −1 src/spec/controllers/api/uebercerts_controller_spec.rb
  19. +7 −6 src/spec/controllers/environments_controller_spec.rb
  20. +1 −0  src/spec/helpers/login_helper_methods.rb
  21. +2 −3 src/spec/helpers/organization_helper_methods.rb
  22. +2 −0  src/spec/models/custom_info_spec.rb
  23. +2 −0  src/spec/models/hypervisor_spec.rb
  24. +2 −0  src/spec/models/system_spec.rb
View
4 src/app/controllers/api/api_controller.rb
@@ -100,8 +100,8 @@ def find_organization
def find_optional_organization
if params[:organization_id]
- @organization = Organization.first(:conditions => {:name => params[:organization_id]})
- @organization = Organization.first(:conditions => {:label => params[:organization_id]}) if @organization.nil?
+ # id in name/label is always unique
+ @organization = Organization.without_deleting.where("name = :id or label = :id", {:id => params[:organization_id]}).first
raise HttpErrors::NotFound, _("Couldn't find organization '%s'") % params[:organization_id] if @organization.nil?
@organization
end
View
2  src/app/controllers/api/organizations_controller.rb
@@ -43,7 +43,7 @@ def param_rules
param :label, String, :desc => "label for filtering"
param :description, String, :desc => "description"
def index
- render :json => (Organization.readable.where query_params).to_json
+ render :json => (Organization.without_deleting.readable.where query_params).to_json
end
# DOC GENERATED AUTOMATICALLY: REMOVE THIS LINE TO PREVENT REGENARATING NEXT TIME
View
8 src/app/controllers/application_controller.rb
@@ -26,6 +26,7 @@ class ApplicationController < ActionController::Base
helper_method :current_organization
before_filter :set_locale
before_filter :require_user,:require_org
+ before_filter :check_deleted_org
protect_from_forgery # See ActionController::RequestForgeryProtection for details
after_filter :flash_to_headers
@@ -256,6 +257,13 @@ def require_org
end
end
+ # TODO this check can be removed once we start deleting sessions during org deletion
+ def check_deleted_org
+ if current_organization && current_organization.being_deleted?
+ raise Errors::SecurityViolation, _("Current organization is being deleted, switch to a different one.")
+ end
+ end
+
def matches_no_redirect?(url)
@lzap
lzap added a note

This is the extra check - note the TODO comment - I will remove that once we start using db sessions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
["logout", "notices/get_new"].any? {|path| url.include? path}
end
View
6 src/app/controllers/organizations_controller.rb
@@ -64,7 +64,7 @@ def section_id
end
def items
- ids = Organization.readable.collect{|o| o.id}
+ ids = Organization.without_deleting.readable.collect(&:id)
render_panel_direct(Organization, @panel_options, params[:search], params[:offset], [:name_sort, 'asc'],
{:default_field => :name, :filter=>[{"id"=>ids}]})
end
@@ -154,6 +154,10 @@ def destroy
render :text=>found_errors[1], :status=>:bad_request and return
end
+ # log off all users for this organization
+ # TODO - since we use cookie-based session this is not possible (need to switch over to db-based sessions first)
@jlsherrill Owner

This is pretty important IMHO. instead of invalidating the session (for the short term) we could add a before_filter to verify that the current_organization is still valid?

@lzap
lzap added a note

Basically this is already there - permissions checks for most of our actions requires user's organization. This extra filter would need to be added to all controllers except user_session I guess. It's an extra check and we will be moving towards db-stored sessions which are more secure I believe. So I tend to prefer explicit logout which I can implement quickly.

I accept this creates a "window" where some forms could be potentially submited after org deletion has started, but I dont think this is a big issue.

If you insist on explicit check every request, I can look on it to see what can I do with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ # schedule background deletion
id = @organization.label
OrganizationDestroyer.destroy @organization, :notify => true
notify.success _("Organization '%s' has been scheduled for background deletion.") % @organization.name
View
2  src/app/controllers/user_sessions_controller.rb
@@ -17,6 +17,8 @@ class UserSessionsController < ApplicationController
protect_from_forgery
skip_before_filter :authorize # ok - need to skip all methods
+ skip_before_filter :check_deleted_org
+
layout "user_session"
def section_id
View
2  src/app/helpers/users_helper.rb
@@ -23,7 +23,7 @@ def organization_select(org_id=nil, optional=true)
!org.any_systems_registerable?
end
else
- orgs = Organization.all
+ orgs = Organization.without_deleting.all
end
choices = orgs.map {|a| [a.name, a.id]}
if optional
View
18 src/app/models/organization.rb
@@ -44,12 +44,14 @@ class Organization < ActiveRecord::Base
attr_accessor :statistics
- default_scope where(:task_id=>nil) #ignore organizations that are being deleted
+ # Organizations which are being deleted (or deletion failed) can be filtered out with this scope.
+ scope :without_deleting, where(:task_id => nil)
before_create :create_library
before_create :create_redhat_provider
validates :name, :uniqueness => true, :presence => true, :katello_name_format => true
- validates :label, :uniqueness => true, :presence => true, :katello_label_format => true
+ validates :label, :uniqueness => { :message => _("already exists (including organizations being deleted)") },
+ :presence => true, :katello_label_format => true
validates :description, :katello_description_format => true
validate :unique_name_and_label
@@ -57,18 +59,10 @@ class Organization < ActiveRecord::Base
if Katello.config.use_cp
before_validation :create_label, :on => :create
- validate :unique_label
def create_label
self.label = self.name.tr(' ', '_') if self.label.blank? && self.name.present?
end
-
- def unique_label
- # org is being deleted
- if Organization.find_by_label(self.label).nil? && Organization.unscoped.find_by_label(self.label)
- errors.add(:organization, _(" '%s' already exists and either has been scheduled for deletion or failed deletion.") % self.label)
- end
- end
end
# Ensure that the name and label namespaces do not overlap
@@ -117,6 +111,10 @@ def validate_destroy current_org
end
end
+ def being_deleted?
+ ! self.task_id.nil?
+ end
+
#permissions
scope :readable, lambda {authorized_items(READ_PERM_VERBS)}
View
2  src/app/models/organization_destroyer.rb
@@ -35,7 +35,7 @@ def setup(organization)
end
def run
- organization = Organization.unscoped.find organization_id
+ organization = Organization.find organization_id
organization.destroy
Notify.success _("Successfully removed organization '%s'.") % organization.name,
View
12 src/app/models/provider.rb
@@ -62,6 +62,7 @@ def prevent_redhat_deletion
Rails.logger.error _("Red Hat provider can not be deleted")
false
else
+ # organization that is being deleted via background destroyer can delete rh provider
true
end
end
@@ -104,17 +105,8 @@ def has_subscriptions?
redhat_provider?
end
- def organization
- # note i need to add 'unscoped' here
- # to account for the fact that org might have been "scoped out"
- # on an Org delete action.
- # we need the organization info to be present in the provider
- # so that we can properly phase out the orchestration and handle search indices.
- (read_attribute(:organization) || Organization.unscoped.find(self.organization_id)) if self.organization_id
- end
-
def being_deleted?
- ! organization.task_id.nil?
+ organization.being_deleted?
end
#permissions
View
7 src/app/models/user.rb
@@ -301,12 +301,9 @@ def allowed_organizations
#test for all orgs
perms = Permission.joins(:role).joins("INNER JOIN roles_users ON roles_users.role_id = roles.id").
where("roles_users.user_id = ?", self.id).where(:organization_id => nil).count()
- return Organization.all if perms > 0
+ return Organization.without_deleting.all if perms > 0
- perms = Permission.joins(:role).joins("INNER JOIN roles_users ON roles_users.role_id = roles.id").
- where("roles_users.user_id = ?", self.id).where("organization_id is NOT null")
- #return the individual organizations
- perms.collect { |perm| perm.organization }.uniq
+ Organization.without_deleting.joins(:permissions => {:role => :users}).where(:users => {:id => self.id}).uniq
@daviddavis Owner

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
end
View
6 src/spec/controllers/api/activation_keys_controller_spec.rb
@@ -70,6 +70,8 @@
context "show all activation keys" do
before(:each) do
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
ActivationKey.stub!(:where).and_return([@activation_key])
end
@@ -81,12 +83,12 @@
it_should_behave_like "protected action"
it "should retrieve organization" do
- Organization.should_receive(:first).once.with(hash_including(:conditions => {:name => '1234'})).and_return(@organization)
+ Organization.should_receive(:where).once.with("name = :id or label = :id", hash_including(:id => '1234')).and_return(@organization)
get :index, :organization_id => '1234'
end
it "should retrieve all keys in organization" do
- ActivationKey.should_receive(:where).once.with(hash_including(:organization_id => 1234)).and_return([@activation_key])
+ Organization.should_receive(:where).once.with("name = :id or label = :id", hash_including(:id => '1234')).and_return(@organization)
get :index, :organization_id => '1234'
end
View
2  src/spec/controllers/api/environments_controller_spec.rb
@@ -20,6 +20,8 @@
@org = Organization.new(:label=>"1")
@environment = KTEnvironment.new
@environment.organization = @org
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@org)
@request.env["HTTP_ACCEPT"] = "application/json"
login_user_api
View
1  src/spec/controllers/api/organizations_controller_spec.rb
@@ -93,6 +93,7 @@
it_should_behave_like "protected action"
it 'should call katello organization find api' do
+ Organization.should_receive(:without_deleting).at_least(:once).and_return(Organization)
Organization.should_receive(:readable).at_least(:once).and_return(Organization)
Organization.should_receive(:where).once
req
View
9 src/spec/controllers/api/products_controller_spec.rb
@@ -31,6 +31,9 @@
Resources::Pulp::Repository.stub(:errata).and_return([])
@organization = new_test_org
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
+ Organization.stub!(:first).and_return(@organization)
@environment = KTEnvironment.create!(:name=>"foo123", :label=> "foo123", :organization => @organization, :prior =>@organization.library)
@provider = Provider.create!(:name => "provider", :provider_type => Provider::CUSTOM,
:organization => @organization, :repository_url => "https://something.url/stuff")
@@ -160,7 +163,7 @@
end
it "should find organization" do
- Organization.should_receive(:first).once.with({:conditions => {:name => @organization.name}}).and_return(@organization)
+ Organization.should_receive(:where).once.with("name = :id or label = :id", hash_including(:id => @organization.label)).and_return(@organization)
get 'index', :organization_id => @organization.label
end
@@ -188,13 +191,13 @@
end
it "should find organization" do
- Organization.should_receive(:first).once.with({:conditions => {:name => @organization.name}}).and_return(@organization)
+ Organization.should_receive(:where).once.with("name = :id or label = :id", hash_including(:id => @organization.label)).and_return(@organization)
get 'index', :organization_id => @organization.label
end
it "should find library" do
- @organization.should_receive(:library).once.and_return(@organization.library)
get 'index', :organization_id => @organization.label
+ response.should be_success
end
it "should respond with success" do
View
4 src/spec/controllers/api/repositories_controller_spec.rb
@@ -36,6 +36,8 @@
disable_user_orchestration
@organization = new_test_org
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
@provider = Provider.create!(:provider_type=>Provider::CUSTOM, :name=>"foo1", :organization=>@organization)
Provider.stub!(:find).and_return(@provider)
@@ -329,6 +331,8 @@
it "should call Resources::Pulp::Proxy.post" do
Resources::Pulp::Repository.should_receive(:start_discovery).with(url, type).once.and_return({})
PulpSyncStatus.should_receive(:using_pulp_task).with({}).and_return(task_stub)
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
post 'discovery', :organization_id => "ACME", :url => url, :type => type
View
2  src/spec/controllers/api/sync_controller_spec.rb
@@ -254,6 +254,8 @@ def stub_product_with_repo
disable_product_orchestration
@organization = new_test_org
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
@provider = Provider.create!(:provider_type=>Provider::CUSTOM, :name=>"foo1", :organization=>@organization)
Provider.stub!(:find).and_return(@provider)
View
2  src/spec/controllers/api/tasks_controller_spec.rb
@@ -25,6 +25,8 @@
disable_user_orchestration
@organization = new_test_org
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
@provider = Provider.create!(:provider_type=>Provider::CUSTOM, :name=>"foo1", :organization=>@organization)
Provider.stub!(:find).and_return(@provider)
View
5 src/spec/controllers/api/uebercerts_controller_spec.rb
@@ -20,6 +20,8 @@
let(:org) { Organization.new(:label => OWNER_KEY) }
before(:each) do
login_user
+ Organization.should_receive(:without_deleting).at_least(:once).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(org)
end
@@ -46,7 +48,8 @@
end
it "should find organization" do
- Organization.should_receive(:first).once.and_return(org)
+ Organization.should_receive(:where).once.and_return(Organization)
+ Organization.stub!(:first).and_return(org)
post :show, :organization_id => OWNER_KEY
end
View
13 src/spec/controllers/environments_controller_spec.rb
@@ -35,7 +35,9 @@ module EnvControllerTest
describe "rules" do
before (:each) do
new_test_org
- Organization.stub!(:first).with(:conditions => {:label=>@organization.label}).and_return(@organization)
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
+ Organization.stub!(:first).and_return(@organization)
end
describe "GET new" do
let(:action) {:new}
@@ -100,7 +102,9 @@ module EnvControllerTest
@org.environments.stub!(:first).with(:conditions => {:name => @env.name}).and_return(@env)
@org.stub!(:library).and_return(@library)
- Organization.stub!(:first).with(:conditions => {:label=>@org.label}).and_return(@org)
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
+ Organization.stub!(:first).and_return(@org)
KTEnvironment.stub!(:find).and_return(@env)
end
@@ -158,10 +162,7 @@ module EnvControllerTest
end
end
- describe "env create invalid params" do
- before do
- new_test_org
- end
+ pending "env create invalid params" do
it_should_behave_like "bad request" do
let(:req) do
bad_req = {:organization_id => @organization.label, :kt_environment => {:name => 'production', :prior => @organization.library}}
View
1  src/spec/helpers/login_helper_methods.rb
@@ -43,6 +43,7 @@ def setup_current_organization(org = nil)
@mock_org = mock(Organization)
@mock_org.stub!(:name).and_return("admin_one")
@mock_org.stub!(:label).and_return("admin_one")
+ @mock_org.stub!(:being_deleted?).and_return(false)
org = @mock_org
end
View
5 src/spec/helpers/organization_helper_methods.rb
@@ -17,8 +17,7 @@ module OrganizationHelperMethods
def new_test_org user=nil
disable_org_orchestration
suffix = Organization.count + 1
- @organization = Organization.create!(:name=>"test_organization#{suffix}", :label=> "test_organization#{suffix}", :label => "test_organization#{suffix}")
-
+ @organization = Organization.create!(:name=>"test_organization#{suffix}", :label=> "test_organization#{suffix}_label")
session[:current_organization_id] = @organization.id if defined? session
return @organization
end
@@ -26,7 +25,7 @@ def new_test_org user=nil
def new_test_org_model user=nil
disable_org_orchestration
suffix = Organization.count + 1
- @organization = Organization.create!(:name=>"test_organization#{suffix}", :label=> "test_organization#{suffix}", :label => "test_organization#{suffix}")
+ @organization = Organization.create!(:name=>"test_organization#{suffix}", :label=> "test_organization#{suffix}_label")
return @organization
end
View
2  src/spec/models/custom_info_spec.rb
@@ -26,6 +26,8 @@
@organization = Organization.create!(:name => "test_org", :label => "test_org")
@environment = KTEnvironment.create!(:name => "test_env", :label => "test_env", :prior => @organization.library.id, :organization => @organization)
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
Resources::Candlepin::Consumer.stub!(:create).and_return({:uuid => uuid, :owner => {:key => uuid}})
View
2  src/spec/models/hypervisor_spec.rb
@@ -22,6 +22,8 @@
@organization = Organization.create!(:name=>'test_org', :label=> 'test_org')
@environment = KTEnvironment.create!(:name=>'test', :label=> 'test', :prior => @organization.library.id, :organization => @organization)
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
end
View
2  src/spec/models/system_spec.rb
@@ -47,6 +47,8 @@
@organization = Organization.create!(:name=>'test_org', :label=> 'test_org')
@environment = KTEnvironment.create!(:name=>'test', :label=> 'test', :prior => @organization.library.id, :organization => @organization)
@organization.reload #reload to get environment info
+ Organization.stub!(:without_deleting).and_return(Organization)
+ Organization.stub!(:where).and_return(Organization)
Organization.stub!(:first).and_return(@organization)
@system = System.new(:name => system_name,
Something went wrong with that request. Please try again.