get basic 2 way integration going

get basic 2 way integration going

From b0fe905ba236699b904673d2cdd69ce4883bbb2b Mon Sep 17 00:00:00 2001
From: Sam <sam.saffron@gmail.com>
Date: Fri, 16 Nov 2018 15:40:27 +1100
Subject: [PATCH] get basic 2 way integration going


diff --git a/config/settings.yml b/config/settings.yml
index 4aa341b..660937b 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -1,4 +1,5 @@
 plugins:
+  code_review_enabled: false
   code_review_github_repo: ""
   code_review_pending_category_id:
     hidden: true
diff --git a/jobs/import_commits.rb b/jobs/import_commits.rb
index 78986a3..8188557 100644
--- a/jobs/import_commits.rb
+++ b/jobs/import_commits.rb
@@ -5,12 +5,19 @@ module Jobs
 
     def execute(args = nil)
 
+      return unless SiteSetting.code_review_enabled && SiteSetting.code_review_github_repo.present?
+
       DiscourseCodeReview.commits_since.each do |commit|
 
         title = commit[:subject]
         raw = commit[:body] + "\n\n```diff\n#{commit[:diff]}\n```"
 
-        user = ensure_user(email: commit[:email], name: commit[:name])
+        user = ensure_user(
+          email: commit[:email],
+          name: commit[:name],
+          github_login: commit[:author_login],
+          github_id: commit[:author_id]
+        )
 
         if !TopicCustomField.exists?(name: DiscourseCodeReview::CommitHash, value: commit[:hash])
 
@@ -19,7 +26,8 @@ module Jobs
             raw: raw,
             title: title,
             skip_validations: true,
