1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.credentials.exceptions.publickeycredential
18 
19 import androidx.annotation.RestrictTo
20 import androidx.credentials.exceptions.domerrors.AbortError
21 import androidx.credentials.exceptions.domerrors.ConstraintError
22 import androidx.credentials.exceptions.domerrors.DataCloneError
23 import androidx.credentials.exceptions.domerrors.DataError
24 import androidx.credentials.exceptions.domerrors.DomError
25 import androidx.credentials.exceptions.domerrors.EncodingError
26 import androidx.credentials.exceptions.domerrors.HierarchyRequestError
27 import androidx.credentials.exceptions.domerrors.InUseAttributeError
28 import androidx.credentials.exceptions.domerrors.InvalidCharacterError
29 import androidx.credentials.exceptions.domerrors.InvalidModificationError
30 import androidx.credentials.exceptions.domerrors.InvalidNodeTypeError
31 import androidx.credentials.exceptions.domerrors.InvalidStateError
32 import androidx.credentials.exceptions.domerrors.NamespaceError
33 import androidx.credentials.exceptions.domerrors.NetworkError
34 import androidx.credentials.exceptions.domerrors.NoModificationAllowedError
35 import androidx.credentials.exceptions.domerrors.NotAllowedError
36 import androidx.credentials.exceptions.domerrors.NotFoundError
37 import androidx.credentials.exceptions.domerrors.NotReadableError
38 import androidx.credentials.exceptions.domerrors.NotSupportedError
39 import androidx.credentials.exceptions.domerrors.OperationError
40 import androidx.credentials.exceptions.domerrors.OptOutError
41 import androidx.credentials.exceptions.domerrors.QuotaExceededError
42 import androidx.credentials.exceptions.domerrors.ReadOnlyError
43 import androidx.credentials.exceptions.domerrors.SecurityError
44 import androidx.credentials.exceptions.domerrors.SyntaxError
45 import androidx.credentials.exceptions.domerrors.TimeoutError
46 import androidx.credentials.exceptions.domerrors.TransactionInactiveError
47 import androidx.credentials.exceptions.domerrors.UnknownError
48 import androidx.credentials.exceptions.domerrors.VersionError
49 import androidx.credentials.exceptions.domerrors.WrongDocumentError
50 import androidx.credentials.internal.FrameworkClassParsingException
51 
52 /** An internal class that parses dom exceptions originating from providers. */
53 @RestrictTo(RestrictTo.Scope.LIBRARY)
54 internal class DomExceptionUtils {
55     companion object {
56 
57         const val SEPARATOR = "/"
58 
59         @RestrictTo(RestrictTo.Scope.LIBRARY)
generateDomExceptionnull60         internal inline fun <reified T> generateDomException(
61             type: String,
62             prefix: String,
63             msg: String?,
64             t: T
65         ): T {
66 
67             return when (type) {
68                 prefix + AbortError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_ABORT_ERROR ->
69                     generateException(AbortError(), msg, t)
70                 prefix + ConstraintError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_CONSTRAINT_ERROR ->
71                     generateException(ConstraintError(), msg, t)
72                 prefix + DataCloneError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_DATA_CLONE_ERROR ->
73                     generateException(DataCloneError(), msg, t)
74                 prefix + DataError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_DATA_ERROR ->
75                     generateException(DataError(), msg, t)
76                 prefix + EncodingError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_ENCODING_ERROR ->
77                     generateException(EncodingError(), msg, t)
78                 prefix +
79                     HierarchyRequestError
80                         .TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_HIERARCHY_REQUEST_ERROR ->
81                     generateException(HierarchyRequestError(), msg, t)
82                 prefix +
83                     InUseAttributeError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_IN_USE_ATTRIBUTE_ERROR ->
84                     generateException(InUseAttributeError(), msg, t)
85                 prefix +
86                     InvalidCharacterError
87                         .TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_CHARACTER_ERROR ->
88                     generateException(InvalidCharacterError(), msg, t)
89                 prefix +
90                     InvalidModificationError
91                         .TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_MODIFICATION_ERROR ->
92                     generateException(InvalidModificationError(), msg, t)
93                 prefix +
94                     InvalidNodeTypeError
95                         .TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_NODE_TYPE_ERROR ->
96                     generateException(InvalidNodeTypeError(), msg, t)
97                 prefix + InvalidStateError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_STATE_ERROR ->
98                     generateException(InvalidStateError(), msg, t)
99                 prefix + NamespaceError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NAMESPACE_ERROR ->
100                     generateException(NamespaceError(), msg, t)
101                 prefix + NetworkError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NETWORK_ERROR ->
102                     generateException(NetworkError(), msg, t)
103                 prefix +
104                     NoModificationAllowedError
105                         .TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NO_MODIFICATION_ALLOWED_ERROR ->
106                     generateException(NoModificationAllowedError(), msg, t)
107                 prefix + NotAllowedError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_ALLOWED_ERROR ->
108                     generateException(NotAllowedError(), msg, t)
109                 prefix + NotFoundError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_FOUND_ERROR ->
110                     generateException(NotFoundError(), msg, t)
111                 prefix + NotReadableError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_READABLE_ERROR ->
112                     generateException(NotReadableError(), msg, t)
113                 prefix + NotSupportedError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_SUPPORTED_ERROR ->
114                     generateException(NotSupportedError(), msg, t)
115                 prefix + OperationError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_OPERATION_ERROR ->
116                     generateException(OperationError(), msg, t)
117                 prefix + OptOutError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_OPT_OUT_ERROR ->
118                     generateException(OptOutError(), msg, t)
119                 prefix +
120                     QuotaExceededError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_QUOTA_EXCEEDED_ERROR ->
121                     generateException(QuotaExceededError(), msg, t)
122                 prefix + ReadOnlyError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_READ_ONLY_ERROR ->
123                     generateException(ReadOnlyError(), msg, t)
124                 prefix + SecurityError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_SECURITY_ERROR ->
125                     generateException(SecurityError(), msg, t)
126                 prefix + SyntaxError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_SYNTAX_ERROR ->
127                     generateException(SyntaxError(), msg, t)
128                 prefix + TimeoutError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_TIMEOUT_ERROR ->
129                     generateException(TimeoutError(), msg, t)
130                 prefix +
131                     TransactionInactiveError
132                         .TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_TRANSACTION_INACTIVE_ERROR ->
133                     generateException(TransactionInactiveError(), msg, t)
134                 prefix + UnknownError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_UNKNOWN_ERROR ->
135                     generateException(UnknownError(), msg, t)
136                 prefix + VersionError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_VERSION_ERROR ->
137                     generateException(VersionError(), msg, t)
138                 prefix +
139                     WrongDocumentError.TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_WRONG_DOCUMENT_ERROR ->
140                     generateException(WrongDocumentError(), msg, t)
141                 else -> throw FrameworkClassParsingException()
142             }
143         }
144 
145         @Suppress("UNCHECKED_CAST") // Checked, worst case we throw a parsing exception
generateExceptionnull146         private fun <T> generateException(domError: DomError, msg: String?, t: T): T {
147             return when (t) {
148                 is CreatePublicKeyCredentialDomException -> {
149                     CreatePublicKeyCredentialDomException(domError, msg) as T
150                 }
151                 is GetPublicKeyCredentialDomException -> {
152                     GetPublicKeyCredentialDomException(domError, msg) as T
153                 }
154                 else -> {
155                     throw FrameworkClassParsingException()
156                 }
157             }
158         }
159     }
160 }
161