Class: Shipit::User

Inherits:
Record
  • Object
show all
Defined in:
app/models/shipit/user.rb

Constant Summary collapse

DEFAULT_AVATAR =
URI.parse('https://avatars.githubusercontent.com/u/583231?')
GITHUB_TOKEN_FORMAT =
/^gh[a-z]_/

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Record

serializer_class

Class Method Details

.create_from_github(github_user) ⇒ Object



56
57
58
# File 'app/models/shipit/user.rb', line 56

def self.create_from_github(github_user)
  create(github_user:)
end

.find_from_github(github_user) ⇒ Object



50
51
52
53
54
# File 'app/models/shipit/user.rb', line 50

def self.find_from_github(github_user)
  return unless github_user.id

  find_by(github_id: github_user.id)
end

.find_or_create_author_from_github_commit(github_commit) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'app/models/shipit/user.rb', line 34

def self.find_or_create_author_from_github_commit(github_commit)
  if (match_info = github_commit.commit.message.match(/^#{MergeRequest::MERGE_REQUEST_FIELD}: ([\w\-.]+)$/))
    begin
      return find_or_create_by_login!(match_info[1])
    rescue Octokit::NotFound
      # Corner case where the merge-requested-by user cannot be found (renamed/deleted).
      # In this case we carry on and search for the commit author
    end
  end
  find_or_create_from_github(github_commit.author.presence || github_commit.commit.author.presence)
end

.find_or_create_by_login!(login) ⇒ Object



22
23
24
25
26
27
28
# File 'app/models/shipit/user.rb', line 22

def self.find_or_create_by_login!()
  find_or_create_by!(login:) do |user|
    # Users are global, any app can be used
    # This will not work for users that only exist in an Enterprise install
    user.github_user = Shipit.github.api.user()
  end
end

.find_or_create_committer_from_github_commit(github_commit) ⇒ Object



30
31
32
# File 'app/models/shipit/user.rb', line 30

def self.find_or_create_committer_from_github_commit(github_commit)
  find_or_create_from_github(github_commit.committer.presence || github_commit.commit.committer.presence)
end

.find_or_create_from_github(github_user) ⇒ Object



46
47
48
# File 'app/models/shipit/user.rb', line 46

def self.find_or_create_from_github(github_user)
  find_from_github(github_user) || create_from_github(github_user)
end

.refresh_shard(shard_index, shards_count) ⇒ Object



60
61
62
63
64
# File 'app/models/shipit/user.rb', line 60

def self.refresh_shard(shard_index, shards_count)
  where.not(login: nil).where('id % ? = ?', shards_count, shard_index).find_each do |user|
    RefreshGithubUserJob.perform_later(user)
  end
end

Instance Method Details

#authorized?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'app/models/shipit/user.rb', line 80

def authorized?
  @authorized ||= Shipit.github_teams.empty? || teams.where(id: Shipit.github_teams.map(&:id)).exists?
end

#avatar_uriObject



123
124
125
126
127
# File 'app/models/shipit/user.rb', line 123

def avatar_uri
  URI.parse(avatar_url)
rescue URI::InvalidURIError
  DEFAULT_AVATAR.dup
end

#github_apiObject



66
67
68
69
70
# File 'app/models/shipit/user.rb', line 66

def github_api
  return Shipit.github.api unless github_access_token

  @github_api ||= Shipit.github.new_client(access_token: github_access_token)
end

#github_user=(github_user) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'app/models/shipit/user.rb', line 106

def github_user=(github_user)
  return unless github_user

  if github_user.name.nil? && github_user.rels && github_user.rels[:self]
    github_user = github_user.rels[:self].get.data
  end

  assign_attributes(
    github_id: github_user.id,
    name: github_user.name || github_user., # Name is not mandatory on GitHub
    email: appropriate_email_for(github_user),
    login: github_user.,
    avatar_url: github_user.avatar_url,
    api_url: github_user.url
  )
end

#identifiers_for_pingObject



72
73
74
# File 'app/models/shipit/user.rb', line 72

def identifiers_for_ping
  { github_id:, name:, email:, github_login:  }
end

#logged_in?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'app/models/shipit/user.rb', line 76

def logged_in?
  true
end

#refresh_from_github!Object



96
97
98
99
100
101
102
103
104
# File 'app/models/shipit/user.rb', line 96

def refresh_from_github!
  # Users are global, any app can be used
  # This will not work for users that only exist in an Enterprise install
  update!(github_user: Shipit.github.api.user(github_id))
rescue Octokit::NotFound
  identify_renamed_user!
rescue Octokit::Forbidden
  Rails.logger.info("User #{name}, github_id #{github_id} has forbidden access to their GitHub, likely deleted.")
end

#repositories_contributed_toObject



84
85
86
87
88
# File 'app/models/shipit/user.rb', line 84

def repositories_contributed_to
  return [] unless id

  Stack.where(id: stacks_contributed_to).distinct.pluck(:repository_id)
end

#requires_fresh_login?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'app/models/shipit/user.rb', line 132

def requires_fresh_login?
  github_access_token.present? && !github_access_token.match(GITHUB_TOKEN_FORMAT)
end

#stacks_contributed_toObject



90
91
92
93
94
# File 'app/models/shipit/user.rb', line 90

def stacks_contributed_to
  return [] unless id

  Commit.where('author_id = :id or committer_id = :id', id:).distinct.pluck(:stack_id)
end