-            created_at: commit[:date]
+            created_at: commit[:date],
+            category: SiteSetting.code_review_pending_category_id
           )
 
           TopicCustomField.create!(
@@ -32,12 +40,28 @@ module Jobs
         end
       end
 
+      import_comments
     end
 
-    def ensure_user(email:, name:)
-      user = User.find_by_email(email)
+    def ensure_user(email:, name:, github_login: nil, github_id: nil)
+      user = nil
+
+      if github_id
+        if user_id = UserCustomField.where(name: DiscourseCodeReview::GithubId, value: github_id).pluck(:user_id).first
+          user = User.find_by(id: user_id)
+        end
+      end
+
+      if !user && github_login
+        if user_id = UserCustomField.where(name: DiscourseCodeReview::GithubLogin, value: github_login).pluck(:user_id).first
+          user = User.find_by(id: user_id)
+        end
+      end
+
+      user ||= User.find_by_email(email)
+
       if !user
-        username = UserNameSuggester.sanitize_username(name)
+        username = UserNameSuggester.sanitize_username(github_login || name)
         begin
           user = User.create!(
             email: email,
@@ -47,12 +71,32 @@ module Jobs
           )
         end
       end
+
+      if github_login
+
+        rel = UserCustomField.where(name: DiscourseCodeReview::GithubLogin, value: github_login)
+        existing = rel.pluck(:user_id)
+
+        if existing != [user.id]
+          rel.destroy_all
+          UserCustomField.create!(name: DiscourseCodeReview::GithubLogin, value: github_login, user_id: user.id)
+        end
+      end
+
+      if github_id
+
+        rel = UserCustomField.where(name: DiscourseCodeReview::GithubId, value: github_id)
+        existing = rel.pluck(:user_id)
+
+        if existing != [user.id]
+          rel.destroy_all
+          UserCustomField.create!(name: DiscourseCodeReview::GithubId, value: github_id, user_id: user.id)
+        end
+      end
       user
     end
 
     def import_comments
-      # 140 is a good page for Discourse :)
-      # for testing
       page = DiscourseCodeReview.current_comment_page
 
       while true
@@ -77,17 +121,16 @@ module Jobs
       # do we have the commit?
       if topic_id = TopicCustomField.where(name: DiscourseCodeReview::CommitHash, value: comment[:commit_hash]).pluck(:topic_id).first
         login = comment[:login] || "unknown"
-        user = ensure_user(email: "#{login}@fake.github.com", name: login)
+        user = ensure_user(email: "#{login}@fake.github.com", name: login, github_login: login)
 
-        post = PostCreator.create!(
+        PostCreator.create!(
           user,
           raw: comment[:body],
           skip_validations: true,
           created_at: comment[:created_at],
-          topic_id: topic_id
+          topic_id: topic_id,
+          custom_fields: { DiscourseCodeReview::GithubId => comment[:id] }
         )
-
-        PostCustomField.create!(post_id: post.id, name: DiscourseCodeReview::GithubId, value: comment[:id])
       end
     end
 
diff --git a/plugin.rb b/plugin.rb
index fb3dc76..43f446f 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -11,6 +11,54 @@ rescue LoadError
   gem 'octokit', '4.9.0'
 end
 
+enabled_site_setting :code_review_enabled
+
+require_dependency 'auth/github_authenticator'
+module HackGithubAuthenticator
+
+  def after_authenticate(auth_token, existing_account: nil)
+    result = super(auth_token, existing_account: existing_account)
+
+    if SiteSetting.code_review_enabled
+      if user_id = result.user&.id
+
+        token = auth_token.credentials.token
+
+        user = result.user
+        user.custom_fields[DiscourseCodeReview::UserToken] = token
+        user.custom_fields[DiscourseCodeReview::GithubId] = auth_token[:uid]
+        user.custom_fields[DiscourseCodeReview::GithubLogin] = auth_token.info.nickname
+        user.save_custom_fields
+
+      end
+    end
+
+    result
+  end
+
+  def register_middleware(omniauth)
+    scope = "user:email"
+
+    if SiteSetting.code_review_enabled && SiteSetting.code_review_github_repo.present?
+      scope = "user:email,repo"
+    end
+
+    scope = "user:email,repo"
+
+    omniauth.provider :github,
+           setup: lambda { |env|
+             strategy = env["omniauth.strategy"]
+              strategy.options[:client_id] = SiteSetting.github_client_id
+              strategy.options[:client_secret] = SiteSetting.github_client_secret
+           },
+           scope: scope
+  end
+end
+
+class ::Auth::GithubAuthenticator
+  prepend HackGithubAuthenticator
+end
+
 after_initialize do
 
   module ::DiscourseCodeReview
@@ -21,14 +69,16 @@ after_initialize do
       isolate_namespace DiscourseCodeReview
     end
 
+    UserToken = 'github user token'
     LastCommit = 'last commit'
     CommitHash = 'commit hash'
     GithubId = 'github id'
+    GithubLogin = 'github login'
     CommentPage = 'comment page'
 
     def self.last_commit
       PluginStore.get(DiscourseCodeReview::PluginName, LastCommit) ||
-        (self.last_commit = git('rev-parse HEAD~40'))
+        (self.last_commit = git('rev-parse HEAD~30'))
     end
 
     def self.last_commit=(v)
@@ -70,11 +120,28 @@ after_initialize do
     end
 
     def self.commits_since(hash = nil)
-
       git("pull")
-
       hash ||= last_commit
 
+      github_info = []
+
+      commits = git("log #{hash}.. --pretty=%H").split("\n").map { |x| x.strip }
+
+      commits.each_slice(30).each do |x|
+        commits = Octokit.commits(SiteSetting.code_review_github_repo, sha: x.first)
+        github_info.concat(commits)
+      end
+
+      lookup = {}
+      github_info.each do |commit|
+        lookup[commit.sha] = {
+          author_login: commit&.author&.login,
+          author_id: commit&.author&.id,
+          committer_login: commit&.committer&.login,
+          committer_id: commit&.committer&.id,
+        }
+      end
+
       # hash name email subject body
       format = %w{%H %aN %aE %s %B %at}.join(FEILD_END) << LINE_END
 
@@ -83,7 +150,8 @@ after_initialize do
       data.split(LINE_END).map do |line|
         fields = line.split(FEILD_END).map { |f| f.strip if f }
 
-        hash = fields[0]
+        hash = fields[0].strip
+
         diff = git("show --format=email #{hash}")
 
         abbrev = diff.length > MAX_DIFF_LENGTH
@@ -91,8 +159,10 @@ after_initialize do
           diff = diff[0..MAX_DIFF_LENGTH]
         end
 
+        github_data = lookup[hash] || {}
+
         {
-          hash: fields[0],
+          hash: hash,
           name: fields[1],
      

GitHub

1 Like