2727import eu .openanalytics .containerproxy .model .spec .ProxySpec ;
2828import eu .openanalytics .containerproxy .spec .IProxySpecProvider ;
2929import org .apache .commons .lang3 .StringUtils ;
30- import org .apache .commons .lang3 .tuple .Pair ;
3130import org .springframework .security .core .Authentication ;
3231import org .springframework .stereotype .Service ;
3332
3433import javax .annotation .PostConstruct ;
3534import java .util .ArrayList ;
36- import java .util .Comparator ;
3735import java .util .HashMap ;
3836import java .util .HashSet ;
3937import java .util .List ;
4038import java .util .Map ;
39+ import java .util .Optional ;
4140import java .util .Set ;
4241import java .util .regex .Pattern ;
4342import java .util .stream .Collectors ;
@@ -118,10 +117,21 @@ private void validateSpec(ProxySpec spec) {
118117
119118 }
120119
121- public boolean validateRequest (Authentication auth , ProxySpec resolvedSpec , ProvidedParameters providedParameters ) throws InvalidParametersException {
122- Parameters parameters = resolvedSpec .getParameters ();
120+ /**
121+ * Parses and validates the parameters provided by a user.
122+ * - checks that a value is included for every parameter
123+ * - checks that the user is allowed to use these values
124+ * - converts the (human friendly) name to the backend value
125+ * @param auth the user
126+ * @param spec the Proxy spec to which this requests belong
127+ * @param providedParameters the parameters as provided by the user (using human friendly names)
128+ * @return the parsed parameters (using backend values)
129+ * @throws InvalidParametersException
130+ */
131+ public Optional <ProvidedParameters > parseAndValidateRequest (Authentication auth , ProxySpec spec , ProvidedParameters providedParameters ) throws InvalidParametersException {
132+ Parameters parameters = spec .getParameters ();
123133 if (parameters == null ) {
124- return false ;
134+ return Optional . empty () ;
125135 }
126136
127137 if (providedParameters == null ) {
@@ -142,29 +152,54 @@ public boolean validateRequest(Authentication auth, ProxySpec resolvedSpec, Prov
142152
143153 // check if the combination of values is allowed
144154 for (Parameters .ValueSet valueSet : parameters .getValueSets ()) {
145- if (!accessControlEvaluationService .checkAccess (auth , resolvedSpec , valueSet .getAccessControl ())) {
155+ if (!accessControlEvaluationService .checkAccess (auth , spec , valueSet .getAccessControl ())) {
146156 continue ;
147157 }
148- if (areParametersAllowedByValueSet (parameters .getIds (), valueSet , providedParameters )) {
149- return true ; // parameters are allowed
158+ Optional <ProvidedParameters > res = convertParametersIfAllowed (parameters .getDefinitions (), valueSet , providedParameters );
159+ if (res .isPresent ()) {
160+ return res ; // parameters are allowed, return the converted values
150161 }
151162 }
152163
153164 throw new InvalidParametersException ("Provided parameter values are not allowed" );
154165 }
155166
156- private boolean areParametersAllowedByValueSet (List <String > parameterIds , Parameters .ValueSet valueSet , ProvidedParameters providedParameters ) {
157- for (String parameterId : parameterIds ) {
158- if (!providedParameters .containsParameter (parameterId )) {
159- throw new IllegalStateException ("Could not find value for parameter with id" + parameterId );
167+ /**
168+ * Checks whether the provided parameters are allowed by the given valueSet.
169+ * Returns the converted backend values if (and only if) the provided human-friendly values are allowed by this
170+ * valueSet.
171+ * @param parameters the parameter defintiions
172+ * @param valueSet the valueSet to check
173+ * @param providedParameters the parameters as provided by the user (using human friendly names)
174+ * @return the converted values (i.e. using backend values) if allowed otherwise nothing
175+ */
176+ private Optional <ProvidedParameters > convertParametersIfAllowed (List <ParameterDefinition > parameters , Parameters .ValueSet valueSet , ProvidedParameters providedParameters ) {
177+ Map <String , String > res = new HashMap <>();
178+ for (ParameterDefinition parameter : parameters ) {
179+ if (!providedParameters .containsParameter (parameter .getId ())) {
180+ throw new IllegalStateException ("Could not find value for parameter with id" + parameter .getId ());
181+ }
182+ String providedValue = providedParameters .getValue (parameter .getId ());
183+ String backendValue = parameter .getValueForName (providedValue );
184+ if (backendValue == null ) {
185+ // if we did not find a backend value for the provided value (i.e. the user already provided a backend value),
186+ // check that no mapping exists for this backend value.
187+ // The backend value can only be used if a mapping does not exist.
188+ if (parameter .hasNameForValue (providedValue )) {
189+ return Optional .empty ();
190+ } else {
191+ backendValue = providedValue ;
192+ }
160193 }
161- String providedValue = providedParameters . getValue ( parameterId );
162- if (!valueSet .getParameterValues (parameterId ) .contains (providedValue )) {
163- return false ;
194+ // check whether the backendValue is in the list of allowed values of this valueSet
195+ if (!valueSet .getParameterValues (parameter . getId ()) .contains (backendValue )) {
196+ return Optional . empty () ;
164197 }
198+ res .put (parameter .getId (), backendValue );
165199 }
166200 // providedParameters contains an allowed value for every parameter
167- return true ;
201+ // return the backend values (instead of the names provided by the user)
202+ return Optional .of (new ProvidedParameters (res ));
168203 }
169204
170205 public AllowedParametersForUser calculateAllowedParametersForUser (Authentication auth , ProxySpec proxySpec ) {
@@ -174,7 +209,7 @@ public AllowedParametersForUser calculateAllowedParametersForUser(Authentication
174209 }
175210 List <String > parameterIds = parameters .getIds ();
176211
177- // 1. check which ValueSets are allowed for this
212+ // 1. check which ValueSets are allowed for this user
178213 List <Parameters .ValueSet > allowedValueSets = parameters .getValueSets ().stream ()
179214 .filter (v -> accessControlEvaluationService .checkAccess (auth , proxySpec , v .getAccessControl ()))
180215 .collect (Collectors .toList ());
@@ -186,25 +221,24 @@ public AllowedParametersForUser calculateAllowedParametersForUser(Authentication
186221 // for every set of allowed values
187222 for (Parameters .ValueSet valueSet : allowedValueSets ) {
188223 // for every parameter in this set
189- for (String parameterId : parameterIds ) {
190- valuesToIndex .computeIfAbsent (parameterId , (k ) -> new HashMap <>());
191- values .computeIfAbsent (parameterId , (k ) -> new ArrayList <>());
224+ for (ParameterDefinition parameter : parameters . getDefinitions () ) {
225+ valuesToIndex .computeIfAbsent (parameter . getId () , (k ) -> new HashMap <>());
226+ values .computeIfAbsent (parameter . getId () , (k ) -> new ArrayList <>());
192227 // for every value of this parameter
193- for (String value : valueSet .getParameterValues (parameterId )) {
194- if (!valuesToIndex .get (parameterId ).containsKey (value )) {
228+ for (String value : valueSet .getParameterValues (parameter . getId () )) {
229+ if (!valuesToIndex .get (parameter . getId () ).containsKey (value )) {
195230 // add it to allValues if it does not yet exist
196- Integer newIndex = values .get (parameterId ).size () + 1 ;
197- valuesToIndex .get (parameterId ).put (value , newIndex );
198- values .get (parameterId ) .add (value );
231+ Integer newIndex = values .get (parameter . getId () ).size () + 1 ;
232+ valuesToIndex .get (parameter . getId () ).put (value , newIndex );
233+ values .get (parameter . getId ()) .add (parameter . getNameOfValue ( value ) );
199234 }
200235 }
201236 }
202237 }
203238
204- // 3. compute the set of allowed values
239+ // 3. compute the set of allowed values for every value-set
205240 HashSet <List <Integer >> allowedCombinations = new HashSet <>();
206241
207- // for every value-set
208242 for (Parameters .ValueSet valueSet : allowedValueSets ) {
209243 allowedCombinations .addAll (getAllowedCombinationsForSingleValueSet (parameterIds , valueSet , valuesToIndex ));
210244 }
0 commit comments