sources/Google.Solutions.IapDesktop.Application/Profile/Settings/ApplicationSettingsRepository.cs (218 lines of code) (raw):

// // Copyright 2020 Google LLC // // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you 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. // using Google.Solutions.Common.Util; using Google.Solutions.IapDesktop.Application.Host; using Google.Solutions.Settings; using Google.Solutions.Settings.Collection; using Microsoft.Win32; using System; using System.Collections.Generic; using System.Net; using System.Security; namespace Google.Solutions.IapDesktop.Application.Profile.Settings { /// <summary> /// General settings. /// </summary> public interface IApplicationSettings : ISettingsCollection { ISetting<bool> IsMainWindowMaximized { get; } ISetting<int> MainWindowHeight { get; } ISetting<int> MainWindowWidth { get; } ISetting<bool> IsUpdateCheckEnabled { get; } ISetting<bool> IsTelemetryEnabled { get; } ISetting<long> LastUpdateCheck { get; } ISetting<bool> IsPreviewFeatureSetEnabled { get; } ISetting<string?> ProxyUrl { get; } ISetting<string?> ProxyPacUrl { get; } ISetting<string?> ProxyUsername { get; } ISetting<SecureString?> ProxyPassword { get; } ISetting<int> ProxyAuthenticationRetries { get; } ISetting<SecurityProtocolType> TlsVersions { get; } ISetting<string?> FullScreenDevices { get; } ISetting<string?> CollapsedProjects { get; } /// <summary> /// Participate in surveys. /// </summary> ISetting<bool> IsSurveyEnabled { get; } /// <summary> /// Last release version for which the user has taken a survey. /// </summary> ISetting<string?> LastSurveyVersion { get; } } /// <summary> /// Registry-backed repository for app settings. /// </summary> public class ApplicationSettingsRepository : GroupPolicyAwareRepository<IApplicationSettings> { public const char FullScreenDevicesSeparator = ','; private readonly UserProfile.SchemaVersion schemaVersion; public ApplicationSettingsRepository( RegistryKey settingsKey, RegistryKey? machinePolicyKey, RegistryKey? userPolicyKey, UserProfile.SchemaVersion schemaVersion) : base(settingsKey, machinePolicyKey, userPolicyKey) { Precondition.ExpectNotNull(settingsKey, nameof(settingsKey)); this.schemaVersion = schemaVersion; } public ApplicationSettingsRepository(UserProfile profile) : this( profile.SettingsKey.CreateSubKey("Application"), profile.MachinePolicyKey?.OpenSubKey("Application"), profile.UserPolicyKey?.OpenSubKey("Application"), profile.Version) { } protected override IApplicationSettings LoadSettings(ISettingsStore store) { return new ApplicationSettings(store, this.schemaVersion); } //--------------------------------------------------------------------- // Inner class. //--------------------------------------------------------------------- private class ApplicationSettings : IApplicationSettings { public ISetting<bool> IsMainWindowMaximized { get; } public ISetting<int> MainWindowHeight { get; } public ISetting<int> MainWindowWidth { get; } public ISetting<bool> IsUpdateCheckEnabled { get; } public ISetting<bool> IsTelemetryEnabled { get; } public ISetting<long> LastUpdateCheck { get; } public ISetting<bool> IsPreviewFeatureSetEnabled { get; } public ISetting<string?> ProxyUrl { get; } public ISetting<string?> ProxyPacUrl { get; } public ISetting<string?> ProxyUsername { get; } public ISetting<SecureString?> ProxyPassword { get; } public ISetting<int> ProxyAuthenticationRetries { get; } public ISetting<SecurityProtocolType> TlsVersions { get; } public ISetting<string?> FullScreenDevices { get; } public ISetting<string?> CollapsedProjects { get; } public ISetting<bool> IsSurveyEnabled { get; } public ISetting<string?> LastSurveyVersion { get; } public IEnumerable<ISetting> Settings => new ISetting[] { this.IsMainWindowMaximized, this.MainWindowHeight, this.MainWindowWidth, this.IsUpdateCheckEnabled, this.IsTelemetryEnabled, this.LastUpdateCheck, this.IsUpdateCheckEnabled, this.ProxyUrl, this.ProxyPacUrl, this.ProxyUsername, this.ProxyPassword, this.ProxyAuthenticationRetries, this.TlsVersions, this.FullScreenDevices, this.CollapsedProjects, this.IsSurveyEnabled, this.LastSurveyVersion }; internal ApplicationSettings( ISettingsStore store, UserProfile.SchemaVersion schemaVersion) { // // Settings that can be overridden by policy. // // NB. Default values must be kept consistent with the // ADMX policy templates! // this.IsPreviewFeatureSetEnabled = store.Read<bool>( "IsPreviewFeatureSetEnabled", "IsPreviewFeatureSetEnabled", null, null, false); this.IsUpdateCheckEnabled = store.Read<bool>( "IsUpdateCheckEnabled", "IsUpdateCheckEnabled", null, null, true); this.IsTelemetryEnabled = store.Read<bool>( "IsTelemetryEnabled", "IsTelemetryEnabled", null, null, schemaVersion >= UserProfile.SchemaVersion.Version240); // Auto opt-in new profiles this.ProxyUrl = store.Read<string?>( "ProxyUrl", "ProxyUrl", null, null, null, url => url == null || Uri.TryCreate(url, UriKind.Absolute, out var _)); this.ProxyPacUrl = store.Read<string?>( "ProxyPacUrl", "ProxyPacUrl", null, null, null, url => url == null || Uri.TryCreate(url, UriKind.Absolute, out var _)); this.ProxyAuthenticationRetries = store.Read<int>( "ProxyAuthenticationRetries", "ProxyAuthenticationRetries", null, null, 2, // A single retry might not be sufficient (b/323465182). Predicate.InRange(0, 8)); this.TlsVersions = store.Read<SecurityProtocolType>( "TlsVersions", "TlsVersions", null, null, OSCapabilities.SupportedTlsVersions); // // User preferences. These cannot be overridden by policy. // this.IsMainWindowMaximized = store.Read<bool>( "IsMainWindowMaximized", "IsMainWindowMaximized", null, null, false); this.MainWindowHeight = store.Read<int>( "MainWindowHeight", "MainWindowHeight", null, null, 0, Predicate.InRange(0, ushort.MaxValue)); this.MainWindowWidth = store.Read<int>( "WindowWidth", "WindowWidth", null, null, 0, Predicate.InRange(0, ushort.MaxValue)); this.LastUpdateCheck = store.Read<long>( "LastUpdateCheck", "LastUpdateCheck", null, null, 0, Predicate.InRange(0, long.MaxValue)); this.ProxyUsername = store.Read<string?>( "ProxyUsername", "ProxyUsername", null, null, null, _ => true); this.ProxyPassword = store.Read<SecureString?>( "ProxyPassword", "ProxyPassword", null, null, null); this.FullScreenDevices = store.Read<string?>( "FullScreenDevices", "FullScreenDevices", null, null, null, _ => true); this.CollapsedProjects = store.Read<string?>( "CollapsedProjects", "CollapsedProjects", null, null, null, _ => true); this.IsSurveyEnabled = store.Read<bool>( "IsSurveyEnabled", "IsSurveyEnabled", null, null, true); this.LastSurveyVersion = store.Read<string?>( "LastSurveyVersion", "LastSurveyVersion", null, null, null, _ => true); } } } }