Create dummy users for new api tokens
This commit is contained in:
parent
74d7bb0156
commit
2ceea32cc4
@ -24,10 +24,10 @@ class UserDecorator < ApplicationDecorator
|
||||
private
|
||||
|
||||
def wrap_with_link(html)
|
||||
if id
|
||||
h.link_to html, h.profile_path(model), title: nickname
|
||||
else
|
||||
if dummy
|
||||
html
|
||||
else
|
||||
h.link_to html, h.profile_path(model), title: nickname
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4,43 +4,31 @@ class AsciicastParams
|
||||
meta = JSON.parse(params[:meta].read)
|
||||
|
||||
attributes = {
|
||||
stdout_data: params[:stdout],
|
||||
stdout_timing: params[:stdout_timing],
|
||||
command: meta['command'],
|
||||
duration: meta['duration'],
|
||||
shell: meta['shell'],
|
||||
stdin_data: params[:stdin],
|
||||
stdin_timing: params[:stdin_timing],
|
||||
username: meta['username'],
|
||||
duration: meta['duration'],
|
||||
title: meta['title'],
|
||||
command: meta['command'],
|
||||
shell: meta['shell'],
|
||||
terminal_lines: meta['term']['lines'],
|
||||
stdout_data: params[:stdout],
|
||||
stdout_timing: params[:stdout_timing],
|
||||
terminal_columns: meta['term']['columns'],
|
||||
terminal_lines: meta['term']['lines'],
|
||||
terminal_type: meta['term']['type'],
|
||||
title: meta['title'],
|
||||
user: get_user(meta)
|
||||
}
|
||||
|
||||
if meta['uname']
|
||||
if meta['uname'] # old client, with useless, random user_agent
|
||||
attributes[:uname] = meta['uname']
|
||||
else
|
||||
attributes[:user_agent] = user_agent
|
||||
end
|
||||
|
||||
assign_user_or_token(attributes, meta)
|
||||
|
||||
attributes
|
||||
end
|
||||
|
||||
def self.assign_user_or_token(attributes, meta)
|
||||
token = meta['user_token']
|
||||
|
||||
if token.present?
|
||||
api_token = ApiToken.find_by_token(token)
|
||||
|
||||
if api_token
|
||||
attributes[:user_id] = api_token.user_id
|
||||
else
|
||||
attributes[:api_token] = token
|
||||
end
|
||||
end
|
||||
def self.get_user(attributes)
|
||||
User.for_api_token(attributes['user_token'], attributes['username'])
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -10,7 +10,9 @@ class User < ActiveRecord::Base
|
||||
|
||||
attr_accessible :nickname, :email, :name
|
||||
|
||||
validates :nickname, :email, presence: true, uniqueness: true
|
||||
validates :nickname, presence: true
|
||||
validates :nickname, uniqueness: { scope: :dummy }, unless: :dummy
|
||||
validates :email, presence: true, uniqueness: true, unless: :dummy
|
||||
|
||||
before_create :generate_auth_token
|
||||
|
||||
@ -22,6 +24,26 @@ class User < ActiveRecord::Base
|
||||
where(email: email).first
|
||||
end
|
||||
|
||||
def self.for_api_token(token, username)
|
||||
return nil if token.blank?
|
||||
|
||||
user = User.joins(:api_tokens).where('api_tokens.token' => token).first
|
||||
user ? user : create_user_with_token(token, username)
|
||||
end
|
||||
|
||||
def self.create_user_with_token(token, username)
|
||||
username = 'anonymous' if username.blank?
|
||||
|
||||
transaction do |tx|
|
||||
user = User.new
|
||||
user.dummy = true
|
||||
user.nickname = username
|
||||
user.save!
|
||||
user.add_api_token(token)
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
def self.generate_auth_token
|
||||
SecureRandom.urlsafe_base64
|
||||
end
|
||||
|
6
db/migrate/20140211152727_add_dummy_to_users.rb
Normal file
6
db/migrate/20140211152727_add_dummy_to_users.rb
Normal file
@ -0,0 +1,6 @@
|
||||
class AddDummyToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :dummy, :boolean, default: false, null: false
|
||||
add_index :users, :dummy
|
||||
end
|
||||
end
|
10
db/schema.rb
10
db/schema.rb
@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20140210153648) do
|
||||
ActiveRecord::Schema.define(version: 20140211152727) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@ -91,13 +91,15 @@ ActiveRecord::Schema.define(version: 20140210153648) do
|
||||
t.string "email"
|
||||
t.string "name"
|
||||
t.string "avatar_url"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "nickname", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "nickname", null: false
|
||||
t.string "auth_token"
|
||||
t.boolean "dummy", default: false, null: false
|
||||
end
|
||||
|
||||
add_index "users", ["auth_token"], name: "index_users_on_auth_token", using: :btree
|
||||
add_index "users", ["dummy"], name: "index_users_on_dummy", using: :btree
|
||||
add_index "users", ["email"], name: "index_users_on_email", using: :btree
|
||||
add_index "users", ["nickname"], name: "index_users_on_nickname", using: :btree
|
||||
add_index "users", ["provider", "uid"], name: "index_users_on_provider_and_uid", unique: true, using: :btree
|
||||
|
@ -13,9 +13,9 @@ describe UserDecorator do
|
||||
allow(h).to receive(:profile_path).with(user) { '/path' }
|
||||
end
|
||||
|
||||
context "when user has id" do
|
||||
context "when user is real" do
|
||||
before do
|
||||
user.id = 1
|
||||
user.dummy = false
|
||||
end
|
||||
|
||||
it "is a nickname link to user's profile" do
|
||||
@ -23,9 +23,9 @@ describe UserDecorator do
|
||||
end
|
||||
end
|
||||
|
||||
context "when user has no id" do
|
||||
context "when user is dummy" do
|
||||
before do
|
||||
user.id = nil
|
||||
user.dummy = true
|
||||
end
|
||||
|
||||
it "is user's nickname" do
|
||||
@ -44,9 +44,9 @@ describe UserDecorator do
|
||||
allow(decorator).to receive(:avatar_image_tag) { '<img ...>'.html_safe }
|
||||
end
|
||||
|
||||
context "when user has id" do
|
||||
context "when user is real" do
|
||||
before do
|
||||
user.id = 1
|
||||
user.dummy = false
|
||||
end
|
||||
|
||||
it "is an avatar link to user's profile" do
|
||||
@ -54,9 +54,9 @@ describe UserDecorator do
|
||||
end
|
||||
end
|
||||
|
||||
context "when user has no id" do
|
||||
context "when user is dummy" do
|
||||
before do
|
||||
user.id = nil
|
||||
user.dummy = true
|
||||
end
|
||||
|
||||
it "is user's avatar image" do
|
||||
|
@ -1,4 +1,5 @@
|
||||
require 'spec_helper'
|
||||
require 'stringio'
|
||||
|
||||
describe AsciicastParams do
|
||||
|
||||
@ -6,86 +7,60 @@ describe AsciicastParams do
|
||||
subject { described_class.build(input, user_agent) }
|
||||
|
||||
let(:input) { {
|
||||
meta: meta_file,
|
||||
meta: StringIO.new(meta.to_json),
|
||||
stdout: stdout_data_file,
|
||||
stdout_timing: stdout_timing_file
|
||||
stdout_timing: stdout_timing_file,
|
||||
} }
|
||||
|
||||
let(:user_agent) { 'asciinema/0.9.7' }
|
||||
|
||||
let(:stdout_data_file) { double('stdout_data_file') }
|
||||
let(:stdout_timing_file) { double('stdout_timing_file') }
|
||||
let(:now) { DateTime.new(2014) }
|
||||
|
||||
let(:required_attrs) { {
|
||||
stdout_data: stdout_data_file,
|
||||
stdout_timing: stdout_timing_file,
|
||||
let(:meta) { {
|
||||
command: '/bin/bash',
|
||||
duration: 11.146430015563965,
|
||||
shell: '/bin/zsh',
|
||||
term: { lines: 26, columns: 96, type: 'screen-256color' },
|
||||
title: 'bashing :)',
|
||||
user_token: 'f33e6188-f53c-11e2-abf4-84a6c827e88b',
|
||||
username: 'kill',
|
||||
} }
|
||||
|
||||
let(:user) { double('user') }
|
||||
|
||||
let(:expected_attrs) { {
|
||||
command: '/bin/bash',
|
||||
duration: 11.146430015563965,
|
||||
shell: '/bin/zsh',
|
||||
stdin_data: nil,
|
||||
stdin_timing: nil,
|
||||
username: 'kill',
|
||||
duration: 11.146430015563965,
|
||||
title: 'bashing :)',
|
||||
command: '/bin/bash',
|
||||
shell: '/bin/zsh',
|
||||
stdout_data: stdout_data_file,
|
||||
stdout_timing: stdout_timing_file,
|
||||
terminal_columns: 96,
|
||||
terminal_lines: 26,
|
||||
terminal_type: 'screen-256color',
|
||||
title: 'bashing :)',
|
||||
user: user,
|
||||
user_agent: 'asciinema/0.9.7',
|
||||
} }
|
||||
|
||||
let(:token) { 'f33e6188-f53c-11e2-abf4-84a6c827e88b' }
|
||||
|
||||
before do
|
||||
allow(DateTime).to receive(:now) { now }
|
||||
allow(User).to receive(:for_api_token).
|
||||
with('f33e6188-f53c-11e2-abf4-84a6c827e88b', 'kill') { user }
|
||||
end
|
||||
|
||||
it { should eq(expected_attrs) }
|
||||
|
||||
context "when uname given" do
|
||||
let(:meta_file) {
|
||||
fixture_file_upload(
|
||||
'spec/fixtures/meta-with-uname.json', 'application/json'
|
||||
)
|
||||
}
|
||||
|
||||
let(:expected_attrs) {
|
||||
required_attrs.merge(
|
||||
api_token: token,
|
||||
uname: 'Linux 3.9.9-302.fc19.x86_64 #1 SMP Sat Jul 6 13:41:07' +
|
||||
' UTC 2013 x86_64'
|
||||
)
|
||||
}
|
||||
|
||||
before do
|
||||
meta[:uname] = 'Linux 3.9.9-302.fc19.x86_64'
|
||||
expected_attrs[:uname] = 'Linux 3.9.9-302.fc19.x86_64'
|
||||
expected_attrs.delete(:user_agent)
|
||||
end
|
||||
|
||||
it { should eq(expected_attrs) }
|
||||
end
|
||||
|
||||
context "when no api_token given" do
|
||||
let(:meta_file) { fixture_file_upload('spec/fixtures/meta-no-token.json',
|
||||
'application/json') }
|
||||
let(:expected_attrs) { required_attrs }
|
||||
|
||||
it { should eq(expected_attrs) }
|
||||
end
|
||||
|
||||
context "when api_token given" do
|
||||
let(:meta_file) { fixture_file_upload('spec/fixtures/meta.json',
|
||||
'application/json') }
|
||||
|
||||
context "and user with this token exists" do
|
||||
let(:user) { create(:user) }
|
||||
let!(:api_token) { create(:api_token, token: token, user: user) }
|
||||
let(:expected_attrs) { required_attrs.merge(user_id: user.id) }
|
||||
|
||||
it { should eq(expected_attrs) }
|
||||
end
|
||||
|
||||
context "and user with this token doesn't exist" do
|
||||
let(:expected_attrs) { required_attrs.merge(api_token: token) }
|
||||
|
||||
it { should eq(expected_attrs) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -2,6 +2,10 @@ require 'spec_helper'
|
||||
|
||||
describe User do
|
||||
|
||||
it "is not dummy by default" do
|
||||
expect(described_class.new).to_not be_dummy
|
||||
end
|
||||
|
||||
it 'gets an auth_token upon creation' do
|
||||
attrs = attributes_for(:user)
|
||||
attrs.delete(:auth_token)
|
||||
@ -11,12 +15,58 @@ describe User do
|
||||
end
|
||||
|
||||
describe "#valid?" do
|
||||
before do
|
||||
create(:user)
|
||||
let!(:existing_user) { create(:user) }
|
||||
let(:user) { described_class.new }
|
||||
|
||||
it { should validate_presence_of(:nickname) }
|
||||
|
||||
context "when user is dummy" do
|
||||
before do
|
||||
user.dummy = true
|
||||
end
|
||||
|
||||
it "doesn't check for nickname uniqueness" do
|
||||
user.nickname = existing_user.nickname
|
||||
user.valid?
|
||||
expect(user.errors[:nickname]).to be_empty
|
||||
end
|
||||
|
||||
it "doesn't check for email presence" do
|
||||
user.email = nil
|
||||
user.valid?
|
||||
expect(user.errors[:email]).to be_empty
|
||||
end
|
||||
|
||||
it "doesn't check for email uniqueness" do
|
||||
user.email = existing_user.email
|
||||
user.valid?
|
||||
expect(user.errors[:email]).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
it { should validate_uniqueness_of(:nickname) }
|
||||
it { should validate_uniqueness_of(:email) }
|
||||
context "when user is real" do
|
||||
before do
|
||||
user.dummy = false
|
||||
end
|
||||
|
||||
it "checks for nickname uniqueness" do
|
||||
user.nickname = existing_user.nickname
|
||||
user.valid?
|
||||
expect(user.errors[:nickname]).to_not be_empty
|
||||
end
|
||||
|
||||
it "checks for email presence" do
|
||||
user.email = nil
|
||||
user.valid?
|
||||
expect(user.errors[:email]).to_not be_empty
|
||||
end
|
||||
|
||||
it "checks for email uniqueness" do
|
||||
user.email = existing_user.email
|
||||
user.valid?
|
||||
expect(user.errors[:email]).to_not be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.generate_auth_token' do
|
||||
@ -70,9 +120,74 @@ describe User do
|
||||
end
|
||||
end
|
||||
|
||||
describe '.for_api_token' do
|
||||
subject { described_class.for_api_token(token, username) }
|
||||
|
||||
let(:token) { 'f33e6188-f53c-11e2-abf4-84a6c827e88b' }
|
||||
let(:username) { 'somerandomguy' }
|
||||
|
||||
context "when token doesn't exist" do
|
||||
it "returns a persisted user record" do
|
||||
expect(subject.id).not_to be(nil)
|
||||
end
|
||||
|
||||
it "assigns given username to the user" do
|
||||
expect(subject.nickname).to eq(username)
|
||||
end
|
||||
|
||||
it "assigns given api token to the user" do
|
||||
expect(subject.api_tokens.first.token).to eq(token)
|
||||
end
|
||||
|
||||
context "and username is nil" do
|
||||
let(:username) { nil }
|
||||
|
||||
it "returns a persisted user record" do
|
||||
expect(subject.id).not_to be(nil)
|
||||
end
|
||||
|
||||
it "assigns 'anonymous' as username to the user" do
|
||||
expect(subject.nickname).to eq('anonymous')
|
||||
end
|
||||
end
|
||||
|
||||
context "and username is an empty string" do
|
||||
let(:username) { nil }
|
||||
|
||||
it "returns a persisted user record" do
|
||||
expect(subject.id).not_to be(nil)
|
||||
end
|
||||
|
||||
it "assigns 'anonymous' as username to the user" do
|
||||
expect(subject.nickname).to eq('anonymous')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when token already exists" do
|
||||
let!(:existing_token) { create(:api_token, token: token) }
|
||||
|
||||
it "returns a persisted user record" do
|
||||
expect(subject).to eq(existing_token.user)
|
||||
end
|
||||
end
|
||||
|
||||
context "when token is nil" do
|
||||
let(:token) { nil }
|
||||
|
||||
it { should be(nil) }
|
||||
end
|
||||
|
||||
context "when token is an empty string" do
|
||||
let(:token) { '' }
|
||||
|
||||
it { should be(nil) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#nickname=' do
|
||||
it 'strips the whitespace' do
|
||||
user = User.new(nickname: ' sickill ')
|
||||
user = described_class.new(nickname: ' sickill ')
|
||||
|
||||
expect(user.nickname).to eq('sickill')
|
||||
end
|
||||
@ -80,7 +195,7 @@ describe User do
|
||||
|
||||
describe '#email=' do
|
||||
it 'strips the whitespace' do
|
||||
user = User.new(email: ' foo@bar.com ')
|
||||
user = described_class.new(email: ' foo@bar.com ')
|
||||
|
||||
expect(user.email).to eq('foo@bar.com')
|
||||
end
|
||||
|
@ -1,13 +1,36 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "Asciicast upload" do
|
||||
it 'returns the URL to the uploaded asciicast' do
|
||||
post '/api/asciicasts', :asciicast => {
|
||||
:meta => fixture_file('meta.json', 'application/json'),
|
||||
:stdout => fixture_file('stdout', 'application/octet-stream'),
|
||||
:stdout_timing => fixture_file('stdout.time', 'application/octet-stream')
|
||||
}
|
||||
subject { response.body }
|
||||
|
||||
before do
|
||||
post '/api/asciicasts', asciicast: {
|
||||
meta: fixture_file(meta_filename, 'application/json'),
|
||||
stdout: fixture_file('stdout', 'application/octet-stream'),
|
||||
stdout_timing: fixture_file('stdout.time', 'application/octet-stream')
|
||||
}
|
||||
end
|
||||
|
||||
let(:meta_filename) { 'meta.json' }
|
||||
|
||||
it 'returns the URL to the uploaded asciicast' do
|
||||
expect(response.body).to eq(asciicast_url(Asciicast.last))
|
||||
end
|
||||
|
||||
context "when json includes uname (legacy)" do
|
||||
let(:meta_filename) { 'meta-with-uname.json' }
|
||||
|
||||
it 'returns the URL to the uploaded asciicast' do
|
||||
expect(response.body).to eq(asciicast_url(Asciicast.last))
|
||||
end
|
||||
end
|
||||
|
||||
context "when json doesn't include user_token (anonymous?)" do
|
||||
let(:meta_filename) { 'meta-no-token.json' }
|
||||
|
||||
it 'returns the URL to the uploaded asciicast' do
|
||||
expect(response.body).to eq(asciicast_url(Asciicast.last))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user