Skip to content

Commit

Permalink
Internal change
Browse files Browse the repository at this point in the history
(cherry picked from commit 6c34ae5)
  • Loading branch information
mai93 committed Jun 13, 2024
1 parent 56fc692 commit ea89058
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 63 deletions.
4 changes: 3 additions & 1 deletion base/src/META-INF/blaze-base.xml
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@
<applicationService serviceInterface="com.google.idea.blaze.base.wizard2.BlazeWizardOptionProvider"
serviceImplementation="com.google.idea.blaze.base.wizard2.BazelWizardOptionProvider"/>
<applicationService serviceInterface="com.google.idea.blaze.base.project.ExtendableBazelProjectCreator"
serviceImplementation="com.google.idea.blaze.base.project.DefaultBazelProjectCreator"/>
serviceImplementation="com.google.idea.blaze.base.project.TrustAwareProjectCreator"/>
<projectService serviceInterface="com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverProvider"
serviceImplementation="com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverProviderImpl"/>
<projectService serviceInterface="com.google.idea.blaze.base.sync.projectview.WorkspaceFileFinder$Provider"
Expand Down Expand Up @@ -552,6 +552,7 @@
<extensionPoint qualifiedName="com.google.idea.blaze.ProjectDataDirectoryValidator" interface="com.google.idea.blaze.base.wizard2.ProjectDataDirectoryValidator"/>
<extensionPoint qualifiedName="com.google.idea.blaze.AspectStrategyProvider" interface="com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategyProvider"/>
<extensionPoint qualifiedName="com.google.idea.blaze.FileStringParser" interface="com.google.idea.blaze.base.run.filter.FileResolver"/>
<extensionPoint qualifiedName="com.google.idea.blaze.BlazeGuard" interface="com.google.idea.blaze.base.execution.BazelGuard"/>
<extensionPoint qualifiedName="com.google.idea.blaze.BlazeTestEventsHandler" interface="com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler"/>
<extensionPoint qualifiedName="com.google.idea.blaze.AttributeSpecificStringLiteralReferenceProvider" interface="com.google.idea.blaze.base.lang.buildfile.references.AttributeSpecificStringLiteralReferenceProvider"/>
<extensionPoint qualifiedName="com.google.idea.blaze.EventLogger" interface="com.google.idea.blaze.base.logging.EventLogger"/>
Expand Down Expand Up @@ -678,6 +679,7 @@
<ExperimentLoader implementation="com.google.idea.common.experiments.SystemPropertyExperimentLoader" order="first" id="SystemPropertyExperimentLoader"/>
<ExperimentLoader implementation="com.google.idea.common.experiments.UserOverridesExperimentLoader" order="after SystemPropertyExperimentLoader" id="UserOverridesExperimentLoader"/>
<ExperimentLoader implementation="com.google.idea.common.experiments.DefaultValuesExperimentLoader" order="last" id="DefaultValuesExperimentLoader"/>
<BlazeGuard implementation="com.google.idea.blaze.base.execution.TrustedProjectGuard"/>
</extensions>

