diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index 18651a3ab12..65dcfaf886c 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -157,7 +157,11 @@ class SiteSetting < ActiveRecord::Base
 
   setting(:enforce_global_nicknames, true)
   setting(:discourse_org_access_key, '')
+  
   setting(:enable_s3_uploads, false)
+  setting(:s3_access_key_id, '')
+  setting(:s3_secret_access_key, '')
+  setting(:s3_region, 'us-west-1')
   setting(:s3_upload_bucket, '')
 
   setting(:default_trust_level, 0)
diff --git a/app/models/upload.rb b/app/models/upload.rb
index 8de2a6e168a..b14442dc17d 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -1,8 +1,6 @@
 require 'digest/sha1'
 
 class Upload < ActiveRecord::Base
-  # attr_accessible :title, :body
-
   belongs_to :user
   belongs_to :topic
 
@@ -43,21 +41,26 @@ class Upload < ActiveRecord::Base
     image_info = FastImage.new(tempfile, raise_on_failure: true)
     blob = file.read
     sha1 = Digest::SHA1.hexdigest(blob)
+    remote_filename = "#{sha1}.#{image_info.type}"
 
-    Fog.credentials_path = "#{Rails.root}/config/fog_credentials.yml"
-    fog = Fog::Storage.new(provider: 'AWS')
+    fog = Fog::Storage.new(
+      aws_access_key_id: SiteSetting.s3_access_key_id,
+      aws_secret_access_key: SiteSetting.s3_secret_access_key,
+      region: SiteSetting.s3_region,
+      provider: 'AWS'
+    )
 
-    remote_filename = "#{sha1[2..-1]}.#{image_info.type}"
-    path = "/uploads/#{sha1[0]}/#{sha1[1]}"
-    location = "#{SiteSetting.s3_upload_bucket}#{path}"
-    directory = fog.directories.create(key: location)
+    directory = fog.directories.create(key: SiteSetting.s3_upload_bucket)
 
-    file = directory.files.create(key: remote_filename,
-                                  body: tempfile,
-                                  public: true,
-                                  content_type: file.content_type)
+    file = directory.files.create(
+      key: remote_filename,
+      body: tempfile,
+      public: true,
+      content_type: file.content_type
+    )
+    
     upload.width, upload.height = ImageSizer.resize(*image_info.size)
-    upload.url = "//#{SiteSetting.s3_upload_bucket}.s3.amazonaws.com#{path}/#{remote_filename}"
+    upload.url = "//#{SiteSetting.s3_upload_bucket}.s3-#{SiteSetting.s3_region}.amazonaws.com/#{remote_filename}"
 
     upload.save
 
@@ -79,12 +82,14 @@ class Upload < ActiveRecord::Base
     clean_name += ".#{image_info.type}"
     url_root = "/uploads/#{RailsMultisite::ConnectionManagement.current_db}/#{upload.id}"
     path = "#{Rails.root}/public#{url_root}"
-    upload.width, upload.height = ImageSizer.resize(*image_info.size)
+
     FileUtils.mkdir_p path
     # not using cause mv, cause permissions are no good on move
     File.open("#{path}/#{clean_name}", "wb") do |f|
       f.write File.read(file.tempfile)
     end
+
+    upload.width, upload.height = ImageSizer.resize(*image_info.size)
     upload.url = Discourse::base_uri + "#{url_root}/#{clean_name}"
 
     upload.save
diff --git a/config/fog_credentials.yml.sample b/config/fog_credentials.yml.sample
deleted file mode 100644
index 5856280429b..00000000000
--- a/config/fog_credentials.yml.sample
+++ /dev/null
@@ -1,4 +0,0 @@
-default:
-  aws_access_key_id: 'your-aws-access-key-id'
-  aws_secret_access_key: 'your-aws-secret-access-key/'
-  region: 'your-aws-region'
\ No newline at end of file
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 3190b65e22e..8b83e79066a 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -544,6 +544,9 @@ en:
 
     enable_s3_uploads: "Place uploads on Amazon S3"
     s3_upload_bucket: "The Amazon S3 bucket name that files will be uploaded into"
+    s3_access_key_id: "The Amazon S3 access key id that will be used to upload images"
+    s3_secret_access_key: "The Amazon S3 secret access key that will be used to upload images"
+    s3_region: "The Amazon S3 region name that will be used to upload images"
 
     default_invitee_trust_level: "Default trust level (0-4) for invited users"
     default_trust_level: "Default trust level (0-4) for users"
diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb
index c09c46cda26..30cca967e14 100644
--- a/spec/models/upload_spec.rb
+++ b/spec/models/upload_spec.rb
@@ -1,4 +1,6 @@
 require 'spec_helper'
+require 'fog'
+require 'imgur'
 
 describe Upload do
 
@@ -38,21 +40,78 @@ describe Upload do
       Upload.create_for(user_id, logo, topic_id)
     end
 
+    shared_examples_for "upload" do
+      it "is valid" do
+        upload.original_filename.should == logo.original_filename
+        upload.filesize.should == logo.size
+        upload.width.should == 244
+        upload.height.should == 66
+      end
+    end
+
     context 'imgur' do
 
-      # TODO
+      before(:each) do
+        # Stub out Imgur entirely as it already is tested.
+        Imgur.stubs(:upload_file).returns({
+          url: "imgurlink",
+          filesize: logo.size,
+          width: 244,
+          height: 66
+        })
+      end
+
+      let(:upload) { Upload.create_on_imgur(user_id, logo, topic_id) }
+
+      it_behaves_like "upload"
+
+      it "works" do
+        upload.url.should == "imgurlink"
+      end
 
     end
 
     context 's3' do
 
-      # TODO
+      before(:each) do 
+        SiteSetting.stubs(:s3_upload_bucket).returns("bucket")
+        Fog.mock!
+      end
+
+      let(:upload) { Upload.create_on_s3(user_id, logo, topic_id) }
+
+      it_behaves_like "upload"
+
+      it "works" do
+        upload.url.should == "//bucket.s3-us-west-1.amazonaws.com/e8b1353813a7d091231f9a27f03566f123463fc1.png"
+      end
+
+      after(:each) do
+        Fog.unmock!
+      end
 
     end
 
     context 'local' do
 
-      # TODO
+      before(:each) do
+        # prevent the tests from creating directories & files...
+        FileUtils.stubs(:mkdir_p)
+        File.stubs(:open)
+      end
+
+      let(:upload) do
+        # The Time needs to be frozen as it is used to generate a clean & unique name
+        Timecop.freeze(Time.new(2013, 2, 17, 0, 0, 0)) do
+          Upload.create_locally(user_id, logo, topic_id)
+        end        
+      end
+
+      it_behaves_like "upload"
+
+      it "works" do
+        upload.url.should match /\/uploads\/default\/[\d]+\/efaf7c3915fdfd3b.png/
+      end
 
     end