summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2018-04-07 09:17:59 +0000
committerKamil Trzciński <ayufan@ayufan.eu>2018-04-07 09:17:59 +0000
commitdd552d06f6e39d5e6138a33bd7c1bffb2d3dbb1d (patch)
treee2cf4b8714c7dbb2bfc08c34e21b14cd5f9fa4e5 /app/models
parent671e93dc38365f3b05cb3cfe719e64713196be31 (diff)
parentb38439a3ae3c7ea1675b7037e4882213bdc58fdf (diff)
downloadgitlab-ce-dd552d06f6e39d5e6138a33bd7c1bffb2d3dbb1d.tar.gz
Merge branch '31591-project-deploy-tokens-to-allow-permanent-access' into 'master'
Create Project Deploy Tokens to allow permanent access to repo and registry Closes #31591 See merge request gitlab-org/gitlab-ce!17894
Diffstat (limited to 'app/models')
-rw-r--r--app/models/deploy_token.rb61
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_deploy_token.rb8
3 files changed, 71 insertions, 0 deletions
diff --git a/app/models/deploy_token.rb b/app/models/deploy_token.rb
new file mode 100644
index 00000000000..fe726b156d4
--- /dev/null
+++ b/app/models/deploy_token.rb
@@ -0,0 +1,61 @@
+class DeployToken < ActiveRecord::Base
+ include Expirable
+ include TokenAuthenticatable
+ add_authentication_token_field :token
+
+ AVAILABLE_SCOPES = %i(read_repository read_registry).freeze
+
+ default_value_for(:expires_at) { Forever.date }
+
+ has_many :project_deploy_tokens, inverse_of: :deploy_token
+ has_many :projects, through: :project_deploy_tokens
+
+ validate :ensure_at_least_one_scope
+ before_save :ensure_token
+
+ accepts_nested_attributes_for :project_deploy_tokens
+
+ scope :active, -> { where("revoked = false AND expires_at >= NOW()") }
+
+ def revoke!
+ update!(revoked: true)
+ end
+
+ def active?
+ !revoked
+ end
+
+ def scopes
+ AVAILABLE_SCOPES.select { |token_scope| read_attribute(token_scope) }
+ end
+
+ def username
+ "gitlab+deploy-token-#{id}"
+ end
+
+ def has_access_to?(requested_project)
+ project == requested_project
+ end
+
+ # This is temporal. Currently we limit DeployToken
+ # to a single project, later we're going to extend
+ # that to be for multiple projects and namespaces.
+ def project
+ projects.first
+ end
+
+ def expires_at
+ expires_at = read_attribute(:expires_at)
+ expires_at != Forever.date ? expires_at : nil
+ end
+
+ def expires_at=(value)
+ write_attribute(:expires_at, value.presence || Forever.date)
+ end
+
+ private
+
+ def ensure_at_least_one_scope
+ errors.add(:base, "Scopes can't be blank") unless read_repository || read_registry
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index 96907f3b23d..3f805dd1fc9 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -222,6 +222,8 @@ class Project < ActiveRecord::Base
has_many :environments
has_many :deployments
has_many :pipeline_schedules, class_name: 'Ci::PipelineSchedule'
+ has_many :project_deploy_tokens
+ has_many :deploy_tokens, through: :project_deploy_tokens
has_many :active_runners, -> { active }, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
diff --git a/app/models/project_deploy_token.rb b/app/models/project_deploy_token.rb
new file mode 100644
index 00000000000..ab4482f0c0b
--- /dev/null
+++ b/app/models/project_deploy_token.rb
@@ -0,0 +1,8 @@
+class ProjectDeployToken < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :deploy_token, inverse_of: :project_deploy_tokens
+
+ validates :deploy_token, presence: true
+ validates :project, presence: true
+ validates :deploy_token_id, uniqueness: { scope: [:project_id] }
+end