<extensions defaultExtensionNs="com.google.idea.blaze.qsync">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@
import com.google.idea.blaze.base.command.buildresult.BuildResultHelperBep;
import com.google.idea.blaze.base.command.buildresult.ParsedBepOutput;
import com.google.idea.blaze.base.console.BlazeConsoleLineProcessorProvider;
import com.google.idea.blaze.base.execution.BazelGuard;
import com.google.idea.blaze.base.execution.ExecutionDeniedException;
import com.google.idea.blaze.base.logging.utils.querysync.BuildDepsStatsScope;
import com.google.idea.blaze.base.logging.utils.querysync.SyncQueryStatsScope;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.run.testlogs.BlazeTestResults;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.SummaryOutput;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.scopes.SharedStringPoolScope;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.sync.aspects.BlazeBuildOutputs;
import com.google.idea.blaze.base.sync.aspects.BuildResult;
import com.google.idea.blaze.base.sync.aspects.BuildResult.Status;
Expand Down Expand Up @@ -65,6 +69,11 @@ public BlazeBuildOutputs run(
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars) {
try {
performGuardCheck(project, context);
} catch (ExecutionDeniedException e) {
return BlazeBuildOutputs.noOutputs(BuildResult.FATAL_ERROR);
}

BuildResult buildResult =
issueBuild(blazeCommandBuilder, WorkspaceRoot.fromProject(project), envVars, context);
Expand Down Expand Up @@ -104,10 +113,17 @@ public BlazeTestResults runTest(
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars) {
try {
performGuardCheck(project, context);
} catch (ExecutionDeniedException e) {
return BlazeTestResults.NO_RESULTS;
}

// For tests, we have to pass the environment variables as `--test_env`, otherwise they don't get forwarded
for (Map.Entry<String, String> env: envVars.entrySet()) {
blazeCommandBuilder.addBlazeFlags(BlazeFlags.TEST_ENV, String.format("%s=%s", env.getKey(), env.getValue()));
}

BuildResult buildResult =
issueBuild(blazeCommandBuilder, WorkspaceRoot.fromProject(project), envVars, context);
if (buildResult.status == Status.FATAL_ERROR) {
Expand All @@ -130,6 +146,8 @@ public InputStream runQuery(
BuildResultHelper buildResultHelper,
BlazeContext context)
throws BuildException {
performGuardCheckAsBuildException(project, context);

try (Closer closer = Closer.create()) {
Path tempFile =
Files.createTempFile(
Expand Down Expand Up @@ -176,6 +194,8 @@ public InputStream runBlazeInfo(
BuildResultHelper buildResultHelper,
BlazeContext context)
throws BuildException {
performGuardCheckAsBuildException(project, context);

try (Closer closer = Closer.create()) {
Path tmpFile =
Files.createTempFile(
Expand Down Expand Up @@ -227,4 +247,27 @@ public Optional<Integer> getMaxCommandLineLength() {
// so choose a value somewhere south of that, which seems to work.
return Optional.of(130000);
}

private void performGuardCheck(Project project, BlazeContext context)
throws ExecutionDeniedException {
try {
BazelGuard.checkExtensionsIsExecutionAllowed(project);
} catch (ExecutionDeniedException e) {
IssueOutput.error(
"Can't invoke "
+ Blaze.buildSystemName(project)
+ " because the project is not trusted")
.submit(context);
throw e;
}
}

private void performGuardCheckAsBuildException(Project project, BlazeContext context)
throws BuildException {
try {
performGuardCheck(project, context);
} catch (ExecutionDeniedException e) {
throw new BuildException(e);
}
}
}
34 changes: 34 additions & 0 deletions base/src/com/google/idea/blaze/base/execution/BazelGuard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2024 The Bazel Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.idea.blaze.base.execution;

import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;

/** Interface for checking if tools execution is allowed for the imported project. */
public interface BazelGuard {

ExtensionPointName<BazelGuard> EP_NAME =
ExtensionPointName.create("com.google.idea.blaze.BlazeGuard");

void checkIsExecutionAllowed(Project project) throws ExecutionDeniedException;

static void checkExtensionsIsExecutionAllowed(Project project) throws ExecutionDeniedException {
for (var extension : EP_NAME.getExtensionList()) {
extension.checkIsExecutionAllowed(project);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2024 The Bazel Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.idea.blaze.base.execution;

/** Exception thrown when tool execution is denied. */
public class ExecutionDeniedException extends Exception {
public ExecutionDeniedException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2024 The Bazel Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.idea.blaze.base.execution;

import com.intellij.ide.impl.TrustedProjects;
import com.intellij.openapi.project.Project;

/** A {@link BazelGuard} that only allows execution if the project is trusted. */
public class TrustedProjectGuard implements BazelGuard {
@Override
public void checkIsExecutionAllowed(Project project) throws ExecutionDeniedException {
if (!TrustedProjects.isTrusted(project)) {
throw new ExecutionDeniedException("Execution is not allowed because project is not trusted");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.Optional;
import javax.swing.Icon;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -113,7 +114,9 @@ Project doOpenProject(
}

Project newProject = createProject(virtualFile);
Objects.requireNonNull(newProject);
if (newProject == null) {
return null;
}

newProject.putUserData(PROJECT_AUTO_IMPORTED, true);

Expand Down Expand Up @@ -170,12 +173,13 @@ private Project createProject(@NotNull VirtualFile virtualFile) {
LOG.error("Failed to commit project import builder", e);
}

Project newProject = builder.createProject(name, projectFilePath);
if (newProject == null) {
LOG.error("Failed to Bazel create project");
Optional<Project> returnedValue = ExtendableBazelProjectCreator.getInstance()
.createProject(builder, name, projectFilePath);
if (returnedValue.isEmpty()) {
return null;
}


Project newProject = returnedValue.get();
newProject.save();

if (!builder.validate(null, newProject)) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
*/
package com.google.idea.blaze.base.project;

import com.google.idea.blaze.base.settings.BuildSystemName;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import java.util.Optional;
import javax.annotation.Nullable;

/** Interface for creating a project with additional configuration. */
public interface ExtendableBazelProjectCreator {
Expand All @@ -26,10 +30,14 @@ public interface ExtendableBazelProjectCreator {
* @param builder the project builder
* @param name the name of the project
* @param path the path to the project
* @return the created project
* @return the created project, can be null if the project cannot be created
*/
public Project createProject(ProjectBuilder builder, String name, String path);
public Optional<Project> createProject(ProjectBuilder builder, String name, String path);

/** Returns true if the project can be created. */
public boolean canCreateProject();
public boolean canCreateProject(@Nullable BuildSystemName buildSystemName);

static ExtendableBazelProjectCreator getInstance() {
return ApplicationManager.getApplication().getService(ExtendableBazelProjectCreator.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2024 The Bazel Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.idea.blaze.base.project;

import com.google.idea.blaze.base.settings.BuildSystemName;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.impl.TrustedProjects;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageDialogBuilder;
import java.util.Optional;
import javax.annotation.Nullable;

/** Creates a project if the user has trusted the project. */
public class TrustAwareProjectCreator implements ExtendableBazelProjectCreator {

/**
* Creates a project if the user has trusted the project.
*
* @param builder the project builder
* @param name the name of the project
* @param path the path to the project
* @return the created project, null if the user did not trust the project
*/
@Override
public Optional<Project> createProject(ProjectBuilder builder, String name, String path) {
if (!canCreateProject(null)) {
return Optional.empty();
}

return Optional.of(builder.createProject(name, path));
}

/** Returns true if the user has trusted the project. */
@Override
public boolean canCreateProject(@Nullable BuildSystemName buildSystemName) {
var trustText = IdeBundle.message("untrusted.project.dialog.trust.button");
var dontOpenText = IdeBundle.message("untrusted.project.open.dialog.cancel.button");

var choice =
new MessageDialogBuilder.Message(
IdeBundle.message("untrusted.project.general.dialog.title"),
IdeBundle.message(
"untrusted.project.open.dialog.text",
ApplicationInfo.getInstance().getFullApplicationName()))
.buttons(
IdeBundle.message("untrusted.project.dialog.trust.button"),
IdeBundle.message("untrusted.project.open.dialog.cancel.button"))
.defaultButton(trustText)
.focusedButton(dontOpenText)
.asWarning()
.help(TrustedProjects.TRUSTED_PROJECTS_HELP_TOPIC)
.show(null, null);

return trustText.equals(choice);
}
}
Loading

0 comments on commit ea89058

Please sign in to comment.