├── github-plugin ├── src │ ├── main │ │ ├── resources │ │ │ ├── static │ │ │ │ ├── footer.html │ │ │ │ ├── header.html │ │ │ │ ├── images │ │ │ │ │ ├── done.png │ │ │ │ │ ├── failed.png │ │ │ │ │ ├── cancelled.png │ │ │ │ │ ├── spinner-24px.gif │ │ │ │ │ └── spinner-32px.gif │ │ │ │ ├── styles.html │ │ │ │ ├── scripts.html │ │ │ │ ├── css │ │ │ │ │ └── github-plugin.css │ │ │ │ ├── js │ │ │ │ │ ├── jquery.cookie.min.js │ │ │ │ │ ├── datatables │ │ │ │ │ │ └── license-bsd.txt │ │ │ │ │ └── jquery │ │ │ │ │ │ ├── jquery.hotkeys.js │ │ │ │ │ │ ├── jquery.color.js │ │ │ │ │ │ ├── jquery.table-hotkeys.js │ │ │ │ │ │ └── jquery.schedule.js │ │ │ │ ├── account.html │ │ │ │ ├── scope.html │ │ │ │ ├── pullrequests.html │ │ │ │ └── repositories.html │ │ │ └── Documentation │ │ │ │ └── about.md │ │ └── java │ │ │ └── com │ │ │ ├── googlesource │ │ │ └── gerrit │ │ │ │ └── plugins │ │ │ │ └── github │ │ │ │ ├── git │ │ │ │ ├── PullRequestImportType.java │ │ │ │ ├── JobCancelledException.java │ │ │ │ ├── GitJob.java │ │ │ │ ├── ProtectedBranchFoundException.java │ │ │ │ ├── MagicRefFoundException.java │ │ │ │ ├── QuotaEnforcedException.java │ │ │ │ ├── GitDestinationAlreadyExistsException.java │ │ │ │ ├── GitDestinationNotWritableException.java │ │ │ │ ├── GitException.java │ │ │ │ ├── BatchImporter.java │ │ │ │ ├── ImportStep.java │ │ │ │ ├── AbstractCloneJob.java │ │ │ │ ├── ErrorJob.java │ │ │ │ ├── JobExecutor.java │ │ │ │ ├── PullRequestImporter.java │ │ │ │ ├── GitCloneFailedException.java │ │ │ │ ├── GitHubUser.java │ │ │ │ ├── GitJobStatus.java │ │ │ │ ├── ProtectedBranchesCheckStep.java │ │ │ │ ├── MagicRefCheckStep.java │ │ │ │ ├── ReplicateProjectStep.java │ │ │ │ ├── QuotaCheckStep.java │ │ │ │ ├── ReplicationRemoteConfigBuilder.java │ │ │ │ └── GitImporter.java │ │ │ │ ├── wizard │ │ │ │ ├── WrappedResponse.java │ │ │ │ ├── VelocityController.java │ │ │ │ ├── JobStatusController.java │ │ │ │ ├── ControllerErrors.java │ │ │ │ ├── RepositoriesCloneCancelController.java │ │ │ │ ├── PullRequestImportStatusController.java │ │ │ │ ├── RepositoriesCloneStatusController.java │ │ │ │ ├── PullRequestImportController.java │ │ │ │ └── RepositoriesCloneController.java │ │ │ │ ├── GitHubURL.java │ │ │ │ ├── InvalidGitHubConfigException.java │ │ │ │ ├── GitHubURLProvider.java │ │ │ │ ├── replication │ │ │ │ ├── ReplicationStatusStore.java │ │ │ │ ├── GerritGsonProvider.java │ │ │ │ ├── RemoteSiteUser.java │ │ │ │ ├── ListProjectReplicationStatus.java │ │ │ │ ├── ReplicationStatusListener.java │ │ │ │ └── ReplicationStatusFlatFile.java │ │ │ │ ├── OnStartStop.java │ │ │ │ ├── notification │ │ │ │ ├── WebhookEventHandler.java │ │ │ │ ├── PingHandler.java │ │ │ │ └── PullRequestHandler.java │ │ │ │ ├── velocity │ │ │ │ └── PluginVelocityModel.java │ │ │ │ ├── group │ │ │ │ ├── GitHubGroup.java │ │ │ │ ├── CurrentUsernameProvider.java │ │ │ │ ├── GitHubTeamGroup.java │ │ │ │ ├── GitHubGroupMembership.java │ │ │ │ └── GitHubOrganisationGroup.java │ │ │ │ ├── GitHubTopMenu.java │ │ │ │ ├── GitHubOAuthServiceProvider.java │ │ │ │ ├── GuiceModule.java │ │ │ │ └── filters │ │ │ │ └── GitHubGroupCacheRefreshFilter.java │ │ │ └── google │ │ │ └── gerrit │ │ │ └── server │ │ │ └── account │ │ │ └── AccountImporter.java │ └── test │ │ └── java │ │ └── com │ │ └── googlesource │ │ └── gerrit │ │ └── plugins │ │ └── github │ │ └── FakeHttpSession.java ├── .gitignore ├── web │ ├── main.ts │ ├── tsconfig.json │ ├── eslint.config.js │ ├── BUILD │ └── gr-github-oauth-progress.ts ├── tsconfig.json ├── rollup.config.mjs ├── package.json ├── tsconfig-plugins-base.json └── BUILD ├── .gitignore ├── Jenkinsfile ├── BUILD ├── github-oauth ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ ├── googlesource │ │ │ └── gerrit │ │ │ │ └── plugins │ │ │ │ └── github │ │ │ │ ├── oauth │ │ │ │ ├── ScopeKey.java │ │ │ │ ├── UserScopedProvider.java │ │ │ │ ├── ScopedProvider.java │ │ │ │ ├── ConcurrentFileBasedConfigWriteException.java │ │ │ │ ├── OAuthTokenException.java │ │ │ │ ├── AuthenticatedLoginHttpRequest.java │ │ │ │ ├── GsonProvider.java │ │ │ │ ├── CipherException.java │ │ │ │ ├── GitHubLogoutServletResponse.java │ │ │ │ ├── VirtualDomainConfig.java │ │ │ │ ├── GitHubHttpConnector.java │ │ │ │ ├── AuthenticatedPathHttpRequest.java │ │ │ │ ├── OAuthGitWrappedResponse.java │ │ │ │ ├── CanonicalWebUrls.java │ │ │ │ ├── AuthenticatedHttpRequest.java │ │ │ │ ├── HttpSessionProvider.java │ │ │ │ ├── OAuthCache.java │ │ │ │ ├── PooledHttpClientProvider.java │ │ │ │ ├── IdentifiedUserGitHubLoginProvider.java │ │ │ │ └── PasswordGenerator.java │ │ │ │ └── groups │ │ │ │ └── OrganizationStructure.java │ │ │ └── google │ │ │ └── gerrit │ │ │ └── httpd │ │ │ └── XGerritAuth.java │ └── test │ │ └── java │ │ └── com │ │ └── googlesource │ │ └── gerrit │ │ └── plugins │ │ └── github │ │ └── oauth │ │ └── PasswordGeneratorTest.java └── BUILD ├── java_library_without_header_compilation.bzl └── external_plugin_deps.bzl /github-plugin/src/main/resources/static/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .project 3 | .classpath 4 | .settings 5 | .idea 6 | *.iml 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/images/done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GerritCodeReview/plugins_github/HEAD/github-plugin/src/main/resources/static/images/done.png -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/images/failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GerritCodeReview/plugins_github/HEAD/github-plugin/src/main/resources/static/images/failed.png -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/images/cancelled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GerritCodeReview/plugins_github/HEAD/github-plugin/src/main/resources/static/images/cancelled.png -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/images/spinner-24px.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GerritCodeReview/plugins_github/HEAD/github-plugin/src/main/resources/static/images/spinner-24px.gif -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/images/spinner-32px.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GerritCodeReview/plugins_github/HEAD/github-plugin/src/main/resources/static/images/spinner-32px.gif -------------------------------------------------------------------------------- /github-plugin/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.classpath 3 | /.project 4 | /.settings/org.maven.ide.eclipse.prefs 5 | /.settings/org.eclipse.m2e.core.prefs 6 | /node_modules 7 | yarn-error.log 8 | /.rollup.cache 9 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/styles.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pluginPipeline(formatCheckId: 'gerritforge:github-format-3852e64366bb37d13b8baf8af9b15cfd38eb9227', 2 | buildCheckId: 'gerritforge:github-3852e64366bb37d13b8baf8af9b15cfd38eb9227', 3 | gjfVersion: '1.22.0') 4 | -------------------------------------------------------------------------------- /github-plugin/web/main.ts: -------------------------------------------------------------------------------- 1 | import '@gerritcodereview/typescript-api/gerrit'; 2 | import './gr-github-oauth-progress'; 3 | 4 | window.Gerrit.install(plugin => { 5 | plugin.registerCustomComponent( 6 | 'auth-link', 7 | 'gr-github-oauth-progress', 8 | { replace: true }); 9 | }); 10 | -------------------------------------------------------------------------------- /github-plugin/web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig-plugins-base.json", 3 | "compilerOptions": { 4 | "experimentalDecorators": true, 5 | /* outDir for IDE (overridden by Bazel rule arg) */ 6 | "outDir": "../../../../.ts-out/plugins/github-plugin/ui", 7 | }, 8 | "include": [ 9 | "**/*", 10 | ], 11 | } -------------------------------------------------------------------------------- /github-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | /* TODO: should be change to ./node_modules/@gerritcodereview/typescript-api/tsconfig-plugins-base.json' when NPM paclage is fixed */ 3 | "extends": "./tsconfig-plugins-base.json", 4 | "compilerOptions": { 5 | "rootDir": ".", 6 | "experimentalDecorators": true, 7 | "skipLibCheck": true, 8 | "outDir": "./target/web" 9 | }, 10 | } -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/scripts.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /github-plugin/web/eslint.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2022 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | const {defineConfig} = require('eslint/config'); 8 | 9 | // eslint-disable-next-line no-undef 10 | __plugindir = 'github/github-plugin/web'; 11 | 12 | const gerritEslint = require('../../eslint.config.js'); 13 | 14 | module.exports = defineConfig([ 15 | { 16 | extends: [gerritEslint], 17 | }, 18 | ]); -------------------------------------------------------------------------------- /github-plugin/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import terser from '@rollup/plugin-terser'; 2 | import { nodeResolve } from '@rollup/plugin-node-resolve'; 3 | 4 | export default { 5 | input: 'target/web/src/main/ts/main.js', 6 | treeshake: false, 7 | output: { 8 | format: 'iife', 9 | compact: true, 10 | file: 'target/classes/static/github-plugin.js', 11 | }, 12 | context: 'window', 13 | plugins: [ 14 | terser(), 15 | nodeResolve(), 16 | ], 17 | } -------------------------------------------------------------------------------- /github-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-oauth-ui", 3 | "description": "UI for the Gerrit GitHub OAuth plugin", 4 | "browser": true, 5 | "dependencies": { 6 | "@gerritcodereview/typescript-api": "^3.8.0", 7 | "@lit/ts-transformers": "^1.1.3", 8 | "@polymer/polymer": "^3.5.1", 9 | "@rollup/plugin-node-resolve": "^15.2.1", 10 | "@rollup/plugin-terser": "^0.4.3", 11 | "lit": "^2.8.0", 12 | "rollup": "^3.29.4", 13 | "typescript": "^4.9.5" 14 | }, 15 | "license": "Apache-2.0", 16 | "private": true, 17 | "scripts": { 18 | "build": "tsc && rollup -c" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | load("//tools/bzl:genrule2.bzl", "genrule2") 2 | 3 | genrule( 4 | name = "github", 5 | srcs = [ 6 | ":github-plugin", 7 | ":github-oauth", 8 | ], 9 | outs = ["github.zip"], 10 | cmd = "zip -o $@ $(SRCS)", 11 | ) 12 | 13 | genrule( 14 | name = "github-oauth", 15 | srcs = ["//plugins/github/github-oauth:github-oauth_deploy.jar"], 16 | outs = ["github-oauth.jar"], 17 | cmd = "cp $< $@", 18 | ) 19 | 20 | genrule( 21 | name = "github-plugin", 22 | srcs = ["//plugins/github/github-plugin"], 23 | outs = ["github-plugin.jar"], 24 | cmd = "cp $< $@", 25 | ) 26 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/css/github-plugin.css: -------------------------------------------------------------------------------- 1 | .repo-sync span.status { 2 | width: 24px; 3 | height: 24px; 4 | display: inline-block; 5 | } 6 | 7 | .repo-sync .sync { 8 | background-image: url("../images/spinner-24px.gif"); 9 | } 10 | 11 | .repo-sync .failed { 12 | background-image: url("../images/failed.png"); 13 | } 14 | 15 | .repo-sync .complete { 16 | background-image: url("../images/done.png"); 17 | } 18 | 19 | .repo-sync .cancelled { 20 | background-image: url("../images/cancelled.png"); 21 | } 22 | 23 | div.loading { 24 | margin-left: 30px; 25 | background-image: url("../images/spinner-32px.gif"); 26 | background-repeat: no-repeat; 27 | padding-left: 50px; 28 | width: 300px; 29 | height: 40px; 30 | display: inline-block; 31 | } 32 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/ScopeKey.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | public record ScopeKey(String name, String description, int sequence) {} 18 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportType.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | public enum PullRequestImportType { 17 | Commits, 18 | Squash 19 | } 20 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/JobCancelledException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | public class JobCancelledException extends Exception { 17 | private static final long serialVersionUID = 4358474273091335160L; 18 | } 19 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/UserScopedProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import com.google.gerrit.common.Nullable; 18 | import com.google.inject.Provider; 19 | 20 | public interface UserScopedProvider extends Provider { 21 | @Nullable 22 | T get(String username); 23 | } 24 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitJob.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | public interface GitJob extends Runnable { 17 | 18 | GitJobStatus getStatus(); 19 | 20 | int getIndex(); 21 | 22 | String getOrganisation(); 23 | 24 | String getRepository(); 25 | 26 | public abstract void cancel(); 27 | } 28 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/ProtectedBranchFoundException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.git; 16 | 17 | public class ProtectedBranchFoundException extends Exception { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | public ProtectedBranchFoundException(String msg) { 22 | super(msg); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/WrappedResponse.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import javax.servlet.http.HttpServletResponse; 17 | import javax.servlet.http.HttpServletResponseWrapper; 18 | 19 | public class WrappedResponse extends HttpServletResponseWrapper { 20 | 21 | public WrappedResponse(HttpServletResponse response) { 22 | super(response); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/ScopedProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import com.google.inject.Provider; 17 | import javax.servlet.http.HttpServletRequest; 18 | 19 | public interface ScopedProvider extends Provider { 20 | T get(HttpServletRequest request); 21 | 22 | void clear(HttpServletRequest request); 23 | 24 | HttpServletRequest getScopedRequest(); 25 | } 26 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/ConcurrentFileBasedConfigWriteException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import java.io.IOException; 17 | 18 | public class ConcurrentFileBasedConfigWriteException extends IOException { 19 | private static final long serialVersionUID = -4019991986934953417L; 20 | 21 | public ConcurrentFileBasedConfigWriteException(String message) { 22 | super(message); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /github-plugin/web/BUILD: -------------------------------------------------------------------------------- 1 | load("//tools/js:eslint.bzl", "plugin_eslint") 2 | load("//tools/bzl:js.bzl", "gerrit_js_bundle") 3 | load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") 4 | 5 | package_group( 6 | name = "visibility", 7 | packages = ["//plugins/github/github-plugin/..."], 8 | ) 9 | 10 | package(default_visibility = [":visibility"]) 11 | 12 | ts_config( 13 | name = "tsconfig", 14 | src = "tsconfig.json", 15 | deps = [ 16 | "//plugins:tsconfig-plugins-base.json", 17 | ], 18 | ) 19 | 20 | ts_project( 21 | name = "github-plugin-ts", 22 | srcs = glob( 23 | ["**/*.ts"], 24 | ), 25 | incremental = True, 26 | out_dir = "_bazel_ts_out", 27 | tsc = "//tools/node_tools:tsc-bin", 28 | tsconfig = ":tsconfig", 29 | deps = [ 30 | "@plugins_npm//@gerritcodereview/typescript-api", 31 | "@plugins_npm//lit", 32 | "@plugins_npm//rxjs", 33 | ], 34 | ) 35 | 36 | gerrit_js_bundle( 37 | name = "github-plugin", 38 | srcs = [":github-plugin-ts"], 39 | entry_point = "_bazel_ts_out/main.js", 40 | ) 41 | 42 | plugin_eslint() 43 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthTokenException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | public class OAuthTokenException extends Exception { 17 | public OAuthTokenException(String message, Exception e) { 18 | super(message, e); 19 | } 20 | 21 | public OAuthTokenException(String message) { 22 | super(message); 23 | } 24 | 25 | private static final long serialVersionUID = -2177841968402814337L; 26 | } 27 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/AuthenticatedLoginHttpRequest.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import javax.servlet.http.HttpServletRequest; 17 | 18 | public class AuthenticatedLoginHttpRequest extends AuthenticatedPathHttpRequest { 19 | 20 | public AuthenticatedLoginHttpRequest( 21 | HttpServletRequest request, String userHeader, String username) { 22 | super(request, "/login", userHeader, username); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /github-oauth/BUILD: -------------------------------------------------------------------------------- 1 | load("//tools/bzl:junit.bzl", "junit_tests") 2 | load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS", "PLUGIN_DEPS_NEVERLINK") 3 | 4 | java_binary( 5 | name = "github-oauth", 6 | main_class = "Dummy", 7 | visibility = ["//visibility:public"], 8 | runtime_deps = [":github-oauth-lib"], 9 | ) 10 | 11 | java_library( 12 | name = "github-oauth-lib", 13 | srcs = glob(["src/main/java/**/*.java"]), 14 | visibility = ["//visibility:public"], 15 | deps = PLUGIN_DEPS_NEVERLINK + [ 16 | "//lib:servlet-api", 17 | "@bridge-method-annotation//jar", 18 | "@bridge-method-injector//jar", 19 | "@commons-io//jar", 20 | "@github-api//jar", 21 | "@jackson-annotations//jar", 22 | "@jackson-core//jar", 23 | "@jackson-databind//jar", 24 | "@org-ow2-asm-commons//jar", 25 | "@org-ow2-asm-tree//jar", 26 | "@org-ow2-asm//jar", 27 | ], 28 | ) 29 | 30 | junit_tests( 31 | name = "github-oauth_tests", 32 | srcs = glob(["src/test/java/**/*.java"]), 33 | tags = ["github"], 34 | deps = PLUGIN_DEPS + [ 35 | ":github-oauth-lib", 36 | ], 37 | ) 38 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubURL.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github; 15 | 16 | import com.google.inject.BindingAnnotation; 17 | import java.lang.annotation.ElementType; 18 | import java.lang.annotation.Retention; 19 | import java.lang.annotation.RetentionPolicy; 20 | import java.lang.annotation.Target; 21 | 22 | @Target({ElementType.PARAMETER, ElementType.FIELD}) 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @BindingAnnotation 25 | public @interface GitHubURL {} 26 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/MagicRefFoundException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | public class MagicRefFoundException extends GitException { 17 | 18 | private static final long serialVersionUID = 1L; 19 | 20 | public MagicRefFoundException(String message) { 21 | super(message); 22 | } 23 | 24 | @Override 25 | public String getErrorDescription() { 26 | return String.format("Clash with Gerrit magic refs. %s", getMessage()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/InvalidGitHubConfigException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github; 15 | 16 | public class InvalidGitHubConfigException extends RuntimeException { 17 | private static final long serialVersionUID = 7006333621290095732L; 18 | 19 | public InvalidGitHubConfigException(String fromTo) { 20 | super( 21 | "Invalid configuration: invalid value " 22 | + fromTo 23 | + ": expected 'from-page.html => to-page.html"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/QuotaEnforcedException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | public class QuotaEnforcedException extends GitException { 17 | 18 | private static final long serialVersionUID = 1L; 19 | 20 | public QuotaEnforcedException(String message, Exception e) { 21 | super(message, e); 22 | } 23 | 24 | @Override 25 | public String getErrorDescription() { 26 | return String.format("Quota enforcing error. %s", getMessage()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubURLProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github; 15 | 16 | import com.google.inject.Inject; 17 | import com.google.inject.Provider; 18 | 19 | public class GitHubURLProvider implements Provider { 20 | 21 | private String gitHubUrl; 22 | 23 | @Inject 24 | public GitHubURLProvider(GitHubConfig gitHubConfig) { 25 | this.gitHubUrl = gitHubConfig.gitHubUrl; 26 | } 27 | 28 | @Override 29 | public String get() { 30 | return gitHubUrl; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java_library_without_header_compilation.bzl: -------------------------------------------------------------------------------- 1 | # See https://github.com/bazelbuild/bazel/issues/12837 2 | # for workaround suggestion for incompatibility between 3 | # Bazel Turbine processor and Lombok library. 4 | 5 | def _java_header_compilation_transition(settings, attr): 6 | _ignore = (settings, attr) 7 | return {"//command_line_option:java_header_compilation": "False"} 8 | 9 | java_header_compilation_transition = transition( 10 | implementation = _java_header_compilation_transition, 11 | inputs = [], 12 | outputs = ["//command_line_option:java_header_compilation"], 13 | ) 14 | 15 | def _java_library_without_header_compilation(ctx): 16 | return [java_common.merge([d[JavaInfo] for d in ctx.attr.dep])] 17 | 18 | java_library_without_header_compilation = rule( 19 | implementation = _java_library_without_header_compilation, 20 | attrs = { 21 | "dep": attr.label( 22 | providers = [JavaInfo], 23 | mandatory = True, 24 | cfg = java_header_compilation_transition, 25 | ), 26 | "_allowlist_function_transition": attr.label( 27 | default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 28 | ), 29 | }, 30 | ) 31 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/replication/ReplicationStatusStore.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.replication; 16 | 17 | import com.google.gerrit.entities.Project; 18 | import com.google.gson.JsonObject; 19 | import java.io.IOException; 20 | import java.util.List; 21 | 22 | public interface ReplicationStatusStore { 23 | 24 | public void set(Project.NameKey projectKey, String refKey, JsonObject statusEvent) 25 | throws IOException; 26 | 27 | public List list(Project.NameKey projectKey) throws IOException; 28 | } 29 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/replication/GerritGsonProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.replication; 16 | 17 | import com.google.gerrit.json.OutputFormat; 18 | import com.google.gson.Gson; 19 | import com.google.inject.Provider; 20 | import com.google.inject.Singleton; 21 | 22 | @Singleton 23 | public class GerritGsonProvider implements Provider { 24 | private final Gson gerritStyleGson = OutputFormat.JSON_COMPACT.newGson(); 25 | 26 | @Override 27 | public Gson get() { 28 | return gerritStyleGson; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitDestinationAlreadyExistsException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | public class GitDestinationAlreadyExistsException extends GitException { 17 | private static final long serialVersionUID = -6202681486717426148L; 18 | 19 | public GitDestinationAlreadyExistsException(String projectName) { 20 | super("Git project " + projectName + " already exists"); 21 | } 22 | 23 | @Override 24 | public String getErrorDescription() { 25 | return "A repository with the same name already exists"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/js/jquery.cookie.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Cookie plugin 3 | * 4 | * Copyright (c) 2006 Klaus Hartl (stilbuero.de) 5 | * Dual licensed under the MIT and GPL licenses: 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * http://www.gnu.org/licenses/gpl.html 8 | * 9 | */ 10 | jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};if(value===null){value='';options.expires=-1}var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toUTCString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000))}else{date=options.expires}expires='; expires='+date.toUTCString()}var path=options.path?'; path='+(options.path):'';var domain=options.domain?'; domain='+(options.domain):'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('')}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i { 25 | 26 | @Override 27 | public Gson get() { 28 | return new GsonBuilder() 29 | .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 30 | .create(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitDestinationNotWritableException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import java.io.File; 17 | 18 | public class GitDestinationNotWritableException extends GitException { 19 | private static final long serialVersionUID = -6486633812790391401L; 20 | 21 | public GitDestinationNotWritableException(File destDirectory) { 22 | super("Destination Git directory " + destDirectory + " is not writable"); 23 | } 24 | 25 | @Override 26 | public String getErrorDescription() { 27 | return "Output destination directory is not writeable"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import java.io.IOException; 17 | 18 | public class GitException extends IOException { 19 | private static final long serialVersionUID = -1180349547385523064L; 20 | 21 | public GitException() { 22 | super(); 23 | } 24 | 25 | public GitException(String message) { 26 | super(message); 27 | } 28 | 29 | public GitException(Throwable cause) { 30 | super(cause); 31 | } 32 | 33 | public GitException(String message, Throwable cause) { 34 | super(message, cause); 35 | } 36 | 37 | public String getErrorDescription() { 38 | return getMessage(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/VelocityController.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 18 | import java.io.IOException; 19 | import javax.servlet.ServletException; 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | 23 | public interface VelocityController { 24 | 25 | void doAction( 26 | IdentifiedUser user, 27 | GitHubLogin hubLogin, 28 | HttpServletRequest req, 29 | HttpServletResponse resp, 30 | ControllerErrors errors) 31 | throws ServletException, IOException; 32 | } 33 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/OnStartStop.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2012 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github; 16 | 17 | import com.google.gerrit.extensions.events.LifecycleListener; 18 | import com.google.inject.Inject; 19 | import com.google.inject.Singleton; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | @Singleton 24 | public class OnStartStop implements LifecycleListener { 25 | private static final Logger LOG = LoggerFactory.getLogger(OnStartStop.class); 26 | 27 | @Inject 28 | public OnStartStop() {} 29 | 30 | @Override 31 | public void start() { 32 | LOG.info("Starting up ..."); 33 | } 34 | 35 | @Override 36 | public void stop() { 37 | LOG.info("Stopping ..."); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/notification/WebhookEventHandler.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.notification; 16 | 17 | import java.io.IOException; 18 | import org.kohsuke.github.GHEvent; 19 | 20 | /** 21 | * Abstract interface to handler which is responsible for a specific github webhook event type. 22 | * 23 | *

