Skip to content

Commit

Permalink
Group Policy for controlling sources (#841)
Browse files Browse the repository at this point in the history
  • Loading branch information
Luis Chacón authored Apr 2, 2021
1 parent a9a63a3 commit 741955e
Show file tree
Hide file tree
Showing 22 changed files with 1,585 additions and 316 deletions.
16 changes: 10 additions & 6 deletions src/AppInstallerCLICore/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ namespace AppInstaller::CLI
{
auto policy = TogglePolicy::GetPolicy(command->GroupPolicy());
AICLI_LOG(CLI, Error, << "Trying to use command: " << *itr << " disabled by group policy " << policy.RegValueName());
throw CommandException(Resource::String::DisabledByGroupPolicy, policy.PolicyName());
throw GroupPolicyException(command->GroupPolicy());
}

AICLI_LOG(CLI, Info, << "Found subcommand: " << *itr);
Expand Down Expand Up @@ -657,7 +657,7 @@ namespace AppInstaller::CLI
{
auto policy = TogglePolicy::GetPolicy(arg.GroupPolicy());
AICLI_LOG(CLI, Error, << "Trying to use argument: " << arg.Name() << " disabled by group policy " << policy.RegValueName());
throw CommandException(Resource::String::DisabledByGroupPolicy, policy.PolicyName());
throw GroupPolicyException(arg.GroupPolicy());
}

if (arg.Required() && !execArgs.Contains(arg.ExecArgType()))
Expand Down Expand Up @@ -783,10 +783,8 @@ namespace AppInstaller::CLI
// Override the function to bypass this.
if (!Settings::GroupPolicies().IsEnabled(Settings::TogglePolicy::Policy::WinGet))
{
auto policy = TogglePolicy::GetPolicy(Settings::TogglePolicy::Policy::WinGet);
AICLI_LOG(CLI, Error, << "WinGet is disabled by group policy " << policy.RegValueName());
context.Reporter.Error() << Resource::String::DisabledByGroupPolicy << " : "_liv << policy.PolicyName() << std::endl;
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY);
AICLI_LOG(CLI, Error, << "WinGet is disabled by group policy");
throw GroupPolicyException(Settings::TogglePolicy::Policy::WinGet);
}

AICLI_LOG(CLI, Info, << "Executing command: " << Name());
Expand Down Expand Up @@ -883,6 +881,12 @@ namespace AppInstaller::CLI
message << std::endl;
return hre.code();
}
catch (const Settings::GroupPolicyException& e)
{
auto policy = Settings::TogglePolicy::GetPolicy(e.Policy());
context.Reporter.Error() << Resource::String::DisabledByGroupPolicy << ": "_liv << policy.PolicyName() << std::endl;
return APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY;
}
catch (const std::exception& e)
{
Logging::Telemetry().LogException(command->FullName(), "std::exception", e.what());
Expand Down
4 changes: 4 additions & 0 deletions src/AppInstallerCLICore/Commands/CompleteCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ namespace AppInstaller::CLI
{
AICLI_LOG(CLI, Info, << "Error encountered during completion, ignoring: " << ce.Message());
}
catch (const Settings::GroupPolicyException& e)
{
AICLI_LOG(CLI, Info, << "Error encountered during completion, ignoring: Blocked by Group Policy " << Settings::TogglePolicy::GetPolicy(e.Policy()).RegValueName());
}
catch (...)
{
AICLI_LOG(CLI, Info, << "Error encountered during completion, ignoring...");
Expand Down
42 changes: 42 additions & 0 deletions src/AppInstallerCLICore/Commands/SourceCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace AppInstaller::CLI
std::make_unique<SourceUpdateCommand>(FullName()),
std::make_unique<SourceRemoveCommand>(FullName()),
std::make_unique<SourceResetCommand>(FullName()),
std::make_unique<SourceExportCommand>(FullName()),
});
}

Expand Down Expand Up @@ -71,6 +72,8 @@ namespace AppInstaller::CLI

void SourceAddCommand::ExecuteInternal(Context& context) const
{
// Note: Group Policy for allowed sources is enforced at the RepositoryCore level
// as we need to validate the source data and handle sources that were already added.
context <<
Workflow::EnsureRunningAsAdmin <<
Workflow::GetSourceList <<
Expand Down Expand Up @@ -187,6 +190,7 @@ namespace AppInstaller::CLI

void SourceRemoveCommand::ExecuteInternal(Context& context) const
{
// Note: Group Policy for unremovable sources is enforced at the RepositoryCore.
context <<
Workflow::EnsureRunningAsAdmin <<
Workflow::GetSourceListWithFilter <<
Expand Down Expand Up @@ -242,4 +246,42 @@ namespace AppInstaller::CLI
Workflow::ResetAllSources;
}
}

std::vector<Argument> SourceExportCommand::GetArguments() const
{
return {
Argument::ForType(Args::Type::SourceName),
};
}

Resource::LocString SourceExportCommand::ShortDescription() const
{
return { Resource::String::SourceExportCommandShortDescription };
}

Resource::LocString SourceExportCommand::LongDescription() const
{
return { Resource::String::SourceExportCommandLongDescription };
}

