From: Zofia Abramowska Date: Tue, 22 Aug 2017 13:48:35 +0000 (+0200) Subject: Add new Tizen.Security.PrivacyPrivilegeManager API X-Git-Tag: preview1-00324^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F16%2F145516%2F13;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git Add new Tizen.Security.PrivacyPrivilegeManager API PS1: Review Tizen.Security.PrivacyPriviledgeManager API cs files This API wrapps native C API of privacy-privilege-manager. Change-Id: Id8d660ac121693015f6c06940122a758b2c8cba7 Signed-off-by: Zofia Abramowska --- diff --git a/pkg/PlatformFileList.txt b/pkg/PlatformFileList.txt index 8aaa14f..2b1fe3b 100644 --- a/pkg/PlatformFileList.txt +++ b/pkg/PlatformFileList.txt @@ -63,6 +63,7 @@ Tizen.PhonenumberUtils.dll #mobile #mobile-emul #wearabl Tizen.Pims.Calendar.dll #common #mobile #mobile-emul #tv #wearable Tizen.Pims.Contacts.dll #mobile #mobile-emul #wearable Tizen.Security.dll #common #mobile #mobile-emul #tv #ivi #wearable +Tizen.Security.PrivacyPrivilegeManager.dll #common #mobile #mobile-emul #tv #ivi #wearable Tizen.Security.SecureRepository.dll #common #mobile #mobile-emul #tv #ivi #wearable Tizen.Security.TEEC.dll #mobile #mobile-emul #tv #ivi #wearable Tizen.Sensor.dll #common #mobile #mobile-emul #tv #ivi #wearable diff --git a/pkg/PublicModuleList.txt b/pkg/PublicModuleList.txt index 2e9e56b..e0d5ed4 100755 --- a/pkg/PublicModuleList.txt +++ b/pkg/PublicModuleList.txt @@ -58,6 +58,7 @@ Tizen.PhonenumberUtils Tizen.Pims.Calendar Tizen.Pims.Contacts Tizen.Security +Tizen.Security.PrivacyPrivilegeManager Tizen.Security.SecureRepository Tizen.Security.TEEC Tizen.Sensor diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Interop/Interop.Libraries.cs b/src/Tizen.Security.PrivacyPrivilegeManager/Interop/Interop.Libraries.cs new file mode 100644 index 0000000..edde8d3 --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Interop/Interop.Libraries.cs @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd 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. + */ + +internal static partial class Interop +{ + internal static partial class Libraries + { + internal const string PrivacyPrivilegeManager = "libcapi-privacy-privilege-manager.so.0"; + } +} diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Interop/Interop.PrivacyPrivilegeManager.cs b/src/Tizen.Security.PrivacyPrivilegeManager/Interop/Interop.PrivacyPrivilegeManager.cs new file mode 100644 index 0000000..da6d21a --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Interop/Interop.PrivacyPrivilegeManager.cs @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd 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. + */ + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class PrivacyPrivilegeManager + { + internal enum ErrorCode + { + None = Tizen.Internals.Errors.ErrorCode.None, + IoError = Tizen.Internals.Errors.ErrorCode.IoError, + InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, + OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, + Unknown = Tizen.Internals.Errors.ErrorCode.Unknown + } + + internal enum CallCause + { + Answer = 0, + Error = 1, + } + + internal enum CheckResult + { + Allow = 0, + Deny = 1, + Ask = 2, + } + + internal enum RequestResult + { + AllowForever = 0, + DenyForever = 1, + DenyOnce = 2, + } + + //[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void RequestResponseCallback(CallCause cause, RequestResult result, string privilege, IntPtr userData); + + [DllImport(Libraries.PrivacyPrivilegeManager, EntryPoint = "ppm_check_permission")] + internal static extern ErrorCode CheckPermission(string privilege, out CheckResult result); + + [DllImport(Libraries.PrivacyPrivilegeManager, EntryPoint = "ppm_request_permission")] + internal static extern ErrorCode RequestPermission(string privilege, RequestResponseCallback callback, IntPtr userData); + } +} diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security.PrivacyPrivilegeManager.csproj b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security.PrivacyPrivilegeManager.csproj new file mode 100644 index 0000000..a3f7577 --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security.PrivacyPrivilegeManager.csproj @@ -0,0 +1,10 @@ + + + netstandard2.0 + + + + + + + diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security.PrivacyPrivilegeManager.sln b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security.PrivacyPrivilegeManager.sln new file mode 100644 index 0000000..f740e19 --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security.PrivacyPrivilegeManager.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tizen.Security.PrivacyPrivilegeManager", "Tizen.Security.PrivacyPrivilegeManager.csproj", "{588EBECE-A11C-4837-80F3-5EDECFC17E5E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Debug|x64.ActiveCfg = Debug|x64 + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Debug|x64.Build.0 = Debug|x64 + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Debug|x86.ActiveCfg = Debug|x86 + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Debug|x86.Build.0 = Debug|x86 + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Release|Any CPU.Build.0 = Release|Any CPU + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Release|x64.ActiveCfg = Release|x64 + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Release|x64.Build.0 = Release|x64 + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Release|x86.ActiveCfg = Release|x86 + {588EBECE-A11C-4837-80F3-5EDECFC17E5E}.Release|x86.Build.0 = Release|x86 + EndGlobalSection +EndGlobal diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/CallCause.cs b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/CallCause.cs new file mode 100644 index 0000000..e0e329a --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/CallCause.cs @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd 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. + */ + +namespace Tizen.Security +{ + /// + /// Enumeration for the call cause of a permission request callback. + /// + /// 4 + public enum CallCause + { + /// + /// The call cause is a permission request answer. + /// + /// 4 + Answer = Interop.PrivacyPrivilegeManager.CallCause.Answer, + /// + /// The call cause is an error. + /// + /// 4 + Error = Interop.PrivacyPrivilegeManager.CallCause.Error, + } +} diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/CheckResult.cs b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/CheckResult.cs new file mode 100644 index 0000000..8abded1 --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/CheckResult.cs @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd 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. + */ + +namespace Tizen.Security +{ + /// + /// Enumeration for the result of a permission check. + /// + /// 4 + public enum CheckResult + { + /// + /// The access to privilege is allowed permanently. + /// + /// 4 + Allow = Interop.PrivacyPrivilegeManager.CheckResult.Allow, + /// + /// The access to privilege is denied permanently. + /// + /// 4 + Deny = Interop.PrivacyPrivilegeManager.CheckResult.Deny, + /// + /// The access to privilege must be resolved by the user. + /// + /// 4 + Ask = Interop.PrivacyPrivilegeManager.CheckResult.Ask, + } +} diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/PrivacyPrivilegeManager.cs b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/PrivacyPrivilegeManager.cs new file mode 100644 index 0000000..6f56551 --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/PrivacyPrivilegeManager.cs @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd 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. + */ + +using System; +using System.Collections.Generic; +using Tizen.Internals.Errors; + +namespace Tizen.Security +{ + /// + /// The PrivacyPrivilegeManager provides the properties or methods to check and request a permission for privacy privilege. + /// + public static class PrivacyPrivilegeManager + { + private const string LogTag = "Tizen.Privilege"; + private static Interop.PrivacyPrivilegeManager.RequestResponseCallback s_requestResponseCb; + private static IDictionary s_responseMap = new Dictionary(); + + static PrivacyPrivilegeManager() + { + s_requestResponseCb = (Interop.PrivacyPrivilegeManager.CallCause cause, Interop.PrivacyPrivilegeManager.RequestResult result, string privilege, IntPtr userData) => + { + try + { + s_responseMap[privilege].FireEvent((CallCause)cause, (RequestResult) result); + } + catch (Exception e) + { + Log.Error(LogTag, "Exception in callback : " + e.Message); + } + }; + } + + /// + /// Gets the status of a privacy privilege permission. + /// + /// The privacy privilege to be checked. + /// The permission setting for a respective privilege. + /// Thrown when an invalid parameter is passed. + /// Thrown when a memory error occurred. + /// Thrown when the method failed due to an internal I/O error. + /// + /// + /// CheckResult result = PrivacyPrivilegeManager.CheckPermission("http://tizen.org/privilege/account.read"); + /// switch (result) + /// { + /// case Allow: + /// // Privilege can be used + /// break; + /// case Deny: + /// // Privilege can't be used + /// break; + /// case Ask: + /// // User permission request required + /// PrivacyPrivilegeManager.RequestPermission("http://tizen.org/privilege/account.read"); + /// break; + /// } + /// + /// + public static CheckResult CheckPermission(string privilege) + { + Interop.PrivacyPrivilegeManager.CheckResult result; + int ret = (int)Interop.PrivacyPrivilegeManager.CheckPermission(privilege, out result); + if (ret != (int)Interop.PrivacyPrivilegeManager.ErrorCode.None) + { + Log.Error(LogTag, "Failed to check permission"); + throw PrivacyPrivilegeManagerErrorFactory.GetException(ret); + } + return (CheckResult)result; + } + + /// + /// Triggers the permission request for a user. + /// + /// The privacy privilege to be requested. + /// Thrown when an invalid parameter is passed. + /// Thrown when a memory error occurred. + /// Thrown when the method failed due to an internal I/O error. + /// + /// + /// CheckResult result = PrivacyPrivilegeManager.CheckPermission("http://tizen.org/privilege/account.read"); + /// switch (result) + /// { + /// case Allow: + /// // Privilege can be used + /// break; + /// case Deny: + /// // Privilege can't be used + /// break; + /// case Ask: + /// // User permission request required + /// PrivacyPrivilegeManager.RequestPermission("http://tizen.org/privilege/account.read"); + /// break; + /// } + /// + /// + public static void RequestPermission(string privilege) + { + int ret = (int)Interop.PrivacyPrivilegeManager.RequestPermission(privilege, s_requestResponseCb, IntPtr.Zero); + if (ret != (int)Interop.PrivacyPrivilegeManager.ErrorCode.None) + { + Log.Error(LogTag, "Failed to request permission"); + throw PrivacyPrivilegeManagerErrorFactory.GetException(ret); + } + } + + /// + /// Gets the response context for a given privilege. + /// + /// + /// The privilege. + /// The response context of a respective privilege. + /// Thrown if the key is an invalid parameter. + /// + /// + /// private static void PPM_RequestResponse(object sender, RequestResponseEventArgs e) + /// { + /// if (e.cause == CallCause.Answer) + /// { + /// switch(e.result) + /// + /// { + /// + /// case RequestResult.AllowForever: + /// Console.WriteLine("User allowed usage of privilege {0} definitely", e.privilege); + /// break; + /// case RequestResult.DenyForever: + /// Console.WriteLine("User denied usage of privilege {0} definitely", e.privilege); + /// break; + /// case RequestResult.DenyOnce: + /// Console.WriteLine("User denied usage of privilege {0} this time", e.privilege); + /// break; + /// }; + /// } + /// else + /// { + /// Console.WriteLine("Error occured during requesting permission for {0}", e.privilege); + /// } + ///} + /// + /// PrivacyPrivilegeManager.ResponseContext context = null; + /// PrivacyPrivilegeManager.GetResponseContext("http://tizen.org/privilege/account.read").TryGetTarget(out context); + /// if(context != null) + /// { + /// context.ResponseFetched += PPM_RequestResponse; + /// } + /// + /// PrivacyPrivilegeManager.RequestPermission("http://tizen.org/privilege/account.read"); + /// + /// PrivacyPrivilegeManager.GetResponseContext("http://tizen.org/privilege/account.read").TryGetTarget(out context); + /// if(context != null) + /// { + /// context.ResponseFetched -= PPM_RequestResponse; + /// } + /// + /// + public static WeakReference GetResponseContext(string privilege) + { + if (!s_responseMap.ContainsKey(privilege)) + { + s_responseMap[privilege] = new ResponseContext(privilege); + } + return new WeakReference(s_responseMap[privilege]); + } + + /// + /// This class manages event handlers of the privilege permission requests. + /// This class enables having event handlers for an individual privilege. + /// + public class ResponseContext + { + private string _privilege; + + internal ResponseContext(string privilege) + { + _privilege = privilege; + } + /// + /// Occurs when the response for a permission request is fetched. + /// + /// Thrown when the bundle instance has been disposed. + public event EventHandler ResponseFetched + { + add + { + _ResponseFetched += value; + } + + remove + { + _ResponseFetched -= value; + if (_ResponseFetched == null) + { + s_responseMap.Remove(_privilege); + } + } + } + + private event EventHandler _ResponseFetched; + + internal void FireEvent(CallCause _cause, RequestResult _result) + { + _ResponseFetched?.Invoke(null, new RequestResponseEventArgs() { cause = _cause, result = _result, privilege = _privilege }); + } + } + } + + internal static class PrivacyPrivilegeManagerErrorFactory + { + static internal Exception GetException(int error) + { + Interop.PrivacyPrivilegeManager.ErrorCode errCode = (Interop.PrivacyPrivilegeManager.ErrorCode)error; + switch(errCode) + { + case Interop.PrivacyPrivilegeManager.ErrorCode.InvalidParameter: + return new ArgumentException("Invalid parameter"); + case Interop.PrivacyPrivilegeManager.ErrorCode.IoError: + return new System.IO.IOException("I/O Error"); + case Interop.PrivacyPrivilegeManager.ErrorCode.OutOfMemory: + return new OutOfMemoryException("Out of memory"); + case Interop.PrivacyPrivilegeManager.ErrorCode.Unknown: + default: + return new ArgumentException("Unknown error"); + } + } + } +} diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/RequestResponseEventArgs.cs b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/RequestResponseEventArgs.cs new file mode 100644 index 0000000..5f50b6c --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/RequestResponseEventArgs.cs @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd 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. + */ + +using System; + +namespace Tizen.Security +{ + /// + /// This class is an event argument of the RequestResponse event. + /// + + public class RequestResponseEventArgs : EventArgs + { + /// + /// The cause of a triggered response. + /// + public CallCause cause { get; internal set; } + + /// + /// The result of a permission request. + /// + public RequestResult result { get; internal set; } + + /// + /// The privilege for which a permission was requested for. + /// + public string privilege { get; internal set; } + } +} diff --git a/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/RequestResult.cs b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/RequestResult.cs new file mode 100644 index 0000000..f87f77e --- /dev/null +++ b/src/Tizen.Security.PrivacyPrivilegeManager/Tizen.Security/RequestResult.cs @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd 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. + */ + +namespace Tizen.Security +{ + /// + /// Enumeration for the result of a permission request. + /// + /// 4 + public enum RequestResult + { + /// + /// The privilege is allowed permanently. + /// + /// 4 + AllowForever = Interop.PrivacyPrivilegeManager.RequestResult.AllowForever, + /// + /// The privilege is denied permanently. + /// + /// 4 + DenyForever = Interop.PrivacyPrivilegeManager.RequestResult.DenyForever, + /// + /// The privilege is denied temporarily. + /// + /// 4 + DenyOnce = Interop.PrivacyPrivilegeManager.RequestResult.DenyOnce, + } +}