Implementation classes must be named by the convention which {@link 24 | * WebhookServlet#getWebhookClassName(GHEvent)} defines. 25 | * 26 | * @param Type of payload. Must be consistent to the event type. 27 | * @return true if the event has been successfully processed 28 | */ 29 | interface WebhookEventHandler { 30 | Class getPayloadType(); 31 | 32 | boolean doAction(T payload) throws IOException; 33 | } 34 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/CipherException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import java.io.IOException; 17 | 18 | /** 19 | * Signals that a cipher exception has occurred. This class can be used to represent exception for 20 | * both encryption and decryption failures 21 | */ 22 | public class CipherException extends IOException { 23 | private static final long serialVersionUID = 1L; 24 | 25 | /** 26 | * Constructs a {@code CipherException} with the specified detail message and cause 27 | * 28 | * @param message The detail message of the failure 29 | * @param cause The cause of the failure 30 | */ 31 | public CipherException(String message, Exception cause) { 32 | super(message, cause); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogoutServletResponse.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import com.google.common.base.MoreObjects; 17 | import java.io.IOException; 18 | import javax.servlet.http.HttpServletResponse; 19 | import javax.servlet.http.HttpServletResponseWrapper; 20 | 21 | public class GitHubLogoutServletResponse extends HttpServletResponseWrapper { 22 | private String redirectUrl; 23 | 24 | public GitHubLogoutServletResponse(HttpServletResponse response, String redirectUrl) { 25 | super(response); 26 | this.redirectUrl = redirectUrl; 27 | } 28 | 29 | @Override 30 | public void sendRedirect(String location) throws IOException { 31 | super.sendRedirect(MoreObjects.firstNonNull(redirectUrl, location)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/Documentation/about.md: -------------------------------------------------------------------------------- 1 | 2 | This plugins allows to integrate Gerrit with external set of users configured 3 | on GitHub. 4 | It relies on the installation of the github-oauth Java library under the `$GERRIT_SITE/lib` 5 | in order filter all the HTTP requests through the GitHub OAuth 2.0 secure authentication. 6 | 7 | GitHub application registration 8 | ------------------------------- 9 | 10 | GitHub uses OAuth2 as protocol to allow external apps request authorization to private 11 | details in a user's GitHub account without getting their password. This is 12 | preferred over Basic Authentication because tokens can be limited to specific 13 | types of data, and can be revoked by users at any time. 14 | 15 | Site owners have to register their application before getting started. For 16 | more information see [GitHub application registration page](https://github.com/settings/applications/new). 17 | A registered OAuth application is assigned a unique `Client ID` and `Client 18 | Secret`. The `Client Secret` should never be shared. 19 | 20 | The Gerrit OAuth callback `/oauth` 21 | needs to be specified in the GitHub application registration to establish mutual 22 | trust between the two domains and exchange the authorization codes. The use of HTTPS 23 | for Gerrit is strongly recommended for keeping the secrets exchange confidential. 24 | 25 | `auth.httpHeader` is set to `GITHUB_USER` with this authentication method and `auth.type` 26 | must be set to HTTP. -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/js/datatables/license-bsd.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2010, Allan Jardine 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | * Neither the name of Allan Jardine nor SpryMedia UK may be used to endorse or promote products derived from this software without specific prior written permission. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/VirtualDomainConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import com.google.inject.Inject; 18 | import com.google.inject.Singleton; 19 | import java.util.List; 20 | import java.util.Optional; 21 | import java.util.SortedMap; 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | @Singleton 25 | public class VirtualDomainConfig { 26 | private final GitHubOAuthConfig oauthConfig; 27 | 28 | @Inject 29 | VirtualDomainConfig(GitHubOAuthConfig oauthConfig) { 30 | this.oauthConfig = oauthConfig; 31 | } 32 | 33 | public SortedMap> getScopes(HttpServletRequest req) { 34 | String serverName = req.getServerName(); 35 | return Optional.ofNullable(oauthConfig.virtualScopes.get(serverName)) 36 | .orElse(oauthConfig.scopes); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/google/gerrit/httpd/XGerritAuth.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.google.gerrit.httpd; 15 | 16 | import com.google.common.cache.Cache; 17 | import com.google.gerrit.httpd.WebSessionManager.Val; 18 | import com.google.inject.Inject; 19 | import com.google.inject.Singleton; 20 | import com.google.inject.name.Named; 21 | import javax.servlet.http.Cookie; 22 | 23 | @Singleton 24 | public class XGerritAuth { 25 | public static final String X_GERRIT_AUTH = "X-Gerrit-Auth"; 26 | private WebSessionManager manager; 27 | 28 | @Inject 29 | public XGerritAuth( 30 | WebSessionManagerFactory managerFactory, 31 | @Named(WebSessionManager.CACHE_NAME) Cache cache) { 32 | this.manager = managerFactory.create(cache); 33 | } 34 | 35 | public String getAuthValue(Cookie gerritCookie) { 36 | Val session = manager.get(new WebSessionManager.Key(gerritCookie.getValue())); 37 | return session.getAuth(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubHttpConnector.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import com.google.inject.Inject; 18 | import java.io.IOException; 19 | import java.net.HttpURLConnection; 20 | import java.net.URL; 21 | import org.kohsuke.github.HttpConnector; 22 | 23 | public class GitHubHttpConnector implements HttpConnector { 24 | 25 | private final GitHubOAuthConfig config; 26 | 27 | @Inject 28 | public GitHubHttpConnector(final GitHubOAuthConfig config) { 29 | this.config = config; 30 | } 31 | 32 | @Override 33 | public HttpURLConnection connect(URL url) throws IOException { 34 | HttpURLConnection huc = (HttpURLConnection) url.openConnection(); 35 | HttpURLConnection.setFollowRedirects(true); 36 | huc.setConnectTimeout((int) config.httpConnectionTimeout); 37 | huc.setReadTimeout((int) config.httpReadTimeout); 38 | return huc; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/replication/RemoteSiteUser.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.replication; 16 | 17 | import com.google.gerrit.server.CurrentUser; 18 | import com.google.gerrit.server.account.GroupMembership; 19 | import com.google.inject.Inject; 20 | import com.google.inject.assistedinject.Assisted; 21 | 22 | public class RemoteSiteUser extends CurrentUser { 23 | public interface Factory { 24 | RemoteSiteUser create(@Assisted GroupMembership authGroups); 25 | } 26 | 27 | private final GroupMembership effectiveGroups; 28 | 29 | @Inject 30 | RemoteSiteUser(@Assisted GroupMembership authGroups) { 31 | effectiveGroups = authGroups; 32 | } 33 | 34 | @Override 35 | public GroupMembership getEffectiveGroups() { 36 | return effectiveGroups; 37 | } 38 | 39 | @Override 40 | public Object getCacheKey() { 41 | return effectiveGroups.getKnownGroups(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/velocity/PluginVelocityModel.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.velocity; 15 | 16 | import com.google.inject.Inject; 17 | import com.google.inject.servlet.RequestScoped; 18 | import org.apache.velocity.VelocityContext; 19 | 20 | @RequestScoped 21 | public class PluginVelocityModel { 22 | 23 | private final VelocityContext context; 24 | 25 | public VelocityContext getContext() { 26 | return context; 27 | } 28 | 29 | @Inject 30 | public PluginVelocityModel(VelocityContext context) { 31 | this.context = context; 32 | } 33 | 34 | public Object get(String key) { 35 | return context.get(key); 36 | } 37 | 38 | public Object[] getKeys() { 39 | return context.getKeys(); 40 | } 41 | 42 | public Object put(String key, Object value) { 43 | return context.put(key, value); 44 | } 45 | 46 | public Object remove(String key) { 47 | return context.remove(key); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/GitHubGroup.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.group; 16 | 17 | import com.google.gerrit.entities.AccountGroup; 18 | import com.google.gerrit.entities.AccountGroup.UUID; 19 | import com.google.gerrit.entities.GroupDescription.Basic; 20 | 21 | public abstract class GitHubGroup implements Basic { 22 | public static final String UUID_PREFIX = "github:"; 23 | public static final String NAME_PREFIX = "github/"; 24 | 25 | protected final UUID groupUUID; 26 | 27 | protected final String url; 28 | 29 | GitHubGroup(UUID groupUUID, String url) { 30 | this.groupUUID = groupUUID; 31 | this.url = url; 32 | } 33 | 34 | @Override 35 | public String getEmailAddress() { 36 | return ""; 37 | } 38 | 39 | @Override 40 | public AccountGroup.UUID getGroupUUID() { 41 | return groupUUID; 42 | } 43 | 44 | @Override 45 | public String getUrl() { 46 | return url; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/CurrentUsernameProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.group; 16 | 17 | import com.google.gerrit.server.CurrentUser; 18 | import com.google.gerrit.server.IdentifiedUser; 19 | import com.google.inject.Inject; 20 | import com.google.inject.Provider; 21 | import java.util.Optional; 22 | 23 | public class CurrentUsernameProvider implements Provider { 24 | public static final String CURRENT_USERNAME = "CurrentUsername"; 25 | 26 | private final Provider userProvider; 27 | 28 | @Inject 29 | CurrentUsernameProvider(Provider userProvider) { 30 | this.userProvider = userProvider; 31 | } 32 | 33 | @Override 34 | public String get() { 35 | return Optional.ofNullable(userProvider.get()) 36 | .filter(CurrentUser::isIdentifiedUser) 37 | .map(CurrentUser::asIdentifiedUser) 38 | .flatMap(IdentifiedUser::getUserName) 39 | .orElse(null); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/notification/PingHandler.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.notification; 16 | 17 | import com.google.inject.Singleton; 18 | import java.io.IOException; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | /** 23 | * Handles ping event in github webhook. 24 | * 25 | * @see Ping Event 26 | */ 27 | @Singleton 28 | class PingHandler implements WebhookEventHandler { 29 | private static final Logger logger = LoggerFactory.getLogger(PingHandler.class); 30 | 31 | static class Ping { 32 | String zen; 33 | int hookId; 34 | 35 | @Override 36 | public String toString() { 37 | return "Ping [zen=" + zen + ", hookId=" + hookId + "]"; 38 | } 39 | } 40 | 41 | @Override 42 | public boolean doAction(Ping payload) throws IOException { 43 | logger.info(payload.toString()); 44 | return true; 45 | } 46 | 47 | @Override 48 | public Class getPayloadType() { 49 | return Ping.class; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/BatchImporter.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import java.util.Collection; 18 | import java.util.concurrent.ConcurrentHashMap; 19 | 20 | public class BatchImporter { 21 | 22 | private final ConcurrentHashMap jobs = new ConcurrentHashMap<>(); 23 | private final JobExecutor executor; 24 | protected final IdentifiedUser user; 25 | 26 | public BatchImporter(final JobExecutor executor, final IdentifiedUser user) { 27 | this.executor = executor; 28 | this.user = user; 29 | } 30 | 31 | public Collection getJobs() { 32 | return jobs.values(); 33 | } 34 | 35 | public void reset() { 36 | cancel(); 37 | jobs.clear(); 38 | } 39 | 40 | public void cancel() { 41 | for (GitJob job : jobs.values()) { 42 | job.cancel(); 43 | } 44 | } 45 | 46 | public synchronized void schedule(int idx, GitJob pullRequestImportJob) { 47 | jobs.put(Integer.valueOf(idx), pullRequestImportJob); 48 | executor.exec(pullRequestImportJob); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/replication/ListProjectReplicationStatus.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.replication; 16 | 17 | import com.google.gerrit.extensions.restapi.AuthException; 18 | import com.google.gerrit.extensions.restapi.BadRequestException; 19 | import com.google.gerrit.extensions.restapi.ResourceConflictException; 20 | import com.google.gerrit.extensions.restapi.Response; 21 | import com.google.gerrit.extensions.restapi.RestReadView; 22 | import com.google.gerrit.server.project.ProjectResource; 23 | import com.google.inject.Inject; 24 | 25 | public class ListProjectReplicationStatus implements RestReadView { 26 | private final ReplicationStatusStore statusStore; 27 | 28 | @Inject 29 | public ListProjectReplicationStatus(ReplicationStatusStore statusStore) { 30 | this.statusStore = statusStore; 31 | } 32 | 33 | @Override 34 | public Response apply(ProjectResource resource) 35 | throws AuthException, BadRequestException, ResourceConflictException, Exception { 36 | return Response.ok(statusStore.list(resource.getNameKey())); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/ImportStep.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.googlesource.gerrit.plugins.github.GitHubURL; 17 | import org.eclipse.jgit.lib.ProgressMonitor; 18 | 19 | public abstract class ImportStep { 20 | private final GitHubRepository gitHubRepository; 21 | 22 | public ImportStep( 23 | @GitHubURL String gitHubUrl, 24 | String organisation, 25 | String repository, 26 | GitHubRepository.Factory ghRepoFactory) { 27 | this.gitHubRepository = ghRepoFactory.create(organisation, repository); 28 | } 29 | 30 | protected String getSourceUri() { 31 | return gitHubRepository.getCloneUrl(); 32 | } 33 | 34 | public String getOrganisation() { 35 | return gitHubRepository.getOrganisation(); 36 | } 37 | 38 | public String getRepositoryName() { 39 | return gitHubRepository.getRepository(); 40 | } 41 | 42 | public GitHubRepository getRepository() { 43 | return gitHubRepository; 44 | } 45 | 46 | public abstract void doImport(ProgressMonitor progress) throws Exception; 47 | 48 | public abstract boolean rollback(); 49 | } 50 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/AbstractCloneJob.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.inject.ProvisionException; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | public class AbstractCloneJob { 21 | private static final Logger LOG = LoggerFactory.getLogger(AbstractCloneJob.class); 22 | 23 | public AbstractCloneJob() { 24 | super(); 25 | } 26 | 27 | protected String getErrorDescription(Throwable exception) { 28 | LOG.error("Job " + this + " FAILED", exception); 29 | if (exception instanceof ProtectedBranchFoundException) { 30 | return exception.getMessage(); 31 | } 32 | if (GitException.class.isAssignableFrom(exception.getClass())) { 33 | return ((GitException) exception).getErrorDescription(); 34 | } else if (ProvisionException.class.isAssignableFrom(exception.getClass())) { 35 | Throwable cause = exception.getCause(); 36 | if (cause != null) { 37 | return getErrorDescription(cause); 38 | } 39 | return "Import startup failed"; 40 | } else { 41 | return "Internal error"; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/JobStatusController.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.common.collect.Lists; 17 | import com.google.gson.Gson; 18 | import com.google.gson.stream.JsonWriter; 19 | import com.googlesource.gerrit.plugins.github.git.BatchImporter; 20 | import com.googlesource.gerrit.plugins.github.git.GitJob; 21 | import com.googlesource.gerrit.plugins.github.git.GitJobStatus; 22 | import java.io.IOException; 23 | import java.util.Collection; 24 | import java.util.List; 25 | import javax.servlet.http.HttpServletResponse; 26 | 27 | public class JobStatusController { 28 | 29 | public JobStatusController() { 30 | super(); 31 | } 32 | 33 | protected void respondWithJobStatusJson(HttpServletResponse resp, BatchImporter cloner) 34 | throws IOException { 35 | Collection jobs = cloner.getJobs(); 36 | List jobListStatus = Lists.newArrayList(); 37 | for (GitJob job : jobs) { 38 | jobListStatus.add(job.getStatus()); 39 | } 40 | try (JsonWriter writer = new JsonWriter(resp.getWriter())) { 41 | new Gson().toJson(jobListStatus, jobListStatus.getClass(), writer); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/js/jquery/jquery.hotkeys.js: -------------------------------------------------------------------------------- 1 | (function(a){this.version="(beta)(0.0.3)";this.all={};this.special_keys={27:"esc",9:"tab",32:"space",13:"return",8:"backspace",145:"scroll",20:"capslock",144:"numlock",19:"pause",45:"insert",36:"home",46:"del",35:"end",33:"pageup",34:"pagedown",37:"left",38:"up",39:"right",40:"down",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12"};this.shift_nums={"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":'"',",":"<",".":">","/":"?","\\":"|"};this.add=function(c,b,h){if(a.isFunction(b)){h=b;b={}}var d={},f={type:"keydown",propagate:false,disableInInput:false,target:a("html")[0]},e=this;d=a.extend(d,f,b||{});c=c.toLowerCase();var g=function(j){j=a.event.fix(j);var o=j.target;o=(o.nodeType==3)?o.parentNode:o;if(d.disableInInput){var s=a(o);if(s.is("input")||s.is("textarea")){return}}var l=j.which,u=j.type,r=String.fromCharCode(l).toLowerCase(),t=e.special_keys[l],m=j.shiftKey,i=j.ctrlKey,p=j.altKey,w=j.metaKey,q=true,k=null;if(a.browser.opera||a.browser.safari){while(!e.all[o]&&o.parentNode){o=o.parentNode}}var v=e.all[o].events[u].callbackMap;if(!m&&!i&&!p&&!w){k=v[t]||v[r]}else{var n="";if(p){n+="alt+"}if(i){n+="ctrl+"}if(m){n+="shift+"}if(w){n+="meta+"}k=v[n+t]||v[n+r]||v[n+e.shift_nums[r]]}if(k){k.cb(j);if(!k.propagate){j.stopPropagation();j.preventDefault();return false}}};if(!this.all[d.target]){this.all[d.target]={events:{}}}if(!this.all[d.target].events[d.type]){this.all[d.target].events[d.type]={callbackMap:{}};a.event.add(d.target,d.type,g)}this.all[d.target].events[d.type].callbackMap[c]={cb:h,propagate:d.propagate};return a};this.remove=function(c,b){b=b||{};target=b.target||a("html")[0];type=b.type||"keydown";c=c.toLowerCase();delete this.all[target].events[type].callbackMap[c];return a};a.hotkeys=this;return a})(jQuery); -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/AuthenticatedPathHttpRequest.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import javax.servlet.http.HttpServletRequest; 17 | 18 | public class AuthenticatedPathHttpRequest extends AuthenticatedHttpRequest { 19 | 20 | private final String contextPath; 21 | private final StringBuffer requestURL; 22 | private String requestURI; 23 | private String requestPath; 24 | 25 | public AuthenticatedPathHttpRequest( 26 | HttpServletRequest request, String requestPath, String userHeader, String username) { 27 | super(request, userHeader, username); 28 | 29 | this.requestPath = requestPath; 30 | this.contextPath = super.getContextPath(); 31 | this.requestURL = super.getRequestURL(); 32 | this.requestURI = super.getRequestURI(); 33 | } 34 | 35 | @Override 36 | public String getRequestURI() { 37 | return contextPath + requestPath; 38 | } 39 | 40 | @Override 41 | public StringBuffer getRequestURL() { 42 | return new StringBuffer( 43 | requestURL.substring(0, requestURL.indexOf(requestURI)) + getRequestURI()); 44 | } 45 | 46 | @Override 47 | public String getServletPath() { 48 | return requestPath; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/ErrorJob.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.googlesource.gerrit.plugins.github.git.GitJobStatus.Code; 17 | 18 | public class ErrorJob extends AbstractCloneJob implements GitJob { 19 | 20 | private int idx; 21 | private String organisation; 22 | private String repository; 23 | private Throwable exception; 24 | private GitJobStatus status; 25 | 26 | public ErrorJob(int idx, String organisation, String repository, Throwable e) { 27 | this.idx = idx; 28 | this.organisation = organisation; 29 | this.repository = repository; 30 | this.exception = e; 31 | status = new GitJobStatus(idx); 32 | status.update(Code.FAILED, "Failed", getErrorDescription(exception)); 33 | } 34 | 35 | @Override 36 | public GitJobStatus getStatus() { 37 | return status; 38 | } 39 | 40 | @Override 41 | public int getIndex() { 42 | return idx; 43 | } 44 | 45 | @Override 46 | public String getOrganisation() { 47 | return organisation; 48 | } 49 | 50 | @Override 51 | public String getRepository() { 52 | return repository; 53 | } 54 | 55 | @Override 56 | public void cancel() {} 57 | 58 | @Override 59 | public void run() {} 60 | } 61 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/groups/OrganizationStructure.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.groups; 16 | 17 | import com.google.common.base.MoreObjects; 18 | import java.io.Serializable; 19 | import java.util.HashMap; 20 | import java.util.HashSet; 21 | import java.util.Set; 22 | import java.util.stream.Collectors; 23 | 24 | public class OrganizationStructure implements Serializable { 25 | private static final long serialVersionUID = 1L; 26 | 27 | private HashMap> teams = new HashMap<>(); 28 | 29 | public Set put(String organisation, String team) { 30 | HashSet userTeams = 31 | MoreObjects.firstNonNull(teams.get(organisation), new HashSet()); 32 | userTeams.add(team); 33 | return teams.put(organisation, userTeams); 34 | } 35 | 36 | public Set keySet() { 37 | return teams.keySet(); 38 | } 39 | 40 | public Iterable get(String organization) { 41 | return teams.get(organization); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return teams.entrySet().stream() 47 | .map(org -> "Organization " + org.getKey() + " Teams: " + org.getValue()) 48 | .collect(Collectors.joining(" : ")); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/ControllerErrors.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.google.inject.Singleton; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | @Singleton 23 | public class ControllerErrors { 24 | private static final Logger log = LoggerFactory.getLogger(ControllerErrors.class); 25 | 26 | private final IdentifiedUser user; 27 | 28 | @Inject 29 | public ControllerErrors(final IdentifiedUser user) { 30 | this.user = user; 31 | } 32 | 33 | public void submit(Exception e) { 34 | log.error( 35 | String.format( 36 | "User:%s Controller:%s Exception:%s '%s'", 37 | getUser(), getController(), e.getClass(), e.getLocalizedMessage()), 38 | e); 39 | } 40 | 41 | private String getController() { 42 | StackTraceElement[] stack = Thread.currentThread().getStackTrace(); 43 | StackTraceElement caller = stack[stack.length - 1]; 44 | return caller.getClassName() + "." + caller.getMethodName(); 45 | } 46 | 47 | private Object getUser() { 48 | return user.getUserName() + " '" + user.getNameEmail() + "'"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/RepositoriesCloneCancelController.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.google.inject.Singleton; 19 | import com.googlesource.gerrit.plugins.github.git.GitImporter; 20 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 21 | import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider; 22 | import java.io.IOException; 23 | import javax.servlet.ServletException; 24 | import javax.servlet.http.HttpServletRequest; 25 | import javax.servlet.http.HttpServletResponse; 26 | 27 | @Singleton 28 | public class RepositoriesCloneCancelController implements VelocityController { 29 | 30 | private ScopedProvider clonerProvider; 31 | 32 | @Inject 33 | public RepositoriesCloneCancelController(ScopedProvider clonerProvider) { 34 | this.clonerProvider = clonerProvider; 35 | } 36 | 37 | @Override 38 | public void doAction( 39 | IdentifiedUser user, 40 | GitHubLogin hubLogin, 41 | HttpServletRequest req, 42 | HttpServletResponse resp, 43 | ControllerErrors errors) 44 | throws ServletException, IOException { 45 | clonerProvider.get(req).cancel(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/PullRequestImportStatusController.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.google.inject.Provider; 19 | import com.googlesource.gerrit.plugins.github.git.PullRequestImporter; 20 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 21 | import java.io.IOException; 22 | import javax.servlet.ServletException; 23 | import javax.servlet.http.HttpServletRequest; 24 | import javax.servlet.http.HttpServletResponse; 25 | 26 | public class PullRequestImportStatusController extends JobStatusController 27 | implements VelocityController { 28 | 29 | private Provider pullRequestsImporter; 30 | 31 | @Inject 32 | public PullRequestImportStatusController( 33 | final Provider pullRequestsImporter) { 34 | this.pullRequestsImporter = pullRequestsImporter; 35 | } 36 | 37 | @Override 38 | public void doAction( 39 | IdentifiedUser user, 40 | GitHubLogin hubLogin, 41 | HttpServletRequest req, 42 | HttpServletResponse resp, 43 | ControllerErrors errors) 44 | throws ServletException, IOException { 45 | respondWithJobStatusJson(resp, pullRequestsImporter.get()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/RepositoriesCloneStatusController.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.google.inject.Singleton; 19 | import com.googlesource.gerrit.plugins.github.git.GitImporter; 20 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 21 | import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider; 22 | import java.io.IOException; 23 | import javax.servlet.ServletException; 24 | import javax.servlet.http.HttpServletRequest; 25 | import javax.servlet.http.HttpServletResponse; 26 | 27 | @Singleton 28 | public class RepositoriesCloneStatusController extends JobStatusController 29 | implements VelocityController { 30 | private ScopedProvider clonerProvider; 31 | 32 | @Inject 33 | public RepositoriesCloneStatusController(ScopedProvider clonerProvider) { 34 | this.clonerProvider = clonerProvider; 35 | } 36 | 37 | @Override 38 | public void doAction( 39 | IdentifiedUser user, 40 | GitHubLogin hubLogin, 41 | HttpServletRequest req, 42 | HttpServletResponse resp, 43 | ControllerErrors errors) 44 | throws ServletException, IOException { 45 | respondWithJobStatusJson(resp, clonerProvider.get(req)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/JobExecutor.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.gerrit.server.util.RequestScopePropagator; 17 | import com.google.inject.Inject; 18 | import com.google.inject.Singleton; 19 | import com.googlesource.gerrit.plugins.github.GitHubConfig; 20 | import java.util.Random; 21 | import java.util.concurrent.Executors; 22 | import java.util.concurrent.ScheduledExecutorService; 23 | import java.util.concurrent.TimeUnit; 24 | 25 | @Singleton 26 | public class JobExecutor { 27 | private final ScheduledExecutorService executor; 28 | private final RequestScopePropagator requestScopePropagator; 29 | private final GitHubConfig config; 30 | 31 | @Inject 32 | public JobExecutor( 33 | final RequestScopePropagator requestScopePropagator, final GitHubConfig config) { 34 | this.requestScopePropagator = requestScopePropagator; 35 | this.config = config; 36 | this.executor = Executors.newScheduledThreadPool(config.jobPoolLimit); 37 | } 38 | 39 | public void exec(GitJob job) { 40 | executor.schedule( 41 | requestScopePropagator.wrap(job), getRandomExecutionDelay(job), TimeUnit.SECONDS); 42 | } 43 | 44 | private int getRandomExecutionDelay(GitJob job) { 45 | Random rnd = new Random(System.currentTimeMillis() + job.hashCode()); 46 | return rnd.nextInt(config.jobExecTimeout); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImporter.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.google.inject.servlet.SessionScoped; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | @SessionScoped 23 | public class PullRequestImporter extends BatchImporter { 24 | private static final Logger log = LoggerFactory.getLogger(PullRequestImporter.class); 25 | 26 | private final PullRequestImportJob.Factory prImportJobProvider; 27 | 28 | @Inject 29 | public PullRequestImporter( 30 | JobExecutor executor, IdentifiedUser user, PullRequestImportJob.Factory prImportJobProvider) { 31 | super(executor, user); 32 | this.prImportJobProvider = prImportJobProvider; 33 | } 34 | 35 | public void importPullRequest( 36 | int idx, 37 | String organisation, 38 | String repoName, 39 | int pullRequestId, 40 | PullRequestImportType importType) { 41 | try { 42 | PullRequestImportJob pullRequestImportJob = 43 | prImportJobProvider.create(idx, organisation, repoName, pullRequestId, importType); 44 | log.debug("New Pull request import job created: " + pullRequestImportJob); 45 | schedule(idx, pullRequestImportJob); 46 | } catch (Throwable e) { 47 | schedule(idx, new ErrorJob(idx, organisation, repoName, e)); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthGitWrappedResponse.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import java.io.IOException; 17 | import javax.servlet.http.HttpServletResponse; 18 | import javax.servlet.http.HttpServletResponseWrapper; 19 | 20 | public class OAuthGitWrappedResponse extends HttpServletResponseWrapper { 21 | public static final String GIT_REALM_NAME = "GitHub authentication for Gerrit Code Review"; 22 | private static final String GIT_AUTHENTICATION_BASIC = "Basic "; 23 | private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; 24 | 25 | public OAuthGitWrappedResponse(HttpServletResponse response) { 26 | super(response); 27 | } 28 | 29 | @Override 30 | public void sendError(int sc) throws IOException { 31 | if (sc == SC_UNAUTHORIZED) { 32 | requestBasicAuthenticationHandshake(); 33 | } 34 | super.sendError(sc); 35 | } 36 | 37 | @Override 38 | public void sendError(int sc, String msg) throws IOException { 39 | if (sc == SC_UNAUTHORIZED) { 40 | requestBasicAuthenticationHandshake(); 41 | } 42 | super.sendError(sc, msg); 43 | } 44 | 45 | private void requestBasicAuthenticationHandshake() { 46 | setStatus(SC_UNAUTHORIZED); 47 | StringBuilder v = new StringBuilder(); 48 | v.append(GIT_AUTHENTICATION_BASIC); 49 | v.append("realm=\"").append(GIT_REALM_NAME).append("\""); 50 | setHeader(WWW_AUTHENTICATE, v.toString()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/CanonicalWebUrls.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import static com.googlesource.gerrit.plugins.github.oauth.GitHubOAuthConfig.GERRIT_OAUTH_FINAL; 18 | import static com.googlesource.gerrit.plugins.github.oauth.GitHubOAuthConfig.GITHUB_PLUGIN_OAUTH_SCOPE; 19 | 20 | import com.google.common.base.CharMatcher; 21 | import com.google.common.base.MoreObjects; 22 | import com.google.gerrit.httpd.HttpCanonicalWebUrlProvider; 23 | import com.google.inject.Inject; 24 | import com.google.inject.Singleton; 25 | 26 | @Singleton 27 | public class CanonicalWebUrls { 28 | private final GitHubOAuthConfig oauthConf; 29 | private final HttpCanonicalWebUrlProvider canonicalWebUrlProvider; 30 | 31 | static String trimTrailingSlash(String url) { 32 | return CharMatcher.is('/').trimTrailingFrom(url); 33 | } 34 | 35 | @Inject 36 | CanonicalWebUrls( 37 | GitHubOAuthConfig oauthConf, HttpCanonicalWebUrlProvider canonicalWebUrlProvider) { 38 | this.oauthConf = oauthConf; 39 | this.canonicalWebUrlProvider = canonicalWebUrlProvider; 40 | } 41 | 42 | public String getScopeSelectionUrl() { 43 | return getCannonicalWebUrl() 44 | + MoreObjects.firstNonNull(oauthConf.scopeSelectionUrl, GITHUB_PLUGIN_OAUTH_SCOPE); 45 | } 46 | 47 | String getOAuthFinalRedirectUrl() { 48 | return getCannonicalWebUrl() + GERRIT_OAUTH_FINAL; 49 | } 50 | 51 | private String getCannonicalWebUrl() { 52 | return trimTrailingSlash(canonicalWebUrlProvider.get()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/AuthenticatedHttpRequest.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import com.google.common.collect.Iterators; 17 | import java.util.Enumeration; 18 | import java.util.HashMap; 19 | import java.util.HashSet; 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletRequestWrapper; 22 | 23 | public class AuthenticatedHttpRequest extends HttpServletRequestWrapper { 24 | private HashMap headers = new HashMap<>(); 25 | 26 | public AuthenticatedHttpRequest(HttpServletRequest request, String... headerNamesValues) { 27 | super(request); 28 | 29 | for (int i = 0; i < headerNamesValues.length; ) { 30 | String name = headerNamesValues[i++]; 31 | String value = headerNamesValues[i++]; 32 | if (name != null && value != null) { 33 | headers.put(name, value); 34 | } 35 | } 36 | } 37 | 38 | @Override 39 | public Enumeration getHeaderNames() { 40 | final Enumeration wrappedHeaderNames = super.getHeaderNames(); 41 | HashSet headerNames = new HashSet<>(headers.keySet()); 42 | while (wrappedHeaderNames.hasMoreElements()) { 43 | headerNames.add(wrappedHeaderNames.nextElement()); 44 | } 45 | return Iterators.asEnumeration(headerNames.iterator()); 46 | } 47 | 48 | @Override 49 | public String getHeader(String name) { 50 | String headerValue = headers.get(name); 51 | if (headerValue != null) { 52 | return headerValue; 53 | } 54 | return super.getHeader(name); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/HttpSessionProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import com.google.common.base.Supplier; 17 | import com.google.common.base.Suppliers; 18 | import com.google.inject.Inject; 19 | import com.google.inject.Provider; 20 | import java.util.Optional; 21 | import javax.servlet.http.HttpServletRequest; 22 | import javax.servlet.http.HttpSession; 23 | 24 | public abstract class HttpSessionProvider implements ScopedProvider { 25 | private final Supplier singletonKey = Suppliers.memoize(() -> getClass().getName()); 26 | 27 | @Inject private Provider provider; 28 | 29 | @Inject private Provider httpRequestProvider; 30 | 31 | @Override 32 | public T get() { 33 | return get(httpRequestProvider.get()); 34 | } 35 | 36 | @Override 37 | public T get(final HttpServletRequest req) { 38 | HttpSession session = req.getSession(); 39 | 40 | synchronized (this) { 41 | @SuppressWarnings("unchecked") 42 | T instance = (T) session.getAttribute(singletonKey.get()); 43 | if (instance == null) { 44 | instance = provider.get(); 45 | session.setAttribute(singletonKey.get(), instance); 46 | } 47 | return instance; 48 | } 49 | } 50 | 51 | public void clear(final HttpServletRequest req) { 52 | Optional.ofNullable(req.getSession(false)) 53 | .ifPresent((s) -> s.removeAttribute(singletonKey.get())); 54 | } 55 | 56 | @Override 57 | public HttpServletRequest getScopedRequest() { 58 | return httpRequestProvider.get(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/GitHubTeamGroup.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.group; 16 | 17 | import com.google.gerrit.common.Nullable; 18 | import com.google.gerrit.entities.AccountGroup; 19 | import com.google.gerrit.entities.AccountGroup.UUID; 20 | import com.google.gerrit.entities.GroupReference; 21 | import com.google.inject.Inject; 22 | import com.google.inject.assistedinject.Assisted; 23 | 24 | public class GitHubTeamGroup extends GitHubGroup { 25 | public interface Factory { 26 | GitHubTeamGroup get( 27 | @Assisted GitHubOrganisationGroup orgGroup, 28 | @Assisted String teamName, 29 | @Nullable String teamUrl); 30 | } 31 | 32 | private final GitHubOrganisationGroup orgGroup; 33 | private final String teamName; 34 | 35 | @Inject 36 | GitHubTeamGroup( 37 | @Assisted GitHubOrganisationGroup orgGroup, 38 | @Assisted String teamName, 39 | @Nullable String teamUrl) { 40 | super(uuid(orgGroup.getGroupUUID(), teamName), teamUrl); 41 | this.orgGroup = orgGroup; 42 | this.teamName = teamName; 43 | } 44 | 45 | @Override 46 | public String getName() { 47 | return orgGroup.getName() + "/" + teamName; 48 | } 49 | 50 | public static UUID uuid(UUID orgUUID, String teamName) { 51 | return AccountGroup.uuid(orgUUID.get() + "/" + teamName); 52 | } 53 | 54 | public static GroupReference groupReference(GroupReference orgReference, String teamName) { 55 | return GroupReference.create( 56 | uuid(orgReference.getUUID(), teamName), orgReference.getName() + "/" + teamName); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitCloneFailedException.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import org.eclipse.jgit.api.errors.JGitInternalException; 17 | 18 | public class GitCloneFailedException extends GitException { 19 | public GitCloneFailedException(String remoteUrl, Throwable e) { 20 | super("Failed to clone from repository " + remoteUrl, e); 21 | } 22 | 23 | private static final long serialVersionUID = 1619949108894445899L; 24 | 25 | @Override 26 | public String getErrorDescription() { 27 | return "Clone failed" + getCauseDescription(getCause()); 28 | } 29 | 30 | private String getCauseDescription(Throwable cause) { 31 | if (cause == null) { 32 | return ""; 33 | } else if (JGitInternalException.class.isAssignableFrom(cause.getClass())) { 34 | Throwable innerCause = cause.getCause(); 35 | return innerCause != null ? getCauseDescription(cause.getCause()) : "JGit internal error"; 36 | } else { 37 | return getDecamelisedName(cause); 38 | } 39 | } 40 | 41 | private String getDecamelisedName(Throwable cause) { 42 | StringBuilder name = new StringBuilder(); 43 | String causeName = cause.getClass().getName(); 44 | causeName = causeName.substring(causeName.lastIndexOf('.') + 1); 45 | for (char causeChar : causeName.toCharArray()) { 46 | if (Character.isUpperCase(causeChar)) { 47 | name.append(" "); 48 | name.append(Character.toLowerCase(causeChar)); 49 | } else { 50 | name.append(causeChar); 51 | } 52 | } 53 | 54 | return name.toString(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/js/jquery/jquery.color.js: -------------------------------------------------------------------------------- 1 | (function(d){d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(f,e){d.fx.step[e]=function(g){if(g.state==0){g.start=c(g.elem,e);g.end=b(g.end)}g.elem.style[e]="rgb("+[Math.max(Math.min(parseInt((g.pos*(g.end[0]-g.start[0]))+g.start[0]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[1]-g.start[1]))+g.start[1]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[2]-g.start[2]))+g.start[2]),255),0)].join(",")+")"}});function b(f){var e;if(f&&f.constructor==Array&&f.length==3){return f}if(e=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(f)){return[parseInt(e[1]),parseInt(e[2]),parseInt(e[3])]}if(e=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(f)){return[parseFloat(e[1])*2.55,parseFloat(e[2])*2.55,parseFloat(e[3])*2.55]}if(e=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(f)){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}if(e=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(f)){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}if(e=/rgba\(0, 0, 0, 0\)/.exec(f)){return a.transparent}return a[d.trim(f).toLowerCase()]}function c(g,e){var f;do{f=d.curCSS(g,e);if(f!=""&&f!="transparent"||d.nodeName(g,"body")){break}e="backgroundColor"}while(g=g.parentNode);return b(f)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]}})(jQuery); -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/js/jquery/jquery.table-hotkeys.js: -------------------------------------------------------------------------------- 1 | (function(a){a.fn.filter_visible=function(c){c=c||3;var b=function(){var e=a(this),d;for(d=0;d groups; 26 | 27 | public interface Factory { 28 | GitHubGroupMembership get(@Assisted String username); 29 | } 30 | 31 | @Inject 32 | GitHubGroupMembership(GitHubGroupsCache ghOrganisationCache, @Assisted String username) { 33 | this.groups = 34 | new ImmutableSet.Builder() 35 | .addAll(ghOrganisationCache.getGroupsForUser(username)) 36 | .build(); 37 | } 38 | 39 | @Override 40 | public boolean contains(UUID groupId) { 41 | return groups.contains(groupId); 42 | } 43 | 44 | @Override 45 | public boolean containsAnyOf(Iterable groupIds) { 46 | return !intersection(groupIds).isEmpty(); 47 | } 48 | 49 | @Override 50 | public Set intersection(Iterable groupIds) { 51 | ImmutableSet.Builder groupBuilder = new ImmutableSet.Builder<>(); 52 | for (UUID uuid : groupIds) { 53 | if (contains(uuid)) { 54 | groupBuilder.add(uuid); 55 | } 56 | } 57 | return groupBuilder.build(); 58 | } 59 | 60 | @Override 61 | public Set getKnownGroups() { 62 | return groups; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitHubUser.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.git; 16 | 17 | import com.google.common.base.Optional; 18 | import com.google.common.base.Strings; 19 | import java.io.IOException; 20 | import org.kohsuke.github.GHUser; 21 | import org.kohsuke.github.GitUser; 22 | 23 | public class GitHubUser { 24 | public final String login; 25 | public final String name; 26 | public final String email; 27 | 28 | private GitHubUser(GHUser gitHubUser, GitUser author) throws IOException { 29 | this.login = initLogin(gitHubUser).or(generateLogin(author.getName())); 30 | this.name = initFullName(gitHubUser).or(author.getName()); 31 | this.email = initEmail(gitHubUser).or(author.getEmail()); 32 | } 33 | 34 | private static String generateLogin(String fullName) { 35 | return fullName.toLowerCase().replaceAll("^[a-z0-9]", "_"); 36 | } 37 | 38 | private static Optional initLogin(GHUser gitHubUser) { 39 | return Optional.fromNullable(gitHubUser != null ? gitHubUser.getLogin() : null); 40 | } 41 | 42 | private static Optional initEmail(GHUser gitHubUser) throws IOException { 43 | return Optional.fromNullable( 44 | gitHubUser != null ? Strings.emptyToNull(gitHubUser.getEmail()) : null); 45 | } 46 | 47 | private static Optional initFullName(GHUser gitHubUser) throws IOException { 48 | return Optional.fromNullable( 49 | gitHubUser != null ? Strings.emptyToNull(gitHubUser.getName()) : null); 50 | } 51 | 52 | public static GitHubUser from(GHUser gitHubUser, GitUser author) throws IOException { 53 | return new GitHubUser(gitHubUser, author); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitJobStatus.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.gson.Gson; 17 | import com.google.gson.stream.JsonWriter; 18 | import java.io.IOException; 19 | import java.io.PrintWriter; 20 | 21 | public class GitJobStatus { 22 | 23 | public enum Code { 24 | SYNC, 25 | COMPLETE, 26 | FAILED, 27 | CANCELLED; 28 | 29 | @Override 30 | public String toString() { 31 | return name().toLowerCase(); 32 | } 33 | } 34 | 35 | public final int index; 36 | private Code status; 37 | private String shortDescription; 38 | private String value; 39 | 40 | public GitJobStatus(int index) { 41 | this.index = index; 42 | this.status = GitJobStatus.Code.SYNC; 43 | this.shortDescription = "Init"; 44 | this.value = "Initializing ..."; 45 | } 46 | 47 | public void update(Code code, String sDescription, String description) { 48 | this.status = code; 49 | this.shortDescription = sDescription; 50 | this.value = description; 51 | } 52 | 53 | public Code getStatus() { 54 | return status; 55 | } 56 | 57 | public String getShortDescription() { 58 | return shortDescription; 59 | } 60 | 61 | public String getValue() { 62 | return value; 63 | } 64 | 65 | public void update(Code statusCode) { 66 | this.status = statusCode; 67 | this.shortDescription = statusCode.name(); 68 | this.value = statusCode.name(); 69 | } 70 | 71 | public void printJson(PrintWriter out) throws IOException { 72 | try (JsonWriter writer = new JsonWriter(out)) { 73 | new Gson().toJson(this, GitJobStatus.class, writer); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/group/GitHubOrganisationGroup.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.group; 16 | 17 | import static com.google.common.base.Preconditions.checkArgument; 18 | 19 | import com.google.gerrit.common.Nullable; 20 | import com.google.gerrit.entities.AccountGroup; 21 | import com.google.gerrit.entities.AccountGroup.UUID; 22 | import com.google.gerrit.entities.GroupDescription.Basic; 23 | import com.google.gerrit.entities.GroupReference; 24 | import com.google.inject.Inject; 25 | import com.google.inject.assistedinject.Assisted; 26 | 27 | public class GitHubOrganisationGroup extends GitHubGroup implements Basic { 28 | public interface Factory { 29 | GitHubOrganisationGroup get( 30 | @Assisted("orgName") String orgName, @Assisted("orgUrl") @Nullable String orgUrl); 31 | } 32 | 33 | private final String orgName; 34 | 35 | @Inject 36 | GitHubOrganisationGroup( 37 | @Assisted("orgName") String orgName, @Assisted("orgUrl") @Nullable String orgUrl) { 38 | super(uuid(orgName), orgUrl); 39 | this.orgName = orgName; 40 | } 41 | 42 | @Override 43 | public String getName() { 44 | return NAME_PREFIX + orgName; 45 | } 46 | 47 | public static GitHubOrganisationGroup fromUUID(UUID uuid) { 48 | checkArgument(uuid.get().startsWith(UUID_PREFIX), "Invalid GitHub UUID '" + uuid + "'"); 49 | return new GitHubOrganisationGroup(uuid.get().substring(UUID_PREFIX.length()), null); 50 | } 51 | 52 | public static UUID uuid(String orgName) { 53 | return AccountGroup.uuid(UUID_PREFIX + orgName); 54 | } 55 | 56 | public static GroupReference groupReference(String orgName) { 57 | return GroupReference.create(uuid(orgName), NAME_PREFIX + orgName); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthCache.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.oauth; 15 | 16 | import com.google.common.cache.CacheLoader; 17 | import com.google.common.cache.LoadingCache; 18 | import com.google.gerrit.server.cache.CacheModule; 19 | import com.google.inject.Inject; 20 | import com.google.inject.Module; 21 | import com.google.inject.Singleton; 22 | import com.google.inject.name.Named; 23 | import com.googlesource.gerrit.plugins.github.oauth.OAuthProtocol.AccessToken; 24 | import java.util.concurrent.ExecutionException; 25 | 26 | @Singleton 27 | public class OAuthCache { 28 | private static final String CACHE_NAME = "github_oauth"; 29 | 30 | public static class Loader extends CacheLoader { 31 | private GitHubLogin ghLogin; 32 | 33 | @Inject 34 | public Loader(GitHubLogin ghLogin) { 35 | this.ghLogin = ghLogin; 36 | } 37 | 38 | @Override 39 | public String load(AccessToken accessToken) throws Exception { 40 | ghLogin.login(accessToken.accessToken); 41 | return ghLogin.getMyself().getLogin(); 42 | } 43 | } 44 | 45 | public static Module module() { 46 | return new CacheModule() { 47 | @Override 48 | protected void configure() { 49 | cache(CACHE_NAME, AccessToken.class, String.class).loader(Loader.class); 50 | bind(OAuthCache.class); 51 | } 52 | }; 53 | } 54 | 55 | private LoadingCache byAccesToken; 56 | 57 | @Inject 58 | public OAuthCache(@Named(CACHE_NAME) LoadingCache byAccessToken) { 59 | this.byAccesToken = byAccessToken; 60 | } 61 | 62 | public String getLoginByAccessToken(AccessToken accessToken) throws ExecutionException { 63 | return byAccesToken.get(accessToken); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/replication/ReplicationStatusListener.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.replication; 16 | 17 | import com.google.gerrit.entities.Project.NameKey; 18 | import com.google.gerrit.server.events.Event; 19 | import com.google.gerrit.server.events.EventListener; 20 | import com.google.gerrit.server.events.RefEvent; 21 | import com.google.gson.Gson; 22 | import com.google.gson.JsonObject; 23 | import com.google.inject.Inject; 24 | import com.google.inject.Provider; 25 | import com.google.inject.Singleton; 26 | import java.io.IOException; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | 30 | @Singleton 31 | public class ReplicationStatusListener implements EventListener { 32 | private static final String REF_REPLICATED_EVENT = "ref-replicated"; 33 | private static Logger log = LoggerFactory.getLogger(ReplicationStatusListener.class); 34 | 35 | private final ReplicationStatusStore statusStore; 36 | private final Gson gson; 37 | 38 | @Inject 39 | public ReplicationStatusListener( 40 | ReplicationStatusStore statusStore, Provider gsonProvider) { 41 | this.statusStore = statusStore; 42 | this.gson = gsonProvider.get(); 43 | } 44 | 45 | @Override 46 | public void onEvent(Event event) { 47 | if (RefEvent.class.isAssignableFrom(event.getClass()) 48 | && event.getType().equals(REF_REPLICATED_EVENT)) { 49 | RefEvent refEvent = (RefEvent) event; 50 | NameKey projectNameKey = refEvent.getProjectNameKey(); 51 | JsonObject eventJson = (JsonObject) gson.toJsonTree(event); 52 | String refKey = eventJson.get("ref").getAsString(); 53 | 54 | try { 55 | statusStore.set(projectNameKey, refKey, eventJson); 56 | } catch (IOException e) { 57 | log.error( 58 | "Unable to update replication status for event " 59 | + eventJson 60 | + " on project " 61 | + projectNameKey, 62 | e); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/ProtectedBranchesCheckStep.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.git; 16 | 17 | import com.google.common.base.Joiner; 18 | import com.google.common.collect.Lists; 19 | import com.google.inject.Inject; 20 | import com.google.inject.assistedinject.Assisted; 21 | import com.googlesource.gerrit.plugins.github.GitHubConfig; 22 | import java.util.Collection; 23 | import java.util.List; 24 | import org.eclipse.jgit.lib.ProgressMonitor; 25 | import org.kohsuke.github.GHBranch; 26 | 27 | public class ProtectedBranchesCheckStep extends ImportStep { 28 | 29 | public interface Factory { 30 | ProtectedBranchesCheckStep create( 31 | @Assisted("organisation") String organisation, @Assisted("name") String repository); 32 | } 33 | 34 | @Inject 35 | public ProtectedBranchesCheckStep( 36 | GitHubConfig config, 37 | GitHubRepository.Factory gitHubRepoFactory, 38 | @Assisted("organisation") String organisation, 39 | @Assisted("name") String repository) { 40 | super(config.gitHubUrl, organisation, repository, gitHubRepoFactory); 41 | } 42 | 43 | @Override 44 | public void doImport(ProgressMonitor progress) throws Exception { 45 | Collection branches = getRepository().getBranches().values(); 46 | progress.beginTask("Checking branch protection", branches.size()); 47 | List protectedBranchNames = Lists.newLinkedList(); 48 | for (GHBranch branch : branches) { 49 | if (branch.isProtected()) { 50 | protectedBranchNames.add(branch.getName()); 51 | } 52 | progress.update(1); 53 | } 54 | progress.endTask(); 55 | if (!protectedBranchNames.isEmpty()) { 56 | throw new ProtectedBranchFoundException( 57 | String.format( 58 | "Cannot import project with protected branches, you should remove protection from:%s", 59 | Joiner.on(",").join(protectedBranchNames))); 60 | } 61 | } 62 | 63 | @Override 64 | public boolean rollback() { 65 | return true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/google/gerrit/server/account/AccountImporter.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.google.gerrit.server.account; 15 | 16 | import com.google.common.base.MoreObjects; 17 | import com.google.gerrit.entities.Account; 18 | import com.google.gerrit.server.Sequences; 19 | import com.google.gerrit.server.ServerInitiated; 20 | import com.google.gerrit.server.account.externalids.ExternalId; 21 | import com.google.gerrit.server.account.externalids.ExternalIdFactory; 22 | import com.google.inject.Inject; 23 | import com.google.inject.Provider; 24 | import java.io.IOException; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | import org.eclipse.jgit.errors.ConfigInvalidException; 28 | 29 | public class AccountImporter { 30 | private final Sequences sequences; 31 | private final Provider accountsUpdateProvider; 32 | private final ExternalIdFactory externalIdFactory; 33 | 34 | @Inject 35 | public AccountImporter( 36 | Sequences sequences, 37 | @ServerInitiated Provider accountsUpdateProvider, 38 | ExternalIdFactory externalIdFactory) { 39 | this.sequences = sequences; 40 | this.accountsUpdateProvider = accountsUpdateProvider; 41 | this.externalIdFactory = externalIdFactory; 42 | } 43 | 44 | public Account.Id importAccount(String login, String name, String email) 45 | throws IOException, ConfigInvalidException { 46 | Account.Id id = Account.id(sequences.nextAccountId()); 47 | List extIds = new ArrayList<>(); 48 | extIds.add(externalIdFactory.createEmail(id, email)); 49 | extIds.add(externalIdFactory.create(ExternalId.SCHEME_GERRIT, login, id)); 50 | extIds.add(externalIdFactory.create(ExternalId.SCHEME_USERNAME, login, id)); 51 | AccountState accountUpdate = 52 | accountsUpdateProvider 53 | .get() 54 | .insert( 55 | "Create GitHub account for " + login, 56 | id, 57 | u -> 58 | u.setFullName(MoreObjects.firstNonNull(name, login)) 59 | .setPreferredEmail(email) 60 | .addExternalIds(extIds)); 61 | return accountUpdate.account().id(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/MagicRefCheckStep.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2021 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.common.base.Joiner; 17 | import com.google.common.collect.Lists; 18 | import com.google.gerrit.entities.RefNames; 19 | import com.google.gerrit.server.util.MagicBranch; 20 | import com.google.inject.Inject; 21 | import com.google.inject.assistedinject.Assisted; 22 | import com.googlesource.gerrit.plugins.github.GitHubConfig; 23 | import java.util.List; 24 | import org.eclipse.jgit.lib.ProgressMonitor; 25 | import org.kohsuke.github.GHRef; 26 | 27 | public class MagicRefCheckStep extends ImportStep { 28 | public interface Factory { 29 | MagicRefCheckStep create( 30 | @Assisted("organisation") String organisation, @Assisted("name") String repository); 31 | } 32 | 33 | @Inject 34 | public MagicRefCheckStep( 35 | GitHubConfig config, 36 | GitHubRepository.Factory gitHubRepoFactory, 37 | @Assisted("organisation") String organisation, 38 | @Assisted("name") String repository) { 39 | super(config.gitHubUrl, organisation, repository, gitHubRepoFactory); 40 | } 41 | 42 | @Override 43 | public void doImport(ProgressMonitor progress) throws Exception { 44 | try { 45 | GHRef[] allRefs = getRepository().getRefs(); 46 | progress.beginTask("Checking magic refs", allRefs.length); 47 | 48 | List offendingRefs = Lists.newLinkedList(); 49 | for (GHRef ref : allRefs) { 50 | if (MagicBranch.isMagicBranch(ref.getRef()) 51 | || ref.getRef().startsWith(RefNames.REFS_META)) { 52 | offendingRefs.add(ref.getRef()); 53 | } 54 | progress.update(1); 55 | } 56 | 57 | if (!offendingRefs.isEmpty()) { 58 | throw new MagicRefFoundException( 59 | String.format( 60 | "Found %d ref(s): Please remove or rename the following ref(s) and try again: %s", 61 | offendingRefs.size(), Joiner.on(", ").join(offendingRefs))); 62 | } 63 | } finally { 64 | progress.endTask(); 65 | } 66 | } 67 | 68 | @Override 69 | public boolean rollback() { 70 | return true; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/notification/PullRequestHandler.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.notification; 16 | 17 | import com.google.inject.Inject; 18 | import com.google.inject.Provider; 19 | import com.google.inject.Singleton; 20 | import com.googlesource.gerrit.plugins.github.git.PullRequestImportType; 21 | import com.googlesource.gerrit.plugins.github.git.PullRequestImporter; 22 | import java.io.IOException; 23 | import org.kohsuke.github.GHEventPayload.PullRequest; 24 | import org.kohsuke.github.GHRepository; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | /** 29 | * Handles pull_request event in github webhook. 30 | * 31 | * @see Pull 32 | * Request Event 33 | */ 34 | @Singleton 35 | class PullRequestHandler implements WebhookEventHandler { 36 | private static final Logger logger = LoggerFactory.getLogger(PullRequestHandler.class); 37 | private final Provider prImportProvider; 38 | 39 | @Inject 40 | public PullRequestHandler(Provider pullRequestsImporter) { 41 | this.prImportProvider = pullRequestsImporter; 42 | } 43 | 44 | @Override 45 | public boolean doAction(PullRequest payload) throws IOException { 46 | String action = payload.getAction(); 47 | if (action.equals("opened") || action.equals("synchronize")) { 48 | GHRepository repository = payload.getRepository(); 49 | Integer prNumber = Integer.valueOf(payload.getNumber()); 50 | PullRequestImporter prImporter = prImportProvider.get(); 51 | String organization = repository.getOwnerName(); 52 | String name = repository.getName(); 53 | logger.info("Importing {}/{}#{}", organization, name, prNumber); 54 | prImporter.importPullRequest( 55 | 0, organization, name, prNumber.intValue(), PullRequestImportType.Commits); 56 | logger.info("Imported {}/{}#{}", organization, name, prNumber); 57 | return true; 58 | } 59 | return false; 60 | } 61 | 62 | @Override 63 | public Class getPayloadType() { 64 | return PullRequest.class; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /github-plugin/tsconfig-plugins-base.json: -------------------------------------------------------------------------------- 1 | /* TODO: this file should be included in @gerritcodereview/typescript-api */ 2 | { 3 | "compilerOptions": { 4 | /* Basic Options */ 5 | "target": "es2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 6 | "module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 7 | "inlineSourceMap": true, /* Generates corresponding '.map' file. */ 8 | "rootDir": ".", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 9 | "removeComments": false, /* Emit comments to output */ 10 | 11 | /* Strict Type-Checking Options */ 12 | "strict": true, /* Enable all strict type-checking options. */ 13 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 14 | "strictNullChecks": true, /* Enable strict null checks. */ 15 | "strictFunctionTypes": true, /* Enable strict checking of function types. */ 16 | "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 17 | "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 18 | "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 19 | 20 | /* Additional Checks */ 21 | "noUnusedLocals": true, /* Report errors on unused locals. */ 22 | "noUnusedParameters": true, /* Report errors on unused parameters. */ 23 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 24 | "noImplicitOverride": true, 25 | "noFallthroughCasesInSwitch": true,/* Report errors for fallthrough cases in switch statement. */ 26 | 27 | "skipLibCheck": true, /* Do not check node_modules */ 28 | 29 | /* Module Resolution Options */ 30 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 31 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 32 | "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 33 | 34 | /* Advanced Options */ 35 | "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ 36 | "incremental": true, 37 | "experimentalDecorators": true, 38 | 39 | "allowUmdGlobalAccess": true, 40 | 41 | "typeRoots": [ 42 | /* typeRoots for Bazel */ 43 | "../external/ui_dev_npm/node_modules/@types", 44 | "../external/plugins_npm/node_modules/@types", 45 | /* typeRoots for IDE */ 46 | "../polygerrit-ui/node_modules/@types", 47 | "../plugins/node_modules/@types" 48 | ] 49 | }, 50 | } 51 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubTopMenu.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github; 15 | 16 | import com.google.gerrit.extensions.annotations.Listen; 17 | import com.google.gerrit.extensions.annotations.PluginName; 18 | import com.google.gerrit.extensions.client.AuthType; 19 | import com.google.gerrit.extensions.client.MenuItem; 20 | import com.google.gerrit.extensions.webui.TopMenu; 21 | import com.google.gerrit.server.CurrentUser; 22 | import com.google.gerrit.server.IdentifiedUser; 23 | import com.google.gerrit.server.config.AuthConfig; 24 | import com.google.inject.Inject; 25 | import com.google.inject.Provider; 26 | import com.google.inject.Singleton; 27 | import java.util.Arrays; 28 | import java.util.Collections; 29 | import java.util.List; 30 | 31 | @Listen 32 | @Singleton 33 | public class GitHubTopMenu implements TopMenu { 34 | private final List menuEntries; 35 | private final Provider userProvider; 36 | private final AuthConfig authConfig; 37 | 38 | @Inject 39 | public GitHubTopMenu( 40 | @PluginName String pluginName, 41 | Provider userProvider, 42 | AuthConfig authConfig, 43 | GitHubConfig ghConfig) { 44 | String baseUrl = "/plugins/" + pluginName; 45 | this.menuEntries = 46 | Arrays.asList( 47 | new MenuEntry( 48 | "GitHub", 49 | Arrays.asList( 50 | getItem("Scope", baseUrl + "/static/scope.html"), 51 | getItem("Profile", baseUrl + "/static/account.html"), 52 | getItem("Repositories", baseUrl + "/static/repositories.html"), 53 | getItem("Pull Requests", baseUrl + "/static/pullrequests.html")))); 54 | this.userProvider = userProvider; 55 | this.authConfig = authConfig; 56 | } 57 | 58 | private MenuItem getItem(String anchorName, String urlPath) { 59 | return new MenuItem(anchorName, urlPath, ""); 60 | } 61 | 62 | @Override 63 | public List getEntries() { 64 | if (userProvider.get() instanceof IdentifiedUser 65 | && 66 | // Only with HTTP authentication we can transparently trigger OAuth if needed 67 | authConfig.getAuthType().equals(AuthType.HTTP)) { 68 | return menuEntries; 69 | } 70 | return Collections.emptyList(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/PullRequestImportController.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.google.inject.Provider; 19 | import com.google.inject.Singleton; 20 | import com.googlesource.gerrit.plugins.github.git.PullRequestImportType; 21 | import com.googlesource.gerrit.plugins.github.git.PullRequestImporter; 22 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 23 | import java.io.IOException; 24 | import java.util.Map.Entry; 25 | import javax.servlet.ServletException; 26 | import javax.servlet.http.HttpServletRequest; 27 | import javax.servlet.http.HttpServletResponse; 28 | 29 | @Singleton 30 | public class PullRequestImportController implements VelocityController { 31 | 32 | private Provider prImportProvider; 33 | 34 | @Inject 35 | public PullRequestImportController(final Provider pullRequestsImporter) { 36 | this.prImportProvider = pullRequestsImporter; 37 | } 38 | 39 | @Override 40 | public void doAction( 41 | IdentifiedUser user, 42 | GitHubLogin hubLogin, 43 | HttpServletRequest req, 44 | HttpServletResponse resp, 45 | ControllerErrors errors) 46 | throws ServletException, IOException { 47 | String organisation = req.getParameter("organisation"); 48 | PullRequestImporter prImporter = prImportProvider.get(); 49 | 50 | for (Entry param : req.getParameterMap().entrySet()) { 51 | String name = param.getKey(); 52 | if (name.endsWith(".selected") 53 | && param.getValue().length == 1 54 | && param.getValue()[0].equalsIgnoreCase("on")) { 55 | 56 | String paramPrefix = name.substring(0, name.length() - ".selected".length()); 57 | int idx = Integer.parseInt(req.getParameter(paramPrefix + ".idx")); 58 | PullRequestImportType importType = 59 | PullRequestImportType.valueOf(req.getParameter(paramPrefix + ".type")); 60 | 61 | int pullRequestId = Integer.parseInt(req.getParameter(paramPrefix + ".id")); 62 | String repoName = req.getParameter(paramPrefix + ".repo"); 63 | 64 | prImporter.importPullRequest(idx, organisation, repoName, pullRequestId, importType); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /github-plugin/src/test/java/com/googlesource/gerrit/plugins/github/FakeHttpSession.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github; 16 | 17 | import java.util.Enumeration; 18 | import java.util.HashMap; 19 | import javax.servlet.ServletContext; 20 | import javax.servlet.http.HttpSession; 21 | import javax.servlet.http.HttpSessionContext; 22 | import org.junit.Ignore; 23 | 24 | @Ignore 25 | public class FakeHttpSession implements HttpSession { 26 | private final HashMap attributes; 27 | 28 | public FakeHttpSession() { 29 | this.attributes = new HashMap<>(); 30 | } 31 | 32 | @Override 33 | public long getCreationTime() { 34 | return 0; 35 | } 36 | 37 | @Override 38 | public String getId() { 39 | return null; 40 | } 41 | 42 | @Override 43 | public long getLastAccessedTime() { 44 | return 0; 45 | } 46 | 47 | @Override 48 | public ServletContext getServletContext() { 49 | return null; 50 | } 51 | 52 | @Override 53 | public void setMaxInactiveInterval(int i) {} 54 | 55 | @Override 56 | public int getMaxInactiveInterval() { 57 | return 0; 58 | } 59 | 60 | @Override 61 | public HttpSessionContext getSessionContext() { 62 | return null; 63 | } 64 | 65 | @Override 66 | public Object getAttribute(String s) { 67 | return attributes.get(s); 68 | } 69 | 70 | @Override 71 | public Object getValue(String s) { 72 | return getAttribute(s); 73 | } 74 | 75 | @Override 76 | public Enumeration getAttributeNames() { 77 | return java.util.Collections.enumeration(attributes.keySet()); 78 | } 79 | 80 | @Override 81 | public String[] getValueNames() { 82 | return attributes.keySet().toArray(new String[0]); 83 | } 84 | 85 | @Override 86 | public void setAttribute(String s, Object o) { 87 | attributes.put(s, o); 88 | } 89 | 90 | @Override 91 | public void putValue(String s, Object o) { 92 | setAttribute(s, o); 93 | } 94 | 95 | @Override 96 | public void removeAttribute(String s) { 97 | attributes.remove(s); 98 | } 99 | 100 | @Override 101 | public void removeValue(String s) { 102 | removeAttribute(s); 103 | } 104 | 105 | @Override 106 | public void invalidate() { 107 | attributes.clear(); 108 | } 109 | 110 | @Override 111 | public boolean isNew() { 112 | return false; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/ReplicateProjectStep.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.gerrit.extensions.registration.DynamicItem; 17 | import com.google.inject.Inject; 18 | import com.google.inject.assistedinject.Assisted; 19 | import com.googlesource.gerrit.plugins.github.GitHubURL; 20 | import com.googlesource.gerrit.plugins.replication.api.ReplicationRemotesApi; 21 | import java.io.IOException; 22 | import org.eclipse.jgit.lib.Config; 23 | import org.eclipse.jgit.lib.ProgressMonitor; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | public class ReplicateProjectStep extends ImportStep { 28 | private static final Logger LOG = LoggerFactory.getLogger(ReplicateProjectStep.class); 29 | private final DynamicItem replicationRemotesUpdaterItem; 30 | private final ReplicationRemoteConfigBuilder remoteConfigBuilder; 31 | 32 | public interface Factory { 33 | ReplicateProjectStep create( 34 | @Assisted("organisation") String organisation, @Assisted("name") String repository); 35 | } 36 | 37 | @Inject 38 | public ReplicateProjectStep( 39 | final DynamicItem replicationRemotesUpdaterItem, 40 | final GitHubRepository.Factory gitHubRepoFactory, 41 | ReplicationRemoteConfigBuilder remoteConfigBuilder, 42 | @GitHubURL String gitHubUrl, 43 | @Assisted("organisation") String organisation, 44 | @Assisted("name") String repository) 45 | throws IOException { 46 | super(gitHubUrl, organisation, repository, gitHubRepoFactory); 47 | this.remoteConfigBuilder = remoteConfigBuilder; 48 | LOG.debug("Gerrit ReplicateProject " + organisation + "/" + repository); 49 | this.replicationRemotesUpdaterItem = replicationRemotesUpdaterItem; 50 | } 51 | 52 | @Override 53 | public void doImport(ProgressMonitor progress) throws Exception { 54 | progress.beginTask("Setting up Gerrit replication", 2); 55 | 56 | String repositoryName = getOrganisation() + "/" + getRepositoryName(); 57 | Config remoteConfig = remoteConfigBuilder.build(repositoryName); 58 | progress.update(1); 59 | 60 | ReplicationRemotesApi updater = replicationRemotesUpdaterItem.get(); 61 | if (updater != null) { 62 | updater.update(remoteConfig); 63 | } 64 | progress.update(1); 65 | 66 | progress.endTask(); 67 | } 68 | 69 | @Override 70 | public boolean rollback() { 71 | return false; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubOAuthServiceProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github; 16 | 17 | import com.google.common.collect.Sets; 18 | import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; 19 | import com.google.gerrit.extensions.auth.oauth.OAuthToken; 20 | import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; 21 | import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; 22 | import com.google.gerrit.server.account.externalids.ExternalId; 23 | import com.google.inject.Inject; 24 | import com.googlesource.gerrit.plugins.github.oauth.GitHubOAuthConfig; 25 | import com.googlesource.gerrit.plugins.github.oauth.OAuthProtocol; 26 | import java.io.IOException; 27 | import org.kohsuke.github.GHMyself; 28 | import org.kohsuke.github.GitHub; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | public class GitHubOAuthServiceProvider implements OAuthServiceProvider { 33 | public static final String VERSION = "2.10.3"; 34 | private static final Logger log = LoggerFactory.getLogger(GitHubOAuthServiceProvider.class); 35 | 36 | private final GitHubOAuthConfig config; 37 | private final OAuthProtocol oauth; 38 | 39 | @Inject 40 | public GitHubOAuthServiceProvider(GitHubOAuthConfig config, OAuthProtocol oauth) { 41 | this.config = config; 42 | this.oauth = oauth; 43 | } 44 | 45 | @Override 46 | public String getAuthorizationUrl() { 47 | return oauth.getAuthorizationUrl( 48 | oauth.getScope(Sets.newHashSet(config.getDefaultScopes())), null, null); 49 | } 50 | 51 | @Override 52 | public OAuthToken getAccessToken(OAuthVerifier verifier) { 53 | try { 54 | return oauth.getAccessToken(verifier).toOAuthToken(); 55 | } catch (IOException e) { 56 | log.error("Invalid OAuth access verifier" + verifier.getValue(), e); 57 | return null; 58 | } 59 | } 60 | 61 | @Override 62 | public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException { 63 | String oauthToken = token.getToken(); 64 | GitHub hub = GitHub.connectUsingOAuth(oauthToken); 65 | GHMyself myself = hub.getMyself(); 66 | String login = myself.getLogin(); 67 | return new OAuthUserInfo( 68 | ExternalId.SCHEME_GERRIT + login, login, myself.getEmail(), myself.getName(), null); 69 | } 70 | 71 | @Override 72 | public String getVersion() { 73 | return VERSION; 74 | } 75 | 76 | @Override 77 | public String getName() { 78 | return "GitHub"; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/RepositoriesCloneController.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.wizard; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.googlesource.gerrit.plugins.github.git.GitImporter; 19 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 20 | import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider; 21 | import java.io.IOException; 22 | import java.util.Map.Entry; 23 | import java.util.Set; 24 | import javax.servlet.ServletException; 25 | import javax.servlet.http.HttpServletRequest; 26 | import javax.servlet.http.HttpServletResponse; 27 | 28 | public class RepositoriesCloneController implements VelocityController { 29 | private static final String REPO_PARAM_PREFIX = "repo_"; 30 | private final ScopedProvider cloneProvider; 31 | 32 | @Inject 33 | public RepositoriesCloneController(ScopedProvider cloneProvider) { 34 | this.cloneProvider = cloneProvider; 35 | } 36 | 37 | @Override 38 | public void doAction( 39 | IdentifiedUser user, 40 | GitHubLogin hubLogin, 41 | HttpServletRequest req, 42 | HttpServletResponse resp, 43 | ControllerErrors errorMgr) 44 | throws ServletException, IOException { 45 | 46 | GitImporter gitCloner = cloneProvider.get(req); 47 | gitCloner.reset(); 48 | Set> params = req.getParameterMap().entrySet(); 49 | for (Entry param : params) { 50 | String paramName = param.getKey(); 51 | String[] paramValue = param.getValue(); 52 | 53 | if (!paramName.startsWith(REPO_PARAM_PREFIX) 54 | || paramValue.length != 1 55 | || paramName.split("_").length != 2) { 56 | continue; 57 | } 58 | String repoIdxString = paramName.split("_")[1]; 59 | if (!Character.isDigit(repoIdxString.charAt(0))) { 60 | continue; 61 | } 62 | 63 | int repoIdx = Integer.parseInt(repoIdxString); 64 | String organisation = req.getParameter(REPO_PARAM_PREFIX + repoIdx + "_organisation"); 65 | String repository = req.getParameter(REPO_PARAM_PREFIX + repoIdx + "_repository"); 66 | String description = req.getParameter(REPO_PARAM_PREFIX + repoIdx + "_description"); 67 | try { 68 | gitCloner.clone(repoIdx, organisation, repository, description); 69 | } catch (Exception e) { 70 | errorMgr.submit(e); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/QuotaCheckStep.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import static com.google.gerrit.server.quota.QuotaGroupDefinitions.REPOSITORY_SIZE_GROUP; 17 | 18 | import com.google.gerrit.entities.Project; 19 | import com.google.gerrit.server.quota.QuotaBackend; 20 | import com.google.gerrit.server.quota.QuotaResponse; 21 | import com.google.inject.Inject; 22 | import com.google.inject.assistedinject.Assisted; 23 | import com.googlesource.gerrit.plugins.github.GitHubConfig; 24 | import org.eclipse.jgit.lib.ProgressMonitor; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | public class QuotaCheckStep extends ImportStep { 29 | private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckStep.class); 30 | private final QuotaBackend quotaBackend; 31 | 32 | private static final long BYTES_PER_KB = 1024L; 33 | 34 | public interface Factory { 35 | QuotaCheckStep create( 36 | @Assisted("organisation") String organisation, @Assisted("repository") String repository); 37 | } 38 | 39 | @Inject 40 | public QuotaCheckStep( 41 | QuotaBackend quotaBackend, 42 | GitHubConfig config, 43 | GitHubRepository.Factory gitHubRepoFactory, 44 | @Assisted("organisation") String organisation, 45 | @Assisted("repository") String repository) { 46 | super(config.gitHubUrl, organisation, repository, gitHubRepoFactory); 47 | this.quotaBackend = quotaBackend; 48 | } 49 | 50 | @Override 51 | public void doImport(ProgressMonitor progress) throws GitException { 52 | Project.NameKey fullProjectName = 53 | Project.nameKey(getOrganisation() + "/" + getRepositoryName()); 54 | try { 55 | progress.beginTask("Getting repository size", 1); 56 | LOG.debug("{}|Getting repository size", fullProjectName); 57 | long size = getRepository().getSize() * BYTES_PER_KB; 58 | LOG.debug("{}|Repository size: {} Kb", fullProjectName, size); 59 | 60 | LOG.debug("{}|Checking repository size is allowed by quota", fullProjectName); 61 | if (size > 0) { 62 | QuotaResponse.Aggregated aggregated = 63 | quotaBackend.currentUser().project(fullProjectName).dryRun(REPOSITORY_SIZE_GROUP, size); 64 | aggregated.throwOnError(); 65 | } 66 | progress.update(1); 67 | } catch (Exception e) { 68 | LOG.error("{}|Quota does not allow importing repo", fullProjectName, e); 69 | throw new QuotaEnforcedException(e.getMessage(), e); 70 | } finally { 71 | progress.endTask(); 72 | } 73 | LOG.debug("{}|SUCCESS repository size is allowed", fullProjectName); 74 | } 75 | 76 | @Override 77 | public boolean rollback() { 78 | return true; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/ReplicationRemoteConfigBuilder.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.common.base.Strings; 17 | import com.google.gerrit.extensions.registration.DynamicItem; 18 | import com.google.inject.Inject; 19 | import com.googlesource.gerrit.plugins.github.GitHubURL; 20 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 21 | import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider; 22 | import com.googlesource.gerrit.plugins.replication.api.ReplicationRemotesApi; 23 | import java.io.IOException; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import org.eclipse.jgit.lib.Config; 27 | 28 | class ReplicationRemoteConfigBuilder { 29 | private final String gitHubUrl; 30 | private final String username; 31 | private final String authToken; 32 | private final DynamicItem replicationConfigItem; 33 | 34 | @Inject 35 | ReplicationRemoteConfigBuilder( 36 | DynamicItem replicationRemotesItem, 37 | ScopedProvider ghLoginProvider, 38 | @GitHubURL String gitHubUrl) 39 | throws IOException { 40 | this.gitHubUrl = gitHubUrl; 41 | this.replicationConfigItem = replicationRemotesItem; 42 | GitHubLogin ghLogin = ghLoginProvider.get(); 43 | this.username = ghLogin.getMyself().getLogin(); 44 | this.authToken = ghLogin.getAccessToken(); 45 | } 46 | 47 | Config build(String repositoryName) { 48 | Config remoteConfig = replicationConfigItem.get().get(username); 49 | 50 | remoteConfig.setString("remote", username, "username", username); 51 | remoteConfig.setString("remote", username, "password", authToken); 52 | 53 | setRemoteConfigIfNotSet(remoteConfig, "url", gitHubUrl + "/${name}.git"); 54 | 55 | String[] existingProjects = getProjects(); 56 | List projects = new ArrayList<>(List.of(existingProjects)); 57 | projects.add(repositoryName); 58 | 59 | remoteConfig.setStringList("remote", username, "projects", projects); 60 | setRemoteConfigIfNotSet(remoteConfig, "push", "refs/*:refs/*"); 61 | 62 | return remoteConfig; 63 | } 64 | 65 | private void setRemoteConfigIfNotSet(Config remoteConfig, String key, String value) { 66 | String existingValue = remoteConfig.getString("remote", username, key); 67 | if (Strings.isNullOrEmpty(existingValue)) { 68 | remoteConfig.setString("remote", username, key, value); 69 | } 70 | } 71 | 72 | private String[] getProjects() { 73 | ReplicationRemotesApi config = replicationConfigItem.get(); 74 | if (config != null) { 75 | return config.get(username).getStringList("remote", username, "projects"); 76 | } 77 | 78 | return new String[0]; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/account.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GitHub plugin for Gerrit Code Review - Account review 6 | #include ("static/styles.html") 7 | #include ("static/scripts.html") 8 | 9 | 10 | 11 |
12 |
13 |
14 | #include ("static/header.html") 15 |
16 |
17 |

Account profile

18 |
19 | 22 | 25 |
26 |
27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 |
35 |
36 |
37 |
GitHub account details
38 |
    39 |
  • 40 | 41 | 43 |
  • 44 | 45 |
  • 46 | 47 | 49 |
  • 50 | 51 |
  • 52 | 53 | 62 |
  • 63 |
64 | 65 |
Import GitHub SSH Public Keys
66 |
    67 | #foreach ( $key in $myself.publicVerifiedKeys ) 68 | #if ( $key.key.length() > 45 ) 69 |
  • 70 | 71 | #set ( $trailStart = $key.key.length() - 10 ) 72 | 73 | 74 |
  • 75 | #end 76 | #end 77 |
78 |
79 |
80 |
81 | 82 | 83 | #include ("static/footer.html") 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GuiceModule.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github; 16 | 17 | import com.google.gerrit.extensions.registration.DynamicSet; 18 | import com.google.gerrit.extensions.restapi.RestApiModule; 19 | import com.google.gerrit.extensions.webui.TopMenu; 20 | import com.google.gerrit.server.account.GroupBackend; 21 | import com.google.gerrit.server.events.EventListener; 22 | import com.google.gerrit.server.project.ProjectResource; 23 | import com.google.gson.Gson; 24 | import com.google.inject.AbstractModule; 25 | import com.google.inject.Scopes; 26 | import com.google.inject.TypeLiteral; 27 | import com.google.inject.assistedinject.FactoryModuleBuilder; 28 | import com.googlesource.gerrit.plugins.github.group.GitHubGroupBackend; 29 | import com.googlesource.gerrit.plugins.github.group.GitHubGroupMembership; 30 | import com.googlesource.gerrit.plugins.github.group.GitHubGroupsCache; 31 | import com.googlesource.gerrit.plugins.github.group.GitHubOrganisationGroup; 32 | import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin; 33 | import com.googlesource.gerrit.plugins.github.oauth.IdentifiedUserGitHubLoginProvider; 34 | import com.googlesource.gerrit.plugins.github.oauth.UserScopedProvider; 35 | import com.googlesource.gerrit.plugins.github.replication.GerritGsonProvider; 36 | import com.googlesource.gerrit.plugins.github.replication.ListProjectReplicationStatus; 37 | import com.googlesource.gerrit.plugins.github.replication.ReplicationStatusFlatFile; 38 | import com.googlesource.gerrit.plugins.github.replication.ReplicationStatusListener; 39 | import com.googlesource.gerrit.plugins.github.replication.ReplicationStatusStore; 40 | 41 | public class GuiceModule extends AbstractModule { 42 | 43 | @Override 44 | protected void configure() { 45 | bind(new TypeLiteral>() {}) 46 | .to(IdentifiedUserGitHubLoginProvider.class); 47 | 48 | install(GitHubGroupsCache.module()); 49 | 50 | DynamicSet.bind(binder(), TopMenu.class).to(GitHubTopMenu.class); 51 | DynamicSet.bind(binder(), GroupBackend.class).to(GitHubGroupBackend.class); 52 | DynamicSet.bind(binder(), EventListener.class).to(ReplicationStatusListener.class); 53 | 54 | install(new FactoryModuleBuilder().build(GitHubOrganisationGroup.Factory.class)); 55 | install(new FactoryModuleBuilder().build(GitHubGroupMembership.Factory.class)); 56 | 57 | install( 58 | new RestApiModule() { 59 | @Override 60 | protected void configure() { 61 | get(ProjectResource.PROJECT_KIND, "replication").to(ListProjectReplicationStatus.class); 62 | } 63 | }); 64 | 65 | bind(ReplicationStatusStore.class).to(ReplicationStatusFlatFile.class).in(Scopes.SINGLETON); 66 | bind(Gson.class).toProvider(GerritGsonProvider.class); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /github-plugin/web/gr-github-oauth-progress.ts: -------------------------------------------------------------------------------- 1 | import { PluginApi } from '@gerritcodereview/typescript-api/plugin'; 2 | import { AuthInfo } from '@gerritcodereview/typescript-api/rest-api'; 3 | import { CSSResult, LitElement, css, html } from "lit"; 4 | import { customElement, property, query, state } from 'lit/decorators.js'; 5 | 6 | @customElement('gr-github-oauth-progress') 7 | export class GrGitHubOAuthProgress extends LitElement { 8 | @query('#gitHubOAuthProgress') 9 | gitHubOAuthProgress?: HTMLDialogElement; 10 | 11 | @property() plugin!: PluginApi; 12 | 13 | @state() authInfo?: AuthInfo; 14 | 15 | @state() loggedIn?: boolean; 16 | 17 | @state() currentNavigationPath?: string; 18 | 19 | override connectedCallback() { 20 | super.connectedCallback(); 21 | const restApi = this.plugin.restApi(); 22 | if (!this.authInfo) { 23 | restApi.getConfig().then(config => this.authInfo = config?.auth); 24 | } 25 | restApi.getLoggedIn().then(loggedIn => this.loggedIn = loggedIn); 26 | document.addEventListener( 27 | 'nav-report', 28 | // the `nav-report` event is emitted before `window.location` is updated, in order 29 | // to get the current location, we need to delay `this.updateLocationPath` execution 30 | // by putting it on the end of processing queue 31 | () => setTimeout(() => this.updateLocationPath(), 0)); 32 | this.updateLocationPath(); 33 | } 34 | 35 | static override get styles() { 36 | return [ 37 | window.Gerrit.styles.spinner as CSSResult, 38 | window.Gerrit.styles.font as CSSResult, 39 | window.Gerrit.styles.modal as CSSResult, 40 | css` 41 | .loginButton { 42 | --gr-button-text-color: var(--header-text-color); 43 | color: var(--header-text-color); 44 | padding: var(--spacing-m) var(--spacing-l); 45 | } 46 | .loadingContainer { 47 | display: flex; 48 | gap: var(--spacing-s); 49 | align-items: baseline; 50 | padding: var(--spacing-xxl); 51 | } 52 | .loadingSpin { 53 | vertical-align: top; 54 | position: relative; 55 | top: 3px; 56 | } 57 | `]; 58 | } 59 | 60 | override render() { 61 | if (!this.authInfo || this.loggedIn !== false) { 62 | return; 63 | } 64 | const loginWithRedirect = new URL(this.authInfo.login_url ?? "/", window.location.origin); 65 | if (this.currentNavigationPath) { 66 | loginWithRedirect.pathname = loginWithRedirect.pathname + this.currentNavigationPath; 67 | } 68 | 69 | return html` 70 | 71 | ${this.authInfo.login_text} 72 | 73 | 74 |
75 | 76 | Waiting for GitHub API response ... 77 |
78 |
79 | ` 80 | } 81 | 82 | private updateLocationPath() { 83 | this.currentNavigationPath = window.location.pathname; 84 | } 85 | 86 | private showModal() { 87 | setTimeout(() => this.gitHubOAuthProgress?.showModal(), 550); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/filters/GitHubGroupCacheRefreshFilter.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.filters; 16 | 17 | import com.google.common.annotations.VisibleForTesting; 18 | import com.google.common.flogger.FluentLogger; 19 | import com.google.gerrit.httpd.AllRequestFilter; 20 | import com.googlesource.gerrit.plugins.github.group.GitHubGroupsCache; 21 | import java.io.IOException; 22 | import java.util.Optional; 23 | import javax.inject.Inject; 24 | import javax.servlet.FilterChain; 25 | import javax.servlet.FilterConfig; 26 | import javax.servlet.ServletException; 27 | import javax.servlet.ServletRequest; 28 | import javax.servlet.ServletResponse; 29 | import javax.servlet.http.HttpServletRequest; 30 | import javax.servlet.http.HttpServletResponse; 31 | 32 | public class GitHubGroupCacheRefreshFilter extends AllRequestFilter { 33 | private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 34 | private static final String LOGIN_URL = "/login"; 35 | private static final String LOGIN_QUERY_FINAL = "final=true"; 36 | private static final String ACCOUNT_COOKIE = "GerritAccount"; 37 | private static final String INVALIDATE_CACHED_GROUPS = "RefreshGroups"; 38 | 39 | private final GitHubGroupsCache ghGroupsCache; 40 | 41 | @Inject 42 | @VisibleForTesting 43 | public GitHubGroupCacheRefreshFilter(GitHubGroupsCache ghGroupsCache) { 44 | this.ghGroupsCache = ghGroupsCache; 45 | } 46 | 47 | @Override 48 | public void init(FilterConfig filterConfig) throws ServletException {} 49 | 50 | @Override 51 | public void doFilter( 52 | ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 53 | throws IOException, ServletException { 54 | filterChain.doFilter(servletRequest, servletResponse); 55 | 56 | HttpServletRequest req = (HttpServletRequest) servletRequest; 57 | if (req.getRequestURI().endsWith(LOGIN_URL) && req.getQueryString().equals(LOGIN_QUERY_FINAL)) { 58 | HttpServletResponse resp = (HttpServletResponse) servletResponse; 59 | String cookieResponse = resp.getHeader("Set-Cookie"); 60 | if (cookieResponse != null && cookieResponse.contains(ACCOUNT_COOKIE)) { 61 | req.getSession().setAttribute(INVALIDATE_CACHED_GROUPS, Boolean.TRUE); 62 | } 63 | } else if (hasSessionFlagForInvalidatingCachedUserGroups(req)) { 64 | ghGroupsCache.invalidateCurrentUserGroups(); 65 | req.getSession().removeAttribute(INVALIDATE_CACHED_GROUPS); 66 | } 67 | } 68 | 69 | private static boolean hasSessionFlagForInvalidatingCachedUserGroups(HttpServletRequest req) { 70 | return Optional.ofNullable(req.getSession(false)) 71 | .flatMap(session -> Optional.ofNullable(session.getAttribute(INVALIDATE_CACHED_GROUPS))) 72 | .filter(refresh -> (Boolean) refresh) 73 | .isPresent(); 74 | } 75 | 76 | @Override 77 | public void destroy() {} 78 | } 79 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/js/jquery/jquery.schedule.js: -------------------------------------------------------------------------------- 1 | 2 | (function($){$.scheduler=function(){this.bucket={};return;};$.scheduler.prototype={schedule:function(){var ctx={"id":null,"time":1000,"repeat":false,"protect":false,"obj":null,"func":function(){},"args":[]};function _isfn(fn){return(!!fn&&typeof fn!="string"&&typeof fn[0]=="undefined"&&RegExp("function","i").test(fn+""));};var i=0;var override=false;if(typeof arguments[i]=="object"&&arguments.length>1){override=true;i++;} 3 | if(typeof arguments[i]=="object"){for(var option in arguments[i]) 4 | if(typeof ctx[option]!="undefined") 5 | ctx[option]=arguments[i][option];i++;} 6 | if(typeof arguments[i]=="number"||(typeof arguments[i]=="string"&&arguments[i].match(RegExp("^[0-9]+[smhdw]$")))) 7 | ctx["time"]=arguments[i++];if(typeof arguments[i]=="boolean") 8 | ctx["repeat"]=arguments[i++];if(typeof arguments[i]=="boolean") 9 | ctx["protect"]=arguments[i++];if(typeof arguments[i]=="object"&&typeof arguments[i+1]=="string"&&_isfn(arguments[i][arguments[i+1]])){ctx["obj"]=arguments[i++];ctx["func"]=arguments[i++];} 10 | else if(typeof arguments[i]!="undefined"&&(_isfn(arguments[i])||typeof arguments[i]=="string")) 11 | ctx["func"]=arguments[i++];while(typeof arguments[i]!="undefined") 12 | ctx["args"].push(arguments[i++]);if(override){if(typeof arguments[1]=="object"){for(var option in arguments[0]) 13 | if(typeof ctx[option]!="undefined"&&typeof arguments[1][option]=="undefined") 14 | ctx[option]=arguments[0][option];} 15 | else{for(var option in arguments[0]) 16 | if(typeof ctx[option]!="undefined") 17 | ctx[option]=arguments[0][option];} 18 | i++;} 19 | ctx["_scheduler"]=this;ctx["_handle"]=null;var match=String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$"));if(match&&match[0]!="undefined"&&match[1]!="undefined") 20 | ctx["time"]=String(parseInt(match[1])*{s:1000,m:1000*60,h:1000*60*60,d:1000*60*60*24,w:1000*60*60*24*7}[match[2]]);if(ctx["id"]==null) 21 | ctx["id"]=(String(ctx["repeat"])+":" 22 | +String(ctx["protect"])+":" 23 | +String(ctx["time"])+":" 24 | +String(ctx["obj"])+":" 25 | +String(ctx["func"])+":" 26 | +String(ctx["args"]));if(ctx["protect"]) 27 | if(typeof this.bucket[ctx["id"]]!="undefined") 28 | return this.bucket[ctx["id"]];if(!_isfn(ctx["func"])){if(ctx["obj"]!=null&&typeof ctx["obj"]=="object"&&typeof ctx["func"]=="string"&&_isfn(ctx["obj"][ctx["func"]])) 29 | ctx["func"]=ctx["obj"][ctx["func"]];else 30 | ctx["func"]=eval("function () { "+ctx["func"]+" }");} 31 | ctx["_handle"]=this._schedule(ctx);this.bucket[ctx["id"]]=ctx;return ctx;},reschedule:function(ctx){if(typeof ctx=="string") 32 | ctx=this.bucket[ctx];ctx["_handle"]=this._schedule(ctx);return ctx;},_schedule:function(ctx){var trampoline=function(){var obj=(ctx["obj"]!=null?ctx["obj"]:ctx);(ctx["func"]).apply(obj,ctx["args"]);if(typeof(ctx["_scheduler"]).bucket[ctx["id"]]!="undefined"&&ctx["repeat"]) 33 | (ctx["_scheduler"])._schedule(ctx);else 34 | delete(ctx["_scheduler"]).bucket[ctx["id"]];};return setTimeout(trampoline,ctx["time"]);},cancel:function(ctx){if(typeof ctx=="string") 35 | ctx=this.bucket[ctx];if(typeof ctx=="object"){clearTimeout(ctx["_handle"]);delete this.bucket[ctx["id"]];}}};$.extend({scheduler$:new $.scheduler(),schedule:function(){return $.scheduler$.schedule.apply($.scheduler$,arguments)},reschedule:function(){return $.scheduler$.reschedule.apply($.scheduler$,arguments)},cancel:function(){return $.scheduler$.cancel.apply($.scheduler$,arguments)}});$.fn.extend({schedule:function(){var a=[{}];for(var i=0;i gsonProvider) { 44 | this.pluginData = pluginData; 45 | this.gson = gsonProvider.get(); 46 | } 47 | 48 | @Override 49 | public void set(Project.NameKey projectKey, String refKey, JsonObject statusEvent) 50 | throws IOException { 51 | Path replicationStatusPath = getReplicationStatusPath(projectKey.get() + "/" + refKey); 52 | Files.write( 53 | replicationStatusPath, statusEvent.toString().getBytes(), TRUNCATE_EXISTING, CREATE, WRITE); 54 | } 55 | 56 | private Path getReplicationStatusPath(String key) throws IOException { 57 | Path projectPath = pluginData.resolve(getSanitizedKey(key) + ".replication-error.json"); 58 | Files.createDirectories(projectPath.getParent()); 59 | return projectPath; 60 | } 61 | 62 | private String getSanitizedKey(String key) { 63 | String sanitizedKey = key.replace(".", "_").replace(" ", "_"); 64 | return sanitizedKey; 65 | } 66 | 67 | @Override 68 | public List list(Project.NameKey parentKey) throws IOException { 69 | Path projectPath = pluginData.resolve(getSanitizedKey(parentKey.get())); 70 | final List entries = new ArrayList<>(); 71 | Files.walkFileTree( 72 | projectPath, 73 | new SimpleFileVisitor() { 74 | 75 | @Override 76 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 77 | throws IOException { 78 | try (Reader fileReader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) { 79 | JsonObject json = gson.fromJson(fileReader, JsonObject.class); 80 | entries.add(json); 81 | } 82 | return FileVisitResult.CONTINUE; 83 | } 84 | }); 85 | return entries; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /github-plugin/BUILD: -------------------------------------------------------------------------------- 1 | load( 2 | "//plugins/github:java_library_without_header_compilation.bzl", 3 | "java_library_without_header_compilation", 4 | ) 5 | load("//tools/bzl:junit.bzl", "junit_tests") 6 | load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS", "PLUGIN_DEPS_NEVERLINK", "PLUGIN_TEST_DEPS", "gerrit_plugin") 7 | 8 | SOURCES_WITH_LOMBOK_USAGE = [ 9 | "src/main/java/com/googlesource/gerrit/plugins/github/git/GitHubRepository.java", 10 | "src/main/java/com/googlesource/gerrit/plugins/github/GitHubURL.java", 11 | ] 12 | 13 | gerrit_plugin( 14 | name = "github-plugin", 15 | srcs = glob( 16 | ["src/main/java/**/*.java"], 17 | exclude = SOURCES_WITH_LOMBOK_USAGE, 18 | ), 19 | dir_name = "github", 20 | manifest_entries = [ 21 | "Gerrit-PluginName: github-plugin", 22 | "Gerrit-Module: com.googlesource.gerrit.plugins.github.GuiceModule", 23 | "Gerrit-HttpModule: com.googlesource.gerrit.plugins.github.GuiceHttpModule", 24 | "Gerrit-InitStep: com.googlesource.gerrit.plugins.github.InitGitHub", 25 | "Implementation-Title: GitHub plugin", 26 | "Implementation-Vendor: GerritForge", 27 | "Implementation-URL: http://www.gerritforge.com", 28 | ], 29 | resource_jars = ["//plugins/github/github-plugin/web:github-plugin"], 30 | resources = glob(["src/main/resources/**/*"]), 31 | deps = [ 32 | ":github-plugin-lib", 33 | ":replication-api", 34 | "//plugins/github/github-oauth:github-oauth-lib", 35 | "@axis-jaxrpc//jar", 36 | "@axis//jar", 37 | "@com-sun-mail//jar", 38 | "@commons-codec//jar", 39 | "@commons-discovery//jar", 40 | "@commons-io//jar", 41 | "@eclipse-mylyn-github//jar", 42 | "@github-api//jar", 43 | "@javax-activation//jar", 44 | "@velocity//jar", 45 | ], 46 | ) 47 | 48 | java_library_without_header_compilation( 49 | name = "github-plugin-lib", 50 | dep = ":github-plugin-lib_impl", 51 | visibility = ["//visibility:public"], 52 | ) 53 | 54 | java_library( 55 | name = "github-plugin-lib_impl", 56 | srcs = SOURCES_WITH_LOMBOK_USAGE, 57 | deps = PLUGIN_DEPS_NEVERLINK + [ 58 | ":lombok", 59 | "//plugins/github/github-oauth:github-oauth-lib", 60 | "@axis-jaxrpc//jar", 61 | "@axis//jar", 62 | "@commons-codec//jar", 63 | "@commons-discovery//jar", 64 | "@commons-io//jar", 65 | "@eclipse-mylyn-github//jar", 66 | "@github-api//jar", 67 | "@velocity//jar", 68 | ], 69 | ) 70 | 71 | junit_tests( 72 | name = "github-plugin_tests", 73 | srcs = glob(["src/test/java/**/*.java"]), 74 | tags = ["github"], 75 | deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [ 76 | ":github-plugin-lib", 77 | ":github-plugin__plugin", 78 | "//javatests/com/google/gerrit/util/http/testutil", 79 | "//plugins/github/github-oauth:github-oauth-lib", 80 | "//plugins/replication:replication-api", 81 | "@commons-io//jar", 82 | "@github-api//jar", 83 | ], 84 | ) 85 | 86 | java_plugin( 87 | name = "lombok_plugin", 88 | generates_api = True, 89 | processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", 90 | deps = ["@lombok//jar"], 91 | ) 92 | 93 | java_library( 94 | name = "lombok", 95 | exported_plugins = [":lombok_plugin"], 96 | neverlink = True, 97 | exports = ["@lombok//jar"], 98 | ) 99 | 100 | java_library( 101 | name = "replication-api", 102 | neverlink = True, 103 | exports = ["//plugins/replication:replication-api"], 104 | ) 105 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/PooledHttpClientProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import com.google.common.base.Strings; 18 | import com.google.gerrit.httpd.ProxyProperties; 19 | import com.google.gerrit.server.config.GerritServerConfig; 20 | import com.google.inject.Inject; 21 | import com.google.inject.Provider; 22 | import java.net.URL; 23 | import org.apache.http.HttpHost; 24 | import org.apache.http.auth.AuthScope; 25 | import org.apache.http.auth.UsernamePasswordCredentials; 26 | import org.apache.http.client.CredentialsProvider; 27 | import org.apache.http.client.HttpClient; 28 | import org.apache.http.impl.client.BasicCredentialsProvider; 29 | import org.apache.http.impl.client.HttpClientBuilder; 30 | import org.apache.http.impl.client.ProxyAuthenticationStrategy; 31 | import org.eclipse.jgit.lib.Config; 32 | 33 | public class PooledHttpClientProvider implements Provider { 34 | private final int maxTotalConnection; 35 | private final int maxConnectionPerRoute; 36 | private final ProxyProperties proxy; 37 | 38 | @Inject 39 | PooledHttpClientProvider(@GerritServerConfig Config config, ProxyProperties proxyProperties) { 40 | this.proxy = proxyProperties; 41 | URL proxyUrl = proxyProperties.getProxyUrl(); 42 | if (proxyUrl != null) { 43 | setProxyProperty("proxyHost", proxyUrl.getHost()); 44 | setProxyProperty("proxyPort", "" + proxyUrl.getPort()); 45 | setProxyProperty("proxyUser", proxyProperties.getUsername()); 46 | setProxyProperty("proxyPassword", proxyProperties.getPassword()); 47 | } 48 | 49 | maxConnectionPerRoute = config.getInt("http", null, "pooledMaxConnectionsPerRoute", 16); 50 | maxTotalConnection = config.getInt("http", null, "pooledMaxTotalConnections", 32); 51 | } 52 | 53 | private static void setProxyProperty(String property, String value) { 54 | if (value != null) { 55 | System.setProperty("http." + property, value); 56 | System.setProperty("https." + property, value); 57 | } 58 | } 59 | 60 | @Override 61 | public HttpClient get() { 62 | HttpClientBuilder builder = 63 | HttpClientBuilder.create() 64 | .setMaxConnPerRoute(maxConnectionPerRoute) 65 | .setMaxConnTotal(maxTotalConnection); 66 | 67 | if (proxy.getProxyUrl() != null) { 68 | URL url = proxy.getProxyUrl(); 69 | builder.setProxy(new HttpHost(url.getHost(), url.getPort())); 70 | if (!Strings.isNullOrEmpty(proxy.getUsername()) 71 | && !Strings.isNullOrEmpty(proxy.getPassword())) { 72 | UsernamePasswordCredentials creds = 73 | new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword()); 74 | CredentialsProvider credsProvider = new BasicCredentialsProvider(); 75 | credsProvider.setCredentials(new AuthScope(url.getHost(), url.getPort()), creds); 76 | builder.setDefaultCredentialsProvider(credsProvider); 77 | builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); 78 | } 79 | } 80 | 81 | return builder.build(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/scope.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GitHub plugin for Gerrit Code Review - Login Scope 6 | #include ("static/styles.html") 7 | #include ("static/scripts.html") 8 | 9 | 17 | 18 | 19 |
20 |
21 |
22 | #include ("static/header.html") 23 |
24 |
25 |

Login Scope Selection

26 |
27 | 30 | 33 |
34 |
35 |
36 |
37 |
38 |
39 | 40 | 41 | 42 |
43 |
44 |
45 |
Which level of GitHub access do you need?
46 |
    47 | #foreach ( $scope in $scopes.keySet() ) 48 |
  • 49 | #set ( $scopeName = $scope.name().substring(6) ) 50 | #set ( $scopeDescription = $scope.description() ) 51 | #set ( $checked = "" ) 52 | #if ( ( $scopeCookie && $scopeCookie == $scope.name() ) || $scopeName == "" ) 53 | #set ( $checked = "checked" ) 54 | #end 55 | 56 | #if ( $scopeName == "") 57 |

    DEFAULT

    58 | #else 59 |

    $scopeName

    60 | #end 61 |

    $scopeDescription

    62 |

    Allow to: 63 | #set ( $scopeItems = $scopes.get($scope) ) 64 | #foreach ( $scopeItem in $scopeItems ) 65 | $scopeItem.description 66 | #if ( $foreach.count < $scopeItems.size()) 67 | ,  68 | #end 69 | #end 70 |

    71 |
  • 72 | #end 73 | 74 |
75 |
    76 |
  • 77 | 78 |
  • 79 |
80 |
81 |
82 |
83 | 84 | 85 | #include ("static/footer.html") 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/pullrequests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GitHub plugin for Gerrit Code Review - Pull Requests replication 6 | #include ("static/styles.html") 7 | #include ("static/scripts.html") 8 | 9 | 10 | 11 |
12 |
13 |
14 | #include ("static/header.html") 15 |
16 |
17 |

18 | Account > Repositories Replication > Opened Pull Requests 19 |

20 |
21 | 24 | 27 |
28 |
29 |
30 |
31 |
32 |
33 | 34 | 35 | 36 |
37 |
38 |
39 |
40 |
    41 |
  • 42 | 52 |
  • 53 | 56 |
57 |
    58 |
59 |
60 |
61 |
62 |

Loading Pull Requests from GitHub ...

63 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 76 | 77 | 78 | 79 | 80 | 81 |
82 |
83 |
84 |
85 | 86 | 87 | 88 | 89 | #include ("static/footer.html") 90 | 91 | 92 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/IdentifiedUserGitHubLoginProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import com.google.gerrit.common.Nullable; 18 | import com.google.gerrit.server.IdentifiedUser; 19 | import com.google.gerrit.server.account.AccountCache; 20 | import com.google.gerrit.server.account.AccountState; 21 | import com.google.gerrit.server.account.externalids.ExternalId; 22 | import com.google.inject.Inject; 23 | import com.google.inject.Provider; 24 | import com.google.inject.Singleton; 25 | import com.googlesource.gerrit.plugins.github.oauth.OAuthProtocol.AccessToken; 26 | import java.io.IOException; 27 | import java.util.Collection; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | @Singleton 32 | public class IdentifiedUserGitHubLoginProvider implements UserScopedProvider { 33 | private static final Logger log = 34 | LoggerFactory.getLogger(IdentifiedUserGitHubLoginProvider.class); 35 | public static final String EXTERNAL_ID_PREFIX = 36 | ExternalId.SCHEME_EXTERNAL + ":" + OAuthWebFilter.GITHUB_EXT_ID; 37 | 38 | private final Provider userProvider; 39 | private final AccountCache accountCache; 40 | private final OAuthTokenCipher oAuthTokenCipher; 41 | private final Provider gitHubLoginProvider; 42 | 43 | @Inject 44 | public IdentifiedUserGitHubLoginProvider( 45 | Provider gitHubLoginaprovider, 46 | Provider identifiedUserProvider, 47 | AccountCache accountCache, 48 | OAuthTokenCipher oAuthTokenCipher) { 49 | this.userProvider = identifiedUserProvider; 50 | this.accountCache = accountCache; 51 | this.oAuthTokenCipher = oAuthTokenCipher; 52 | this.gitHubLoginProvider = gitHubLoginaprovider; 53 | } 54 | 55 | @Override 56 | public GitHubLogin get() { 57 | IdentifiedUser currentUser = userProvider.get(); 58 | return get(currentUser.getUserName().get()); 59 | } 60 | 61 | @Override 62 | @Nullable 63 | public GitHubLogin get(String username) { 64 | try { 65 | AccessToken accessToken = newAccessTokenFromUser(username); 66 | if (accessToken != null) { 67 | GitHubLogin login = gitHubLoginProvider.get(); 68 | login.login(accessToken.accessToken); 69 | return login; 70 | } 71 | return null; 72 | } catch (IOException e) { 73 | log.error("Cannot login to GitHub as '" + username + "'", e); 74 | return null; 75 | } 76 | } 77 | 78 | private AccessToken newAccessTokenFromUser(String username) throws IOException { 79 | AccountState account = accountCache.getByUsername(username).get(); 80 | Collection externalIds = account.externalIds(); 81 | for (ExternalId accountExternalId : externalIds) { 82 | String key = accountExternalId.key().get(); 83 | if (key.startsWith(EXTERNAL_ID_PREFIX)) { 84 | String encryptedOauthToken = key.substring(EXTERNAL_ID_PREFIX.length()); 85 | String decryptedOauthToken = oAuthTokenCipher.decrypt(encryptedOauthToken); 86 | return new AccessToken(decryptedOauthToken); 87 | } 88 | } 89 | return null; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitImporter.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package com.googlesource.gerrit.plugins.github.git; 15 | 16 | import com.google.gerrit.server.IdentifiedUser; 17 | import com.google.inject.Inject; 18 | import com.google.inject.Singleton; 19 | import com.googlesource.gerrit.plugins.github.oauth.HttpSessionProvider; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | public class GitImporter extends BatchImporter { 24 | 25 | @Singleton 26 | public static class Provider extends HttpSessionProvider {} 27 | 28 | private static final Logger log = LoggerFactory.getLogger(GitImporter.class); 29 | private final ProtectedBranchesCheckStep.Factory protectedBranchesCheckFactory; 30 | private final MagicRefCheckStep.Factory magicRefCheckFactory; 31 | private final QuotaCheckStep.Factory quotaCheckFactory; 32 | private final GitCloneStep.Factory cloneFactory; 33 | private final CreateProjectStep.Factory projectFactory; 34 | private final ReplicateProjectStep.Factory replicateFactory; 35 | 36 | @Inject 37 | public GitImporter( 38 | ProtectedBranchesCheckStep.Factory protectedBranchesCheckFactory, 39 | GitCloneStep.Factory cloneFactory, 40 | CreateProjectStep.Factory projectFactory, 41 | ReplicateProjectStep.Factory replicateFactory, 42 | MagicRefCheckStep.Factory magicRefCheckFactory, 43 | QuotaCheckStep.Factory quotaCheckFactory, 44 | JobExecutor executor, 45 | IdentifiedUser user) { 46 | super(executor, user); 47 | this.protectedBranchesCheckFactory = protectedBranchesCheckFactory; 48 | this.cloneFactory = cloneFactory; 49 | this.projectFactory = projectFactory; 50 | this.replicateFactory = replicateFactory; 51 | this.magicRefCheckFactory = magicRefCheckFactory; 52 | this.quotaCheckFactory = quotaCheckFactory; 53 | } 54 | 55 | public void clone(int idx, String organisation, String repository, String description) { 56 | try { 57 | ProtectedBranchesCheckStep protectedBranchesCheckStep = 58 | protectedBranchesCheckFactory.create(organisation, repository); 59 | GitCloneStep cloneStep = cloneFactory.create(organisation, repository); 60 | MagicRefCheckStep magicRefCheckStep = magicRefCheckFactory.create(organisation, repository); 61 | CreateProjectStep projectStep = 62 | projectFactory.create(organisation, repository, description, user.getUserName().get()); 63 | QuotaCheckStep quotaCheckStep = quotaCheckFactory.create(organisation, repository); 64 | ReplicateProjectStep replicateStep = replicateFactory.create(organisation, repository); 65 | GitImportJob gitCloneJob = 66 | new GitImportJob( 67 | idx, 68 | organisation, 69 | repository, 70 | quotaCheckStep, 71 | protectedBranchesCheckStep, 72 | magicRefCheckStep, 73 | cloneStep, 74 | projectStep, 75 | replicateStep); 76 | log.debug("New Git clone job created: " + gitCloneJob); 77 | schedule(idx, gitCloneJob); 78 | } catch (Throwable e) { 79 | schedule(idx, new ErrorJob(idx, organisation, repository, e)); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /github-oauth/src/test/java/com/googlesource/gerrit/plugins/github/oauth/PasswordGeneratorTest.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import static com.googlesource.gerrit.plugins.github.oauth.GitHubOAuthConfig.KeyConfig.PASSWORD_LENGTH_DEFAULT; 18 | import static org.junit.Assert.assertArrayEquals; 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertFalse; 21 | import static org.junit.Assert.assertThrows; 22 | import static org.junit.Assert.assertTrue; 23 | 24 | import java.io.IOException; 25 | import java.nio.file.Files; 26 | import java.nio.file.Path; 27 | import java.util.Arrays; 28 | import org.junit.Before; 29 | import org.junit.Rule; 30 | import org.junit.Test; 31 | import org.junit.rules.TemporaryFolder; 32 | 33 | public class PasswordGeneratorTest { 34 | @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); 35 | 36 | private Path passwordPath; 37 | private final PasswordGenerator objectUnderTest = new PasswordGenerator(); 38 | 39 | @Before 40 | public void setup() throws IOException { 41 | passwordPath = 42 | temporaryFolder.newFolder().toPath().resolve(PasswordGenerator.DEFAULT_PASSWORD_FILE); 43 | } 44 | 45 | @Test 46 | public void shouldGenerateKeyFileWithPasswordDefaultLength() throws IOException { 47 | assertTrue(objectUnderTest.generate(passwordPath)); 48 | assertTrue(Files.isRegularFile(passwordPath)); 49 | 50 | byte[] token = Files.readAllBytes(passwordPath); 51 | assertEquals( 52 | String.format( 53 | "Generated password length doesn't equal to expected %d", PASSWORD_LENGTH_DEFAULT), 54 | token.length, 55 | PASSWORD_LENGTH_DEFAULT); 56 | } 57 | 58 | @Test 59 | public void shouldNotGenerateNewDefaultKeyIfOneAlreadyExistAndIsNotEmpty() throws IOException { 60 | assertTrue(objectUnderTest.generate(passwordPath)); 61 | byte[] expected = Files.readAllBytes(passwordPath); 62 | assertFalse(objectUnderTest.generate(passwordPath)); 63 | byte[] token = Files.readAllBytes(passwordPath); 64 | assertArrayEquals("Existing password file was overwritten", expected, token); 65 | } 66 | 67 | @Test 68 | public void shouldGenerateDifferentContentForDifferentSites() throws IOException { 69 | assertTrue(objectUnderTest.generate(passwordPath)); 70 | byte[] siteA = Files.readAllBytes(passwordPath); 71 | 72 | assertTrue(passwordPath.toFile().delete()); 73 | assertTrue(objectUnderTest.generate(passwordPath)); 74 | byte[] siteB = Files.readAllBytes(passwordPath); 75 | assertFalse( 76 | "The same password was generated for two different sites", Arrays.equals(siteA, siteB)); 77 | } 78 | 79 | @Test 80 | public void shouldThrowIllegalStateExceptionWhenDefaultKeyIsDirectory() throws IOException { 81 | // create dir from passwordPath 82 | assertTrue(passwordPath.toFile().mkdir()); 83 | 84 | IllegalStateException illegalStateException = 85 | assertThrows(IllegalStateException.class, () -> objectUnderTest.generate(passwordPath)); 86 | 87 | assertTrue( 88 | illegalStateException 89 | .getMessage() 90 | .endsWith("is directory whilst a regular file was expected.")); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /github-plugin/src/main/resources/static/repositories.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GitHub plugin for Gerrit Code Review - Repositories replication 6 | #include ("static/styles.html") 7 | #include ("static/scripts.html") 8 | 9 | 10 | 11 |
12 |
13 |
14 | #include ("static/header.html") 15 |
16 |
17 |

Account > Repositories Replication

18 |
19 | 22 | 25 |
26 |
27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 |
35 |
36 |
37 |
Select GitHub repositories to clone and replicate
38 |
    39 |
  • 40 | 41 | 47 | 48 | 49 | 54 | 55 |
  • 56 |
  • Not seeing your organizations or repositories? Login with a different GitHub Scope and try again.

  • 57 |
58 |
59 |

Loading list of GitHub repositories ...

60 |
61 |
    62 |
63 | 75 |
76 |
77 |
78 | 79 | 80 | 81 | 82 | #include ("static/footer.html") 83 | 84 | 85 | -------------------------------------------------------------------------------- /external_plugin_deps.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:java.bzl", "java_import_external") 2 | load("//tools/bzl:maven_jar.bzl", "maven_jar") 3 | 4 | JENKINS = "JENKINS:" 5 | ECLIPSE_EGIT = "ECLIPSE_EGIT:" 6 | 7 | def external_plugin_deps(): 8 | maven_jar( 9 | name = "github-api", 10 | artifact = "org.kohsuke:github-api:1.316", 11 | sha1 = "90ea530f3aeceb46be27b924ae25b4b7b2388c9d", 12 | ) 13 | 14 | maven_jar( 15 | name = "axis", 16 | artifact = "org.apache.axis:axis:1.4", 17 | sha1 = "94a9ce681a42d0352b3ad22659f67835e560d107", 18 | attach_source = False, 19 | ) 20 | 21 | maven_jar( 22 | name = "axis-jaxrpc", 23 | artifact = "org.apache.axis:axis-jaxrpc:1.4", 24 | sha1 = "b393f1f0c0d95b68c86d0b1ab2e687bb71f3c075", 25 | attach_source = False, 26 | ) 27 | 28 | maven_jar( 29 | name = "eclipse-mylyn-github", 30 | artifact = "org.eclipse.mylyn.github:org.eclipse.egit.github.core:6.1.0.202203080745-r", 31 | repository = ECLIPSE_EGIT, 32 | sha1 = "a0bc7ce9f17e2d41bbfbf08e4bc63c3ae0ec15b7", 33 | attach_source = False, 34 | ) 35 | 36 | maven_jar( 37 | name = "commons-discovery", 38 | artifact = "commons-discovery:commons-discovery:0.5", 39 | sha1 = "3a8ac816bbe02d2f88523ef22cbf2c4abd71d6a8", 40 | attach_source = False, 41 | ) 42 | 43 | maven_jar( 44 | name = "velocity", 45 | artifact = "org.apache.velocity:velocity-engine-core:2.3", 46 | sha1 = "e2133b723d0e42be74880d34de6bf6538ea7f915", 47 | ) 48 | 49 | maven_jar( 50 | name = "lombok", 51 | artifact = "org.projectlombok:lombok:1.18.32", 52 | sha1 = "17d46b3e205515e1e8efd3ee4d57ce8018914163", 53 | ) 54 | 55 | maven_jar( 56 | name = "com-sun-mail", 57 | artifact = "com.sun.mail:javax.mail:1.6.2", 58 | sha1 = "935151eb71beff17a2ffac15dd80184a99a0514f", 59 | ) 60 | 61 | maven_jar( 62 | name = "javax-activation", 63 | artifact = "javax.activation:activation:1.1", 64 | sha1 = "e6cb541461c2834bdea3eb920f1884d1eb508b50", 65 | ) 66 | 67 | maven_jar( 68 | name = "jackson-core", 69 | artifact = "com.fasterxml.jackson.core:jackson-core:2.15.2", 70 | sha1 = "a6fe1836469a69b3ff66037c324d75fc66ef137c", 71 | ) 72 | 73 | maven_jar( 74 | name = "jackson-databind", 75 | artifact = "com.fasterxml.jackson.core:jackson-databind:2.15.2", 76 | sha1 = "9353b021f10c307c00328f52090de2bdb4b6ff9c", 77 | ) 78 | 79 | maven_jar( 80 | name = "jackson-annotations", 81 | artifact = "com.fasterxml.jackson.core:jackson-annotations:2.15.2", 82 | sha1 = "4724a65ac8e8d156a24898d50fd5dbd3642870b8", 83 | ) 84 | 85 | maven_jar( 86 | name = "org-ow2-asm", 87 | artifact = "org.ow2.asm:asm:9.6", 88 | sha1 = "aa205cf0a06dbd8e04ece91c0b37c3f5d567546a", 89 | ) 90 | 91 | maven_jar( 92 | name = "org-ow2-asm-tree", 93 | artifact = "org.ow2.asm:asm-tree:9.6", 94 | sha1 = "c0cdda9d211e965d2a4448aa3fd86110f2f8c2de", 95 | ) 96 | 97 | maven_jar( 98 | name = "org-ow2-asm-commons", 99 | artifact = "org.ow2.asm:asm-commons:9.6", 100 | sha1 = "f1a9e5508eff490744144565c47326c8648be309", 101 | ) 102 | 103 | maven_jar( 104 | name = "bridge-method-injector", 105 | artifact = "com.infradna.tool:bridge-method-injector:1.29", 106 | repository = JENKINS, 107 | sha1 = "5b6c616c7a6e04beb4178327d616af4f1bbe88da", 108 | ) 109 | 110 | maven_jar( 111 | name = "bridge-method-annotation", 112 | artifact = "com.infradna.tool:bridge-method-annotation:1.29", 113 | repository = JENKINS, 114 | sha1 = "55dd67d0578d107697803a95cb9c235a9bd83ec1", 115 | ) 116 | -------------------------------------------------------------------------------- /github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/PasswordGenerator.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.googlesource.gerrit.plugins.github.oauth; 16 | 17 | import static com.googlesource.gerrit.plugins.github.oauth.GitHubOAuthConfig.KeyConfig.PASSWORD_LENGTH_DEFAULT; 18 | import static java.util.Objects.requireNonNull; 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.nio.file.Files; 23 | import java.nio.file.Path; 24 | import java.security.SecureRandom; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | public class PasswordGenerator { 29 | private static final Logger logger = LoggerFactory.getLogger(PasswordGenerator.class); 30 | public static final String DEFAULT_PASSWORD_FILE = "default.key"; 31 | 32 | /** 33 | * Generates default password and stores under given {@code Path}. Note that if password already 34 | * exists it is not regenerated. 35 | * 36 | * @param passwordFilePath path that should contain the default password; cannot be {@code null} 37 | * @throws {@link IllegalStateException} when file denoted by given {@code Path} is a directory, 38 | * cannot be read, has invalid length or doesn't exist and cannot be created 39 | * @return {@code true} if password was generated, {@code false} if it already exists 40 | */ 41 | public boolean generate(Path passwordFilePath) { 42 | requireNonNull(passwordFilePath); 43 | 44 | File passwordFile = passwordFilePath.toFile(); 45 | 46 | if (passwordFile.isDirectory()) { 47 | throw logErrorAndCreateRuntimeException( 48 | "'%s' is directory whilst a regular file was expected.", passwordFilePath); 49 | } 50 | 51 | if (passwordFile.isFile()) { 52 | if (!passwordFile.canRead()) { 53 | throw logErrorAndCreateRuntimeException( 54 | "'%s' password file exists, but cannot be read.", passwordFilePath); 55 | } 56 | 57 | long length = passwordFile.length(); 58 | if (length != PASSWORD_LENGTH_DEFAULT) { 59 | throw logErrorAndCreateRuntimeException( 60 | "'%s' password file exists but has an invalid length of %d bytes. The expected length" 61 | + " is %d bytes.", 62 | passwordFilePath, length, PASSWORD_LENGTH_DEFAULT); 63 | } 64 | return false; 65 | } 66 | 67 | byte[] token = generateToken(); 68 | try { 69 | Files.write(passwordFilePath, token); 70 | logger.info("Password was stored in {} file", passwordFilePath); 71 | return true; 72 | } catch (IOException e) { 73 | throw logErrorAndCreateRuntimeException(e, "Password generation has failed"); 74 | } 75 | } 76 | 77 | private byte[] generateToken() { 78 | SecureRandom random = new SecureRandom(); 79 | byte[] token = new byte[PASSWORD_LENGTH_DEFAULT]; 80 | random.nextBytes(token); 81 | return token; 82 | } 83 | 84 | private IllegalStateException logErrorAndCreateRuntimeException( 85 | String msg, Object... parameters) { 86 | return logErrorAndCreateRuntimeException(null, msg, parameters); 87 | } 88 | 89 | private IllegalStateException logErrorAndCreateRuntimeException( 90 | Exception e, String msg, Object... parameters) { 91 | String log = String.format(msg, parameters); 92 | if (e != null) { 93 | logger.error(log, e); 94 | return new IllegalStateException(log, e); 95 | } 96 | 97 | logger.error(log); 98 | return new IllegalStateException(log); 99 | } 100 | } 101 | --------------------------------------------------------------------------------