void SourceExportCommand::Complete(Context& context, Args::Type valueType) const
{
if (valueType == Args::Type::SourceName)
{
context <<
Workflow::CompleteSourceName;
}
}

std::string SourceExportCommand::HelpLink() const
{
return std::string{ s_SourceCommand_HelpLink };
}

void SourceExportCommand::ExecuteInternal(Context& context) const
{
context <<
Workflow::GetSourceListWithFilter <<
Workflow::ExportSourceList;
}
}
20 changes: 19 additions & 1 deletion src/AppInstallerCLICore/Commands/SourceCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace AppInstaller::CLI

struct SourceAddCommand final : public Command
{
SourceAddCommand(std::string_view parent) : Command("add", parent) {}
SourceAddCommand(std::string_view parent) : Command("add", parent, Settings::TogglePolicy::Policy::AllowedSources) {}

std::vector<Argument> GetArguments() const override;

Expand Down Expand Up @@ -71,6 +71,7 @@ namespace AppInstaller::CLI

struct SourceRemoveCommand final : public Command
{
// We can remove user or default sources, so this is not gated by any single policy.
SourceRemoveCommand(std::string_view parent) : Command("remove", parent) {}

std::vector<Argument> GetArguments() const override;
Expand Down Expand Up @@ -102,4 +103,21 @@ namespace AppInstaller::CLI
protected:
void ExecuteInternal(Execution::Context& context) const override;
};

struct SourceExportCommand final : public Command
{
SourceExportCommand(std::string_view parent) : Command("export", parent) {}

std::vector<Argument> GetArguments() const override;

Resource::LocString ShortDescription() const override;
Resource::LocString LongDescription() const override;

void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;

std::string HelpLink() const override;

protected:
void ExecuteInternal(Execution::Context& context) const override;
};
}
8 changes: 8 additions & 0 deletions src/AppInstallerCLICore/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ namespace AppInstaller::CLI
AICLI_LOG(CLI, Error, << "Error encountered parsing command line: " << ce.Message());
return APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS;
}
catch (const Settings::GroupPolicyException& e)
{
// Report any action blocked by Group Policy.
auto policy = Settings::TogglePolicy::GetPolicy(e.Policy());
AICLI_LOG(CLI, Error, << "Operation blocked by Group Policy: " << policy.RegValueName());
context.Reporter.Error() << Resource::String::DisabledByGroupPolicy << " : "_liv << policy.PolicyName() << std::endl;
return APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY;
}

return Execute(context, command);
}
Expand Down
2 changes: 2 additions & 0 deletions src/AppInstallerCLICore/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(SourceArgumentDescription);
WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(SourceListArg);
WINGET_DEFINE_RESOURCE_STRINGID(SourceListCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(SourceListCommandShortDescription);
Expand Down
26 changes: 26 additions & 0 deletions src/AppInstallerCLICore/Workflows/SourceFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace AppInstaller::CLI::Workflow
{
using namespace AppInstaller::CLI::Execution;
using namespace AppInstaller::Settings;
using namespace AppInstaller::Utility::literals;

void GetSourceList(Execution::Context& context)
Expand Down Expand Up @@ -166,6 +167,8 @@ namespace AppInstaller::CLI::Workflow

void RemoveSources(Execution::Context& context)
{
// TODO: We currently only allow removing a single source. If that changes,
// we need to check all sources with the Group Policy before removing any of them.
if (!context.Args.Contains(Args::Type::SourceName))
{
context.Reporter.Info() << Resource::String::SourceRemoveAll << std::endl;
Expand Down Expand Up @@ -215,4 +218,27 @@ namespace AppInstaller::CLI::Workflow
Repository::DropSource({});
context.Reporter.Info() << Resource::String::Done << std::endl;
}

void ExportSourceList(Execution::Context& context)
{
const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();

if (sources.empty())
{
context.Reporter.Info() << Resource::String::SourceListNoSources << std::endl;
}
else
{
for (const auto& source : sources)
{
SourceFromPolicy s;
s.Name = source.Name;
s.Type = source.Type;
s.Arg = source.Arg;
s.Data = source.Data;
s.Identifier = source.Identifier;
context.Reporter.Info() << s.ToJsonString() << std::endl;
}
}
}
}
6 changes: 6 additions & 0 deletions src/AppInstallerCLICore/Workflows/SourceFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,10 @@ namespace AppInstaller::CLI::Workflow
// Inputs: None
// Outputs: None
void ResetAllSources(Execution::Context& context);

// Lists the sources in SourceList in a format appropriate for using in Group Policy
// Required Args: None
// Inputs: SourceList
// Outputs: None
void ExportSourceList(Execution::Context& context);
}
6 changes: 6 additions & 0 deletions src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw
Original file line number Diff line number Diff line change
Expand Up @@ -902,4 +902,10 @@ Configuration is disabled due to Group Policy.</value>
<data name="PolicyEnableHashOverride" xml:space="preserve">
<value>Enable Windows App Installer Hash Override</value>
</data>
<data name="SourceExportCommandLongDescription" xml:space="preserve">
<value>Export current sources as JSON for Group Policy.</value>
</data>
<data name="SourceExportCommandShortDescription" xml:space="preserve">
<value>Export current sources</value>
</data>
</root>
Loading

0 comments on commit 741955e

Please sign in to comment.