1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * * Neither the name of Google LLC nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package com.google.auth.oauth2; 33 34 import static org.junit.Assert.assertEquals; 35 import static org.junit.Assert.assertNull; 36 import static org.junit.Assert.fail; 37 38 import com.google.auth.oauth2.CredentialAccessBoundary.AccessBoundaryRule; 39 import com.google.auth.oauth2.CredentialAccessBoundary.AccessBoundaryRule.AvailabilityCondition; 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.Collections; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.junit.runners.JUnit4; 46 47 /** Tests for {@link CredentialAccessBoundary} and encompassing classes. */ 48 @RunWith(JUnit4.class) 49 public class CredentialAccessBoundaryTest { 50 51 @Test credentialAccessBoundary()52 public void credentialAccessBoundary() { 53 AvailabilityCondition availabilityCondition = 54 AvailabilityCondition.newBuilder().setExpression("expression").build(); 55 56 AccessBoundaryRule firstRule = 57 AccessBoundaryRule.newBuilder() 58 .setAvailableResource("firstResource") 59 .addAvailablePermission("firstPermission") 60 .setAvailabilityCondition(availabilityCondition) 61 .build(); 62 63 AccessBoundaryRule secondRule = 64 AccessBoundaryRule.newBuilder() 65 .setAvailableResource("secondResource") 66 .addAvailablePermission("secondPermission") 67 .build(); 68 69 CredentialAccessBoundary credentialAccessBoundary = 70 CredentialAccessBoundary.newBuilder() 71 .setRules(Arrays.asList(firstRule, secondRule)) 72 .build(); 73 74 assertEquals(2, credentialAccessBoundary.getAccessBoundaryRules().size()); 75 76 AccessBoundaryRule first = credentialAccessBoundary.getAccessBoundaryRules().get(0); 77 assertEquals(firstRule, first); 78 assertEquals("firstResource", first.getAvailableResource()); 79 assertEquals(1, first.getAvailablePermissions().size()); 80 assertEquals("firstPermission", first.getAvailablePermissions().get(0)); 81 assertEquals(availabilityCondition, first.getAvailabilityCondition()); 82 assertEquals("expression", first.getAvailabilityCondition().getExpression()); 83 assertNull(first.getAvailabilityCondition().getTitle()); 84 assertNull(first.getAvailabilityCondition().getDescription()); 85 86 AccessBoundaryRule second = credentialAccessBoundary.getAccessBoundaryRules().get(1); 87 assertEquals(secondRule, second); 88 assertEquals("secondResource", second.getAvailableResource()); 89 assertEquals(1, second.getAvailablePermissions().size()); 90 assertEquals("secondPermission", second.getAvailablePermissions().get(0)); 91 assertNull(second.getAvailabilityCondition()); 92 } 93 94 @Test credentialAccessBoundary_nullRules_throws()95 public void credentialAccessBoundary_nullRules_throws() { 96 try { 97 CredentialAccessBoundary.newBuilder().build(); 98 fail("Should fail."); 99 } catch (NullPointerException e) { 100 // Expected. 101 } 102 } 103 104 @Test credentialAccessBoundary_withoutRules_throws()105 public void credentialAccessBoundary_withoutRules_throws() { 106 try { 107 CredentialAccessBoundary.newBuilder().setRules(new ArrayList<AccessBoundaryRule>()).build(); 108 fail("Should fail."); 109 } catch (IllegalArgumentException e) { 110 assertEquals("At least one access boundary rule must be provided.", e.getMessage()); 111 } 112 } 113 114 @Test credentialAccessBoundary_ruleCountExceeded_throws()115 public void credentialAccessBoundary_ruleCountExceeded_throws() { 116 AccessBoundaryRule rule = 117 AccessBoundaryRule.newBuilder() 118 .setAvailableResource("resource") 119 .addAvailablePermission("permission") 120 .build(); 121 122 CredentialAccessBoundary.Builder builder = CredentialAccessBoundary.newBuilder(); 123 for (int i = 0; i <= 10; i++) { 124 builder.addRule(rule); 125 } 126 127 try { 128 builder.build(); 129 fail("Should fail."); 130 } catch (IllegalArgumentException e) { 131 assertEquals("The provided list has more than 10 access boundary rules.", e.getMessage()); 132 } 133 } 134 135 @Test credentialAccessBoundary_toJson()136 public void credentialAccessBoundary_toJson() { 137 AvailabilityCondition availabilityCondition = 138 AvailabilityCondition.newBuilder() 139 .setExpression("expression") 140 .setTitle("title") 141 .setDescription("description") 142 .build(); 143 144 AccessBoundaryRule firstRule = 145 AccessBoundaryRule.newBuilder() 146 .setAvailableResource("firstResource") 147 .addAvailablePermission("firstPermission") 148 .setAvailabilityCondition(availabilityCondition) 149 .build(); 150 151 AccessBoundaryRule secondRule = 152 AccessBoundaryRule.newBuilder() 153 .setAvailableResource("secondResource") 154 .setAvailablePermissions(Arrays.asList("firstPermission", "secondPermission")) 155 .build(); 156 157 CredentialAccessBoundary credentialAccessBoundary = 158 CredentialAccessBoundary.newBuilder() 159 .setRules(Arrays.asList(firstRule, secondRule)) 160 .build(); 161 162 String expectedJson = 163 "{\"accessBoundary\":{\"accessBoundaryRules\":" 164 + "[{\"availableResource\":\"firstResource\"," 165 + "\"availablePermissions\":[\"firstPermission\"]," 166 + "\"availabilityCondition\":{\"expression\":\"expression\"," 167 + "\"title\":\"title\",\"description\":\"description\"}}," 168 + "{\"availableResource\":\"secondResource\"," 169 + "\"availablePermissions\":[\"firstPermission\"," 170 + "\"secondPermission\"]}]}}"; 171 assertEquals(expectedJson, credentialAccessBoundary.toJson()); 172 } 173 174 @Test accessBoundaryRule_allFields()175 public void accessBoundaryRule_allFields() { 176 AvailabilityCondition availabilityCondition = 177 AvailabilityCondition.newBuilder().setExpression("expression").build(); 178 179 AccessBoundaryRule rule = 180 AccessBoundaryRule.newBuilder() 181 .setAvailableResource("resource") 182 .addAvailablePermission("firstPermission") 183 .addAvailablePermission("secondPermission") 184 .setAvailabilityCondition(availabilityCondition) 185 .build(); 186 187 assertEquals("resource", rule.getAvailableResource()); 188 assertEquals(2, rule.getAvailablePermissions().size()); 189 assertEquals("firstPermission", rule.getAvailablePermissions().get(0)); 190 assertEquals("secondPermission", rule.getAvailablePermissions().get(1)); 191 assertEquals(availabilityCondition, rule.getAvailabilityCondition()); 192 } 193 194 @Test accessBoundaryRule_requiredFields()195 public void accessBoundaryRule_requiredFields() { 196 AccessBoundaryRule rule = 197 AccessBoundaryRule.newBuilder() 198 .setAvailableResource("resource") 199 .setAvailablePermissions(Collections.singletonList("firstPermission")) 200 .build(); 201 202 assertEquals("resource", rule.getAvailableResource()); 203 assertEquals(1, rule.getAvailablePermissions().size()); 204 assertEquals("firstPermission", rule.getAvailablePermissions().get(0)); 205 assertNull(rule.getAvailabilityCondition()); 206 } 207 208 @Test accessBoundaryRule_withEmptyAvailableResource_throws()209 public void accessBoundaryRule_withEmptyAvailableResource_throws() { 210 try { 211 AccessBoundaryRule.newBuilder() 212 .setAvailableResource("") 213 .addAvailablePermission("permission") 214 .build(); 215 fail("Should fail."); 216 } catch (IllegalArgumentException e) { 217 assertEquals("The provided availableResource is empty.", e.getMessage()); 218 } 219 } 220 221 @Test accessBoundaryRule_withoutAvailableResource_throws()222 public void accessBoundaryRule_withoutAvailableResource_throws() { 223 try { 224 AccessBoundaryRule.newBuilder().addAvailablePermission("permission").build(); 225 fail("Should fail."); 226 } catch (NullPointerException e) { 227 // Expected. 228 } 229 } 230 231 @Test accessBoundaryRule_withoutAvailablePermissions_throws()232 public void accessBoundaryRule_withoutAvailablePermissions_throws() { 233 try { 234 AccessBoundaryRule.newBuilder().setAvailableResource("resource").build(); 235 fail("Should fail."); 236 } catch (NullPointerException e) { 237 // Expected. 238 } 239 } 240 241 @Test accessBoundaryRule_withEmptyAvailablePermissions_throws()242 public void accessBoundaryRule_withEmptyAvailablePermissions_throws() { 243 try { 244 AccessBoundaryRule.newBuilder() 245 .setAvailableResource("resource") 246 .setAvailablePermissions(new ArrayList<String>()) 247 .build(); 248 fail("Should fail."); 249 } catch (IllegalArgumentException e) { 250 assertEquals("The list of provided availablePermissions is empty.", e.getMessage()); 251 } 252 } 253 254 @Test accessBoundaryRule_withNullAvailablePermissions_throws()255 public void accessBoundaryRule_withNullAvailablePermissions_throws() { 256 try { 257 AccessBoundaryRule.newBuilder() 258 .setAvailableResource("resource") 259 .addAvailablePermission(null) 260 .build(); 261 fail("Should fail."); 262 } catch (IllegalArgumentException e) { 263 assertEquals("One of the provided available permissions is null.", e.getMessage()); 264 } 265 } 266 267 @Test accessBoundaryRule_withEmptyAvailablePermission_throws()268 public void accessBoundaryRule_withEmptyAvailablePermission_throws() { 269 try { 270 AccessBoundaryRule.newBuilder() 271 .setAvailableResource("resource") 272 .addAvailablePermission("") 273 .build(); 274 fail("Should fail."); 275 } catch (IllegalArgumentException e) { 276 assertEquals("One of the provided available permissions is empty.", e.getMessage()); 277 } 278 } 279 280 @Test availabilityCondition_allFields()281 public void availabilityCondition_allFields() { 282 AvailabilityCondition availabilityCondition = 283 AvailabilityCondition.newBuilder() 284 .setExpression("expression") 285 .setTitle("title") 286 .setDescription("description") 287 .build(); 288 289 assertEquals("expression", availabilityCondition.getExpression()); 290 assertEquals("title", availabilityCondition.getTitle()); 291 assertEquals("description", availabilityCondition.getDescription()); 292 } 293 294 @Test availabilityCondition_expressionOnly()295 public void availabilityCondition_expressionOnly() { 296 AvailabilityCondition availabilityCondition = 297 AvailabilityCondition.newBuilder().setExpression("expression").build(); 298 299 assertEquals("expression", availabilityCondition.getExpression()); 300 assertNull(availabilityCondition.getTitle()); 301 assertNull(availabilityCondition.getDescription()); 302 } 303 304 @Test availabilityCondition_nullExpression_throws()305 public void availabilityCondition_nullExpression_throws() { 306 try { 307 AvailabilityCondition.newBuilder().setExpression(null).build(); 308 fail("Should fail."); 309 } catch (NullPointerException e) { 310 // Expected. 311 } 312 } 313 314 @Test availabilityCondition_emptyExpression_throws()315 public void availabilityCondition_emptyExpression_throws() { 316 try { 317 AvailabilityCondition.newBuilder().setExpression("").build(); 318 fail("Should fail."); 319 } catch (IllegalArgumentException e) { 320 assertEquals("The provided expression is empty.", e.getMessage()); 321 } 322 } 323 } 324