Error handling refactor
This refactor aims to improve error handling throughout the project by refining the overarching error types and increasing usage of proper error handling. Replaced existing networked operation error with `NetworkOperationError`. `NetworkOperationError` does not forward any internal error details, which allows `OperationError` to grow into a better error type. `OperationError` now has support for storing real typed errors inside of it for better debugging. `IntoInternalError` is a trait which allows for easy conversion of error types into `OperationError::internal`.
parent: tbd commit: e02c03d
1 | use |
2 | , | SocketAddr
3 | , | Deref
4 | , |
5 | ; |
6 | |
7 | use Error; |
8 | use ; |
9 | |
10 | use |
11 | , |
12 | , | OperationError
13 | , | Instance
14 | ; |
15 | |
16 | use AuthenticatedPayload; |
17 | use |
18 | AuthenticatedInstance, AuthenticatedUser, GiteratedStack, StackOperationState, |
19 | ; |
20 | use ; |
21 | use |
22 | , | DecodeRsaPublicKey
23 | , |
24 | , | Sha256
25 | , | Verifier
26 | RsaPublicKey, |
27 | ; |
28 | use Serialize; |
29 | |
30 | use ; |
31 | use ; |
32 | use Table; |
33 | |
34 | use crate:: |
35 | , | AuthenticationTokenGranter
36 | , |
37 | , | InstanceConnections
38 | , | PublicKeyCache
39 | ; |
40 | |
41 | use Connections; |
42 | |
43 | pub async |
44 | socket: , |
45 | connections: , |
46 | repository_backend: , |
47 | user_backend: , |
48 | auth_granter: , |
49 | settings_backend: , |
50 | addr: SocketAddr, |
51 | instance: impl , |
52 | instance_connections: , |
53 | config: Table, |
54 | runtime: , |
55 | mut operation_state: StackOperationState, |
56 | |
57 | let connection_state = ConnectionState |
58 | socket: new, |
59 | connections, |
60 | repository_backend, |
61 | user_backend, |
62 | auth_granter, |
63 | settings_backend, |
64 | addr, |
65 | instance: instance.to_owned, |
66 | handshaked: new, |
67 | key_cache: default, |
68 | instance_connections: instance_connections.clone, |
69 | config, |
70 | ; |
71 | |
72 | let _handshaked = false; |
73 | let mut key_cache = default; |
74 | |
75 | loop |
76 | let mut socket = connection_state.socket.lock .await; |
77 | let message = socket.next .await; |
78 | drop; |
79 | |
80 | match message |
81 | Some => |
82 | let payload = match message |
83 | => payload, | Binary
84 | => | Ping
85 | let mut socket = connection_state.socket.lock .await; |
86 | let _ = socket.send .await; |
87 | drop; |
88 | continue; |
89 | |
90 | => return, | Close
91 | _ => continue, |
92 | ; |
93 | |
94 | let message: AuthenticatedPayload = deserialize .unwrap; |
95 | |
96 | // Get authentication |
97 | let instance = |
98 | let mut verified_instance: = None; |
99 | for source in &message.source |
100 | if let Instance |
101 | instance, |
102 | signature, |
103 | = source |
104 | |
105 | let public_key = key_cache.get .await.unwrap; |
106 | let public_key = from_pkcs1_pem .unwrap; |
107 | let verifying_key = new; |
108 | |
109 | if verifying_key |
110 | .verify |
111 | &message.payload, |
112 | & try_from .unwrap, |
113 | |
114 | .is_ok |
115 | |
116 | verified_instance = |
117 | Some; |
118 | |
119 | break; |
120 | |
121 | |
122 | |
123 | |
124 | verified_instance |
125 | ; |
126 | |
127 | let user = |
128 | let mut verified_user = None; |
129 | if let Some = &instance |
130 | for source in &message.source |
131 | if let User = source |
132 | // Get token |
133 | let public_key = key_cache.get .await.unwrap; |
134 | |
135 | let token: = decode |
136 | token.as_ref, |
137 | & from_rsa_pem .unwrap, |
138 | & new, |
139 | |
140 | .unwrap; |
141 | |
142 | if token.claims.generated_for != *verified_instance.deref |
143 | // Nope! |
144 | break; |
145 | |
146 | |
147 | if token.claims.user != *user |
148 | // Nope! |
149 | break; |
150 | |
151 | |
152 | verified_user = Some; |
153 | break; |
154 | |
155 | |
156 | |
157 | |
158 | verified_user |
159 | ; |
160 | |
161 | operation_state.user = user; |
162 | operation_state.instance = instance; |
163 | |
164 | let result = runtime |
165 | .handle_network_message |
166 | .await; |
167 | |
168 | // Asking for exploits here |
169 | operation_state.user = None; |
170 | operation_state.instance = None; |
171 | |
172 | if let Err = &result |
173 | error!; |
174 | |
175 | |
176 | // Map error to the network variant |
177 | let result = result.map_err; |
178 | |
179 | let mut socket = connection_state.socket.lock .await; |
180 | let _ = socket |
181 | .send |
182 | .await; |
183 | |
184 | drop; |
185 | |
186 | _ => |
187 | return; |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | socket: , |
196 | pub connections: , |
197 | pub repository_backend: , |
198 | pub user_backend: , |
199 | pub auth_granter: , |
200 | pub settings_backend: , |
201 | pub addr: SocketAddr, |
202 | pub instance: Instance, |
203 | pub handshaked: , |
204 | pub key_cache: , |
205 | pub instance_connections: , |
206 | pub config: Table, |
207 | |
208 | |
209 | |
210 | pub async |
211 | let payload = to_string?; |
212 | self.socket |
213 | .lock |
214 | .await |
215 | .send |
216 | .await?; |
217 | |
218 | Ok |
219 | |
220 | |
221 | pub async |
222 | let payload = to_string?; |
223 | self.socket |
224 | .lock |
225 | .await |
226 | .send |
227 | .await?; |
228 | |
229 | Ok |
230 | |
231 | |
232 | pub async |
233 | let mut keys = self.key_cache.lock .await; |
234 | keys.get .await |
235 | |
236 | |
237 |