diff options
author | Ash McKenzie <amckenzie@gitlab.com> | 2018-07-31 21:01:49 +1000 |
---|---|---|
committer | Ash McKenzie <amckenzie@gitlab.com> | 2018-08-01 10:12:04 +1000 |
commit | 2f733baacdf5d0dca98276cc9b6e895097d5e8d2 (patch) | |
tree | 0db1256260f546cc13f01b4025e0fa045f32f9d1 | |
parent | cda96eb70992cc80d0dde8195df57d7b5c4a1429 (diff) | |
download | gitlab-shell-2f733baacdf5d0dca98276cc9b6e895097d5e8d2.tar.gz |
New Actor::Base, Actor::Key and Actor::User
-rw-r--r-- | lib/actor.rb | 18 | ||||
-rw-r--r-- | lib/actor/base.rb | 50 | ||||
-rw-r--r-- | lib/actor/key.rb | 29 | ||||
-rw-r--r-- | lib/actor/user.rb | 19 | ||||
-rw-r--r-- | spec/actor/base_spec.rb | 28 | ||||
-rw-r--r-- | spec/actor/key_spec.rb | 80 | ||||
-rw-r--r-- | spec/actor/user_spec.rb | 62 | ||||
-rw-r--r-- | spec/actor_spec.rb | 28 |
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 |