From 5b792fa07e7b768ea6256857195790de46b68365 Mon Sep 17 00:00:00 2001 From: Tian L <60599517+tian-lt@users.noreply.github.com> Date: Mon, 24 May 2021 18:44:49 +0800 Subject: [PATCH] Fixed a graphing calculator "permissions" bug caused by PR #1426 (#1471) (#34) - The PR #1426 can cause a crash when no users are returned via `User::FindAllAsync(UserType::LocalUser)` when subsequently trying to access the first user. The existing code also does not guarantee that the returned user is the currently active user. - This fix retrieves the user that opened the app and passes this user into a function to check if this user has the proper permissions to access the graphing mode. This makes sense since the active user is indistinguishable (at least from the app's perspective) to the user who opened the app. This user's permissions are then propagated downwards to properly set up the navigation menu of the app. - Implementation detail worth pointing out: `s_categoryManifest` is what is used to populate the navigation menu of the app, but this variable is static by design, so a separate function was written to override the appropriate `isEnabled` value in `s_categoryManifest`. This function is called by `onLaunched`. - Manual testing Co-authored-by: Wei (Waley) Zhang --- src/CalcViewModel/Common/NavCategory.cpp | 48 +++++++++++++++++++----- src/CalcViewModel/Common/NavCategory.h | 4 +- src/Calculator/App.xaml.cs | 1 + 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/CalcViewModel/Common/NavCategory.cpp b/src/CalcViewModel/Common/NavCategory.cpp index 9985da45..9385fef2 100644 --- a/src/CalcViewModel/Common/NavCategory.cpp +++ b/src/CalcViewModel/Common/NavCategory.cpp @@ -61,20 +61,31 @@ bool IsGraphingModeAvailable() } Box ^ _isGraphingModeEnabledCached = nullptr; -bool IsGraphingModeEnabled() +bool IsGraphingModeEnabled(User ^ currentUser = nullptr) { - // CSHARP_MIGRATION: TODO: merge PR ##1471 to fix below bug before we release to PROD -#ifdef _DEBUG - _isGraphingModeEnabledCached = true; -#else - throw "CSHARP_MIGRATION: EXCEPTION"; -#endif // _DEBUG + if (!IsGraphingModeAvailable()) + { + return false; + } + + if (_isGraphingModeEnabledCached != nullptr) + { + return _isGraphingModeEnabledCached->Value; + } + + if (!currentUser) + { + return true; + } + + auto namedPolicyData = NamedPolicy::GetPolicyFromPathForUser(currentUser, L"Education", L"AllowGraphingCalculator"); + _isGraphingModeEnabledCached = namedPolicyData->GetBoolean() == true; return _isGraphingModeEnabledCached->Value; } // The order of items in this list determines the order of items in the menu. -static const list s_categoryManifest = [] { +static list s_categoryManifest = [] { auto res = list{ NavCategoryInitializer{ ViewMode::Standard, STANDARD_ID, L"Standard", @@ -100,7 +111,7 @@ static const list s_categoryManifest = [] { bool supportGraphingCalculator = IsGraphingModeAvailable(); if (supportGraphingCalculator) { - const bool isEnabled = IsGraphingModeEnabled(); + bool isEnabled = IsGraphingModeEnabled(); res.push_back(NavCategoryInitializer{ ViewMode::Graphing, GRAPHING_ID, L"Graphing", @@ -268,6 +279,25 @@ static const list s_categoryManifest = [] { return res; }(); +void NavCategory::InitializeCategoryManifest(User ^ user) +{ + int i = 0; + for (NavCategoryInitializer category : s_categoryManifest) + { + if (category.viewMode == ViewMode::Graphing) + { + auto navCatInit = s_categoryManifest.begin(); + std::advance(navCatInit, i); + (*navCatInit).isEnabled = IsGraphingModeEnabled(user); + break; + } + else + { + i++; + } + } + } + // This function should only be used when storing the mode to app data. int NavCategory::Serialize(ViewMode mode) { diff --git a/src/CalcViewModel/Common/NavCategory.h b/src/CalcViewModel/Common/NavCategory.h index 74cfaeed..1af04676 100644 --- a/src/CalcViewModel/Common/NavCategory.h +++ b/src/CalcViewModel/Common/NavCategory.h @@ -92,7 +92,7 @@ namespace CalculatorApp::ViewModel const MyVirtualKey virtualKey; const wchar_t* const accessKey; const bool supportsNegative; - const bool isEnabled; + bool isEnabled; }; private @@ -140,6 +140,8 @@ namespace CalculatorApp::ViewModel static bool IsDateCalculatorViewMode(ViewMode mode); static bool IsConverterViewMode(ViewMode mode); + static void InitializeCategoryManifest(Windows::System::User ^ user); + static Platform::String ^ GetFriendlyName(ViewMode mode); static Platform::String ^ GetNameResourceKey(ViewMode mode); static CategoryGroupType GetGroupType(ViewMode mode); diff --git a/src/Calculator/App.xaml.cs b/src/Calculator/App.xaml.cs index bce8e909..79b7d038 100644 --- a/src/Calculator/App.xaml.cs +++ b/src/Calculator/App.xaml.cs @@ -86,6 +86,7 @@ namespace CalculatorApp // If the app got pre-launch activated, then save that state in a flag m_preLaunched = true; } + NavCategory.InitializeCategoryManifest(args.User); OnAppLaunch(args, args.Arguments); }