@@ -29,6 +29,7 @@ use tracing::warn;
29
29
use crate :: {
30
30
authorization:: Authorization ,
31
31
broker:: { self , AuthorizedAccess , UpdateError } ,
32
+ glob:: Matcher ,
32
33
permissions:: { self , Permissions } ,
33
34
} ;
34
35
@@ -100,36 +101,141 @@ impl Viss for Server {
100
101
request_id,
101
102
metadata,
102
103
} ) ) ;
103
- }
104
- let permissions = resolve_permissions ( & self . authorization , & request. authorization )
105
- . map_err ( |error| GetErrorResponse {
106
- request_id : request_id. clone ( ) ,
107
- error,
108
- ts : SystemTime :: now ( ) . into ( ) ,
109
- } ) ?;
110
- let broker = self . broker . authorized_access ( & permissions) ;
104
+ } else if let Some ( Filter :: Paths ( paths_filter) ) = & request. filter {
105
+ let request_path = request. path . as_ref ( ) ;
106
+ if request_path. contains ( '*' ) {
107
+ return Err ( GetErrorResponse {
108
+ request_id,
109
+ ts : SystemTime :: now ( ) . into ( ) ,
110
+ error : Error :: NotFoundInvalidPath ,
111
+ } ) ;
112
+ }
113
+
114
+ let permissions = resolve_permissions ( & self . authorization , & request. authorization )
115
+ . map_err ( |error| GetErrorResponse {
116
+ request_id : request_id. clone ( ) ,
117
+ error,
118
+ ts : SystemTime :: now ( ) . into ( ) ,
119
+ } ) ?;
120
+ let broker = self . broker . authorized_access ( & permissions) ;
121
+
122
+ let mut request_matcher: Vec < ( Matcher , bool ) > = Vec :: new ( ) ;
123
+ let mut entries_data = Vec :: new ( ) ;
124
+ let mut signal_errors = Vec :: new ( ) ;
125
+
126
+ for path in & paths_filter. parameter {
127
+ let new_path = format ! ( "{}.{}" , request_path, path) ;
128
+ if let Ok ( matcher) = Matcher :: new ( & new_path) {
129
+ request_matcher. push ( ( matcher, false ) ) ;
130
+ }
131
+ }
132
+
133
+ if !request_matcher. is_empty ( ) {
134
+ for ( matcher, is_match) in & mut request_matcher {
135
+ broker
136
+ . for_each_entry ( |entry| {
137
+ let glob_path = & entry. metadata ( ) . glob_path ;
138
+ let path = entry. metadata ( ) . path . clone ( ) ;
139
+ if matcher. is_match ( glob_path) {
140
+ match entry. datapoint ( ) {
141
+ Ok ( datapoint) => {
142
+ let dp = DataPoint :: from ( datapoint. clone ( ) ) ;
143
+ * is_match = true ;
144
+ entries_data. push ( DataObject {
145
+ path : Path :: from ( path) ,
146
+ dp,
147
+ } ) ;
148
+ }
149
+ Err ( _) => {
150
+ signal_errors. push ( path) ;
151
+ }
152
+ }
153
+ }
154
+ } )
155
+ . await ;
156
+
157
+ // Not found any matches meaning it could be a branch path request
158
+ // Only support branches like Vehicle.Cabin.Sunroof but not like **.Sunroof
159
+ if !matcher. as_string ( ) . starts_with ( "**" )
160
+ && !matcher. as_string ( ) . ends_with ( "/**" )
161
+ && !( * is_match)
162
+ {
163
+ if let Ok ( branch_matcher) = Matcher :: new ( & ( matcher. as_string ( ) + "/**" ) ) {
164
+ broker
165
+ . for_each_entry ( |entry| {
166
+ let glob_path = & entry. metadata ( ) . glob_path ;
167
+ let path = entry. metadata ( ) . path . clone ( ) ;
168
+ if branch_matcher. is_match ( glob_path) {
169
+ match entry. datapoint ( ) {
170
+ Ok ( datapoint) => {
171
+ let dp = DataPoint :: from ( datapoint. clone ( ) ) ;
172
+ * is_match = true ;
173
+ entries_data. push ( DataObject {
174
+ path : Path :: from ( path) ,
175
+ dp,
176
+ } ) ;
177
+ }
178
+ Err ( _) => {
179
+ signal_errors. push ( path) ;
180
+ }
181
+ }
182
+ }
183
+ } )
184
+ . await ;
185
+ }
186
+ }
187
+ }
188
+ }
111
189
112
- // Get datapoints
113
- match broker. get_datapoint_by_path ( request. path . as_ref ( ) ) . await {
114
- Ok ( datapoint) => {
115
- let dp = DataPoint :: from ( datapoint) ;
190
+ // https://w3c.github.io/automotive/spec/VISSv2_Core.html#error-handling
191
+ if signal_errors. is_empty ( ) {
116
192
Ok ( GetSuccessResponse :: Data ( DataResponse {
117
193
request_id,
118
- data : Data :: Object ( DataObject {
119
- path : request. path ,
120
- dp,
121
- } ) ,
194
+ data : Data :: Array ( entries_data) ,
122
195
} ) )
196
+ } else {
197
+ Err ( GetErrorResponse {
198
+ request_id,
199
+ ts : SystemTime :: now ( ) . into ( ) ,
200
+ error : Error :: Forbidden {
201
+ msg : Some ( format ! (
202
+ "Permission denied for some signal: {}" ,
203
+ signal_errors. join( ", " )
204
+ ) ) ,
205
+ } ,
206
+ } )
207
+ }
208
+ } else {
209
+ let permissions = resolve_permissions ( & self . authorization , & request. authorization )
210
+ . map_err ( |error| GetErrorResponse {
211
+ request_id : request_id. clone ( ) ,
212
+ error,
213
+ ts : SystemTime :: now ( ) . into ( ) ,
214
+ } ) ?;
215
+ let broker = self . broker . authorized_access ( & permissions) ;
216
+
217
+ // Get datapoints
218
+ match broker. get_datapoint_by_path ( request. path . as_ref ( ) ) . await {
219
+ Ok ( datapoint) => {
220
+ let dp = DataPoint :: from ( datapoint) ;
221
+ Ok ( GetSuccessResponse :: Data ( DataResponse {
222
+ request_id,
223
+ data : Data :: Object ( DataObject {
224
+ path : request. path ,
225
+ dp,
226
+ } ) ,
227
+ } ) )
228
+ }
229
+ Err ( err) => Err ( GetErrorResponse {
230
+ request_id,
231
+ ts : SystemTime :: now ( ) . into ( ) ,
232
+ error : match err {
233
+ broker:: ReadError :: NotFound => Error :: NotFoundInvalidPath ,
234
+ broker:: ReadError :: PermissionDenied => Error :: Forbidden { msg : None } ,
235
+ broker:: ReadError :: PermissionExpired => Error :: UnauthorizedTokenExpired ,
236
+ } ,
237
+ } ) ,
123
238
}
124
- Err ( err) => Err ( GetErrorResponse {
125
- request_id,
126
- ts : SystemTime :: now ( ) . into ( ) ,
127
- error : match err {
128
- broker:: ReadError :: NotFound => Error :: NotFoundInvalidPath ,
129
- broker:: ReadError :: PermissionDenied => Error :: Forbidden ,
130
- broker:: ReadError :: PermissionExpired => Error :: UnauthorizedTokenExpired ,
131
- } ,
132
- } ) ,
133
239
}
134
240
}
135
241
@@ -211,7 +317,7 @@ impl Viss for Server {
211
317
UpdateError :: UnsupportedType => Error :: BadRequest {
212
318
msg : Some ( "Unsupported data type." . into ( ) ) ,
213
319
} ,
214
- UpdateError :: PermissionDenied => Error :: Forbidden ,
320
+ UpdateError :: PermissionDenied => Error :: Forbidden { msg : None } ,
215
321
UpdateError :: PermissionExpired => Error :: UnauthorizedTokenExpired ,
216
322
}
217
323
} else {
0 commit comments