summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsh McKenzie <amckenzie@gitlab.com>2018-07-31 21:01:49 +1000
committerAsh McKenzie <amckenzie@gitlab.com>2018-08-01 10:12:04 +1000
commit2f733baacdf5d0dca98276cc9b6e895097d5e8d2 (patch)
tree0db1256260f546cc13f01b4025e0fa045f32f9d1
parentcda96eb70992cc80d0dde8195df57d7b5c4a1429 (diff)
downloadgitlab-shell-2f733baacdf5d0dca98276cc9b6e895097d5e8d2.tar.gz
New Actor::Base, Actor::Key and Actor::User
-rw-r--r--lib/actor.rb18
-rw-r--r--lib/actor/base.rb50
-rw-r--r--lib/actor/key.rb29
-rw-r--r--lib/actor/user.rb19
-rw-r--r--spec/actor/base_spec.rb28
-rw-r--r--spec/actor/key_spec.rb80
-rw-r--r--spec/actor/user_spec.rb62
-rw-r--r--spec/actor_spec.rb28
8 files changed, 314 insertions, 0 deletions
diff --git a/lib/actor.rb b/lib/actor.rb
new file mode 100644
index 0000000..eab1bc4
--- /dev/null
+++ b/lib/actor.rb
@@ -0,0 +1,18 @@
+require_relative 'actor/base'
+require_relative 'actor/key'
+require_relative 'actor/user'
+
+module Actor
+ class UnsupportedActorError < StandardError; end
+
+ def self.new_from(str, audit_usernames: false)
+ case str
+ when Key.id_regex
+ Key.from(str, audit_usernames: audit_usernames)
+ when User.id_regex
+ User.from(str, audit_usernames: audit_usernames)
+ else
+ raise UnsupportedActorError
+ end
+ end
+end
diff --git a/lib/actor/base.rb b/lib/actor/base.rb
new file mode 100644
index 0000000..76cc522
--- /dev/null
+++ b/lib/actor/base.rb
@@ -0,0 +1,50 @@
+module Actor
+ class Base
+ attr_reader :id
+
+ def initialize(id, audit_usernames: false)
+ @id = id
+ @audit_usernames = audit_usernames
+ end
+
+ def self.from(str, audit_usernames: false)
+ new(str.gsub(/#{identifier_prefix}-/, ''), audit_usernames: audit_usernames)
+ end
+
+ def self.identifier_key
+ raise NotImplementedError
+ end
+
+ def self.identifier_prefix
+ raise NotImplementedError
+ end
+
+ def self.id_regex
+ raise NotImplementedError
+ end
+
+ def username
+ raise NotImplementedError
+ end
+
+ def identifier
+ "#{self.class.identifier_prefix}-#{id}"
+ end
+
+ def log_username
+ audit_usernames? ? username : "#{klass_name.downcase} with identifier #{identifier}"
+ end
+
+ private
+
+ attr_reader :audit_usernames
+
+ def klass_name
+ self.class.to_s.split('::')[-1]
+ end
+
+ def audit_usernames?
+ audit_usernames
+ end
+ end
+end
diff --git a/lib/actor/key.rb b/lib/actor/key.rb
new file mode 100644
index 0000000..411ef15
--- /dev/null
+++ b/lib/actor/key.rb
@@ -0,0 +1,29 @@
+require_relative 'base'
+require_relative '../gitlab_net'
+
+module Actor
+ class Key < Base
+ ANONYMOUS_USER = 'Anonymous'.freeze
+
+ alias key_id id
+
+ def self.identifier_prefix
+ 'key'.freeze
+ end
+
+ def self.identifier_key
+ 'key_id'.freeze
+ end
+
+ def self.id_regex
+ /\Akey\-\d+\Z/
+ end
+
+ def username
+ @username ||= begin
+ user = GitlabNet.new.discover(key_id)
+ user ? "@#{user['username']}" : ANONYMOUS_USER
+ end
+ end
+ end
+end
diff --git a/lib/actor/user.rb b/lib/actor/user.rb
new file mode 100644
index 0000000..55ba7f1
--- /dev/null
+++ b/lib/actor/user.rb
@@ -0,0 +1,19 @@
+require_relative 'base'
+
+module Actor
+ class User < Base
+ alias username identifier
+
+ def self.identifier_prefix
+ 'user'.freeze
+ end
+
+ def self.identifier_key
+ 'user_id'.freeze
+ end
+
+ def self.id_regex
+ /\Auser\-\d+\Z/
+ end
+ end
+end
diff --git a/spec/actor/base_spec.rb b/spec/actor/base_spec.rb
new file mode 100644
index 0000000..26f899d
--- /dev/null
+++ b/spec/actor/base_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../spec_helper'
+require_relative '../../lib/actor/base'
+
+describe Actor::Base do
+ describe '.identifier_key' do
+ it 'raises a NotImplementedError exception' do
+ expect do
+ described_class.identifier_key
+ end.to raise_error(NotImplementedError)
+ end
+ end
+
+ describe '.identifier_prefix' do
+ it 'raises a NotImplementedError exception' do
+ expect do
+ described_class.identifier_prefix
+ end.to raise_error(NotImplementedError)
+ end
+ end
+
+ describe '.id_regex' do
+ it 'raises a NotImplementedError exception' do
+ expect do
+ described_class.id_regex
+ end.to raise_error(NotImplementedError)
+ end
+ end
+end
diff --git a/spec/actor/key_spec.rb b/spec/actor/key_spec.rb
new file mode 100644
index 0000000..3c13f76
--- /dev/null
+++ b/spec/actor/key_spec.rb
@@ -0,0 +1,80 @@
+require_relative '../spec_helper'
+require_relative '../../lib/actor/key'
+
+describe Actor::Key do
+ let(:key_id) { '1' }
+ let(:username) { 'testuser' }
+ let(:api) { double(GitlabNet) }
+
+ let(:discover_payload) { { 'username' => username } }
+ let(:audit_usernames) { nil }
+
+ before do
+ allow(GitlabNet).to receive(:new).and_return(api)
+ allow(api).to receive(:discover).with(key_id).and_return(discover_payload)
+ end
+
+ describe '.from' do
+ it 'returns an instance of Actor::Key' do
+ expect(described_class.from('key-1')).to be_a(Actor::Key)
+ end
+
+ it 'has a key_id == 1' do
+ expect(described_class.from('key-1').key_id).to eq '1'
+ end
+ end
+
+ describe '.identifier_prefix' do
+ it "returns 'key'" do
+ expect(described_class.identifier_prefix).to eql 'key'
+ end
+ end
+
+ describe '.identifier_key' do
+ it "returns 'key_id'" do
+ expect(described_class.identifier_key).to eql 'key_id'
+ end
+ end
+
+ subject { described_class.new(key_id, audit_usernames: audit_usernames) }
+
+ describe '#username' do
+ context 'with a valid user' do
+ it "returns '@testuser'" do
+ expect(subject.username).to eql '@testuser'
+ end
+ end
+
+ context 'without a valid user' do
+ let(:discover_payload) { nil }
+
+ it "returns 'Anonymous'" do
+ expect(subject.username).to eql 'Anonymous'
+ end
+ end
+ end
+
+ describe '#identifier' do
+ it "returns 'key-1'" do
+ expect(subject.identifier).to eql 'key-1'
+ end
+ end
+
+ describe '#log_username' do
+ context 'when audit_usernames is true' do
+ let(:audit_usernames) { true }
+
+ it "returns 'testuser'" do
+ expect(subject.log_username).to eql '@testuser'
+ end
+ end
+
+ context 'when audit_usernames is false' do
+ let(:audit_usernames) { false }
+
+ it "returns 'key with identifier key-1'" do
+ expect(subject.log_username).to eql 'key with identifier key-1'
+ end
+ end
+ end
+end
diff --git a/spec/actor/user_spec.rb b/spec/actor/user_spec.rb
new file mode 100644
index 0000000..311fe73
--- /dev/null
+++ b/spec/actor/user_spec.rb
@@ -0,0 +1,62 @@
+require_relative '../spec_helper'
+require_relative '../../lib/actor/user'
+
+describe Actor::User do
+ let(:user_id) { '1' }
+ let(:username) { 'testuser' }
+ let(:audit_usernames) { nil }
+
+ describe '.from' do
+ it 'returns an instance of Actor::User' do
+ expect(described_class.from('user-1')).to be_a(Actor::User)
+ end
+
+ it 'has an id == 1' do
+ expect(described_class.from('user-1').id).to eq '1'
+ end
+ end
+
+ describe '.identifier_prefix' do
+ it "returns 'user'" do
+ expect(described_class.identifier_prefix).to eql 'user'
+ end
+ end
+
+ describe '.identifier_key' do
+ it "returns 'user_id'" do
+ expect(described_class.identifier_key).to eql 'user_id'
+ end
+ end
+
+ subject { described_class.new(user_id, audit_usernames: audit_usernames) }
+
+ describe '#username' do
+ it "returns 'user-1'" do
+ expect(subject.username).to eql 'user-1'
+ end
+ end
+
+ describe '#identifier' do
+ it "returns 'user-1'" do
+ expect(subject.identifier).to eql 'user-1'
+ end
+ end
+
+ describe '#log_username' do
+ context 'when audit_usernames is true' do
+ let(:audit_usernames) { true }
+
+ it "returns 'user-1'" do
+ expect(subject.log_username).to eql 'user-1'
+ end
+ end
+
+ context 'when audit_usernames is false' do
+ let(:audit_usernames) { false }
+
+ it "returns 'user with identifier user-1'" do
+ expect(subject.log_username).to eql 'user with identifier user-1'
+ end
+ end
+ end
+end
diff --git a/spec/actor_spec.rb b/spec/actor_spec.rb
new file mode 100644
index 0000000..c88c405
--- /dev/null
+++ b/spec/actor_spec.rb
@@ -0,0 +1,28 @@
+require_relative 'spec_helper'
+require_relative '../lib/actor'
+
+describe Actor do
+ describe '.new_from' do
+ context 'for an unsupported Actor type' do
+ it 'raises a NotImplementedError exception' do
+ expect do
+ described_class.new_from('unsupported-1')
+ end.to raise_error(Actor::UnsupportedActorError)
+ end
+ end
+
+ context 'for a supported Actor type' do
+ context 'of Key' do
+ it 'returns an instance of Key' do
+ expect(described_class.new_from('key-1')).to be_a(Actor::Key)
+ end
+ end
+
+ context 'of User' do
+ it 'returns an instance of User' do
+ expect(described_class.new_from('user-1')).to be_a(Actor::User)
+ end
+ end
+ end
+ end
+end