summaryrefslogtreecommitdiff
path: root/app/models/jira_connect/public_key.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/jira_connect/public_key.rb')
-rw-r--r--app/models/jira_connect/public_key.rb48
1 files changed, 48 insertions, 0 deletions
diff --git a/app/models/jira_connect/public_key.rb b/app/models/jira_connect/public_key.rb
new file mode 100644
index 00000000000..8959884861b
--- /dev/null
+++ b/app/models/jira_connect/public_key.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module JiraConnect
+ class PublicKey
+ # Public keys are created with JWT tokens via JiraConnect::CreateAsymmetricJwtService
+ # They need to be available for third party applications to verify the token.
+ # This should happen right after the application received the token so public keys
+ # only need to exist for a few minutes.
+ REDIS_EXPIRY_TIME = 5.minutes.to_i.freeze
+
+ attr_reader :key, :uuid
+
+ def self.create!(key:)
+ new(key: key, uuid: Gitlab::UUID.v5(SecureRandom.hex)).save!
+ end
+
+ def self.find(uuid)
+ Gitlab::Redis::SharedState.with do |redis|
+ key = redis.get(redis_key(uuid))
+
+ raise ActiveRecord::RecordNotFound if key.nil?
+
+ new(key: key, uuid: uuid)
+ end
+ end
+
+ def initialize(key:, uuid:)
+ key = OpenSSL::PKey.read(key) unless key.is_a?(OpenSSL::PKey::RSA)
+
+ @key = key.to_s
+ @uuid = uuid
+ rescue OpenSSL::PKey::PKeyError
+ raise ArgumentError, 'Invalid public key'
+ end
+
+ def save!
+ Gitlab::Redis::SharedState.with do |redis|
+ redis.set(self.class.redis_key(uuid), key, ex: REDIS_EXPIRY_TIME)
+ end
+
+ self
+ end
+
+ def self.redis_key(uuid)
+ "JiraConnect:public_key:uuid=#{uuid}"
+ end
+ end
+end