Rust implementation of OCI Distribution Spec with granular access control
at main 322 lines 7.7 kB view raw
1mod common; 2 3use common::*; 4use serial_test::serial; 5 6#[test] 7#[serial] 8fn test_admin_list_users() { 9 let mut server = TestServer::new(); 10 server.start(); 11 let client = server.client(); 12 13 let resp = client 14 .get("/admin/users") 15 .basic_auth("admin", Some("admin")) 16 .send() 17 .unwrap(); 18 19 assert_eq!(resp.status(), 200); 20 let json: serde_json::Value = resp.json().unwrap(); 21 22 let users = json["users"].as_array().unwrap(); 23 assert!(users.len() >= 4); // admin, reader, writer, limited 24 25 // Verify admin user exists 26 let admin_user = users.iter().find(|u| u["username"] == "admin"); 27 assert!(admin_user.is_some()); 28} 29 30#[test] 31#[serial] 32fn test_admin_create_user() { 33 let mut server = TestServer::new(); 34 server.start(); 35 let client = server.client(); 36 37 let new_user = serde_json::json!({ 38 "username": "newuser", 39 "password": "newpass", 40 "permissions": [] 41 }); 42 43 let resp = client 44 .post("/admin/users") 45 .basic_auth("admin", Some("admin")) 46 .json(&new_user) 47 .send() 48 .unwrap(); 49 50 assert_eq!(resp.status(), 201); 51 52 // Verify user can authenticate 53 let resp = client 54 .get("/v2/") 55 .basic_auth("newuser", Some("newpass")) 56 .send() 57 .unwrap(); 58 assert_eq!(resp.status(), 200); 59} 60 61#[test] 62#[serial] 63fn test_admin_create_duplicate_user() { 64 let mut server = TestServer::new(); 65 server.start(); 66 let client = server.client(); 67 68 let duplicate_user = serde_json::json!({ 69 "username": "admin", 70 "password": "newpass", 71 "permissions": [] 72 }); 73 74 let resp = client 75 .post("/admin/users") 76 .basic_auth("admin", Some("admin")) 77 .json(&duplicate_user) 78 .send() 79 .unwrap(); 80 81 assert_eq!(resp.status(), 409); // Conflict 82} 83 84#[test] 85#[serial] 86fn test_admin_delete_user() { 87 let mut server = TestServer::new(); 88 server.start(); 89 let client = server.client(); 90 91 // Create user first 92 let new_user = serde_json::json!({ 93 "username": "todelete", 94 "password": "pass", 95 "permissions": [] 96 }); 97 98 client 99 .post("/admin/users") 100 .basic_auth("admin", Some("admin")) 101 .json(&new_user) 102 .send() 103 .unwrap(); 104 105 // Delete user 106 let resp = client 107 .delete("/admin/users/todelete") 108 .basic_auth("admin", Some("admin")) 109 .send() 110 .unwrap(); 111 112 assert_eq!(resp.status(), 200); 113 114 // Verify user cannot authenticate 115 let resp = client 116 .get("/v2/") 117 .basic_auth("todelete", Some("pass")) 118 .send() 119 .unwrap(); 120 assert_eq!(resp.status(), 401); 121} 122 123#[test] 124#[serial] 125fn test_admin_delete_nonexistent_user() { 126 let mut server = TestServer::new(); 127 server.start(); 128 let client = server.client(); 129 130 let resp = client 131 .delete("/admin/users/nonexistent") 132 .basic_auth("admin", Some("admin")) 133 .send() 134 .unwrap(); 135 136 assert_eq!(resp.status(), 404); 137} 138 139#[test] 140#[serial] 141fn test_admin_add_permission() { 142 let mut server = TestServer::new(); 143 server.start(); 144 let client = server.client(); 145 146 // Create user with no permissions 147 let new_user = serde_json::json!({ 148 "username": "testperm", 149 "password": "pass", 150 "permissions": [] 151 }); 152 153 client 154 .post("/admin/users") 155 .basic_auth("admin", Some("admin")) 156 .json(&new_user) 157 .send() 158 .unwrap(); 159 160 // User should not be able to push 161 let blob = sample_blob(); 162 let digest = sample_blob_digest(); 163 let resp = client 164 .post(&format!("/v2/test/repo/blobs/uploads/?digest={}", digest)) 165 .basic_auth("testperm", Some("pass")) 166 .body(blob.clone()) 167 .send() 168 .unwrap(); 169 assert_eq!(resp.status(), 403); 170 171 // Add permission 172 let permission = serde_json::json!({ 173 "username": "testperm", 174 "repository": "test/*", 175 "tag": "*", 176 "actions": ["pull", "push"] 177 }); 178 179 let resp = client 180 .post("/admin/permissions") 181 .basic_auth("admin", Some("admin")) 182 .json(&permission) 183 .send() 184 .unwrap(); 185 186 assert_eq!(resp.status(), 200); 187 188 // User should now be able to push 189 let resp = client 190 .post(&format!("/v2/test/repo/blobs/uploads/?digest={}", digest)) 191 .basic_auth("testperm", Some("pass")) 192 .body(blob) 193 .send() 194 .unwrap(); 195 assert_eq!(resp.status(), 201); 196} 197 198#[test] 199#[serial] 200fn test_admin_requires_admin_permission() { 201 let mut server = TestServer::new(); 202 server.start(); 203 let client = server.client(); 204 205 // Non-admin users should not access admin endpoints 206 let resp = client 207 .get("/admin/users") 208 .basic_auth("reader", Some("reader")) 209 .send() 210 .unwrap(); 211 assert_eq!(resp.status(), 403); 212 213 let resp = client 214 .post("/admin/users") 215 .basic_auth("writer", Some("writer")) 216 .json(&serde_json::json!({"username": "test", "password": "test", "permissions": []})) 217 .send() 218 .unwrap(); 219 assert_eq!(resp.status(), 403); 220 221 // Admin should have access 222 let resp = client 223 .get("/admin/users") 224 .basic_auth("admin", Some("admin")) 225 .send() 226 .unwrap(); 227 assert_eq!(resp.status(), 200); 228} 229 230#[test] 231#[serial] 232fn test_admin_api_requires_authentication() { 233 let mut server = TestServer::new(); 234 server.start(); 235 let client = server.client(); 236 237 // No auth should fail 238 let resp = client.get("/admin/users").send().unwrap(); 239 assert_eq!(resp.status(), 401); 240 241 // Invalid credentials should fail 242 let resp = client 243 .get("/admin/users") 244 .basic_auth("invalid", Some("invalid")) 245 .send() 246 .unwrap(); 247 assert_eq!(resp.status(), 401); 248} 249 250#[test] 251#[serial] 252fn test_admin_create_user_with_permissions() { 253 let mut server = TestServer::new(); 254 server.start(); 255 let client = server.client(); 256 257 let new_user = serde_json::json!({ 258 "username": "fulluser", 259 "password": "pass", 260 "permissions": [ 261 { 262 "repository": "myorg/*", 263 "tag": "*", 264 "actions": ["pull", "push"] 265 } 266 ] 267 }); 268 269 let resp = client 270 .post("/admin/users") 271 .basic_auth("admin", Some("admin")) 272 .json(&new_user) 273 .send() 274 .unwrap(); 275 276 assert_eq!(resp.status(), 201); 277 278 // Verify permissions work 279 let blob = sample_blob(); 280 let digest = sample_blob_digest(); 281 let resp = client 282 .post(&format!("/v2/myorg/repo/blobs/uploads/?digest={}", digest)) 283 .basic_auth("fulluser", Some("pass")) 284 .body(blob) 285 .send() 286 .unwrap(); 287 assert_eq!(resp.status(), 201); 288} 289 290#[test] 291#[serial] 292fn test_admin_user_persistence() { 293 let mut server = TestServer::new(); 294 server.start(); 295 let client = server.client(); 296 297 // Create user 298 let new_user = serde_json::json!({ 299 "username": "persistent", 300 "password": "pass", 301 "permissions": [] 302 }); 303 304 client 305 .post("/admin/users") 306 .basic_auth("admin", Some("admin")) 307 .json(&new_user) 308 .send() 309 .unwrap(); 310 311 // Verify user exists in list 312 let resp = client 313 .get("/admin/users") 314 .basic_auth("admin", Some("admin")) 315 .send() 316 .unwrap(); 317 318 let json: serde_json::Value = resp.json().unwrap(); 319 let users = json["users"].as_array().unwrap(); 320 let persistent_user = users.iter().find(|u| u["username"] == "persistent"); 321 assert!(persistent_user.is_some()); 322}