github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/registry/auth/htpasswd/access_test.go (about) 1 package htpasswd 2 3 import ( 4 "io/ioutil" 5 "net/http" 6 "net/http/httptest" 7 "testing" 8 9 "github.com/docker/distribution/context" 10 "github.com/docker/distribution/registry/auth" 11 ) 12 13 func TestBasicAccessController(t *testing.T) { 14 testRealm := "The-Shire" 15 testUsers := []string{"bilbo", "frodo", "MiShil", "DeokMan"} 16 testPasswords := []string{"baggins", "baggins", "새주", "공주님"} 17 testHtpasswdContent := `bilbo:{SHA}5siv5c0SHx681xU6GiSx9ZQryqs= 18 frodo:$2y$05$926C3y10Quzn/LnqQH86VOEVh/18T6RnLaS.khre96jLNL/7e.K5W 19 MiShil:$2y$05$0oHgwMehvoe8iAWS8I.7l.KoECXrwVaC16RPfaSCU5eVTFrATuMI2 20 DeokMan:공주님` 21 22 tempFile, err := ioutil.TempFile("", "htpasswd-test") 23 if err != nil { 24 t.Fatal("could not create temporary htpasswd file") 25 } 26 if _, err = tempFile.WriteString(testHtpasswdContent); err != nil { 27 t.Fatal("could not write temporary htpasswd file") 28 } 29 30 options := map[string]interface{}{ 31 "realm": testRealm, 32 "path": tempFile.Name(), 33 } 34 ctx := context.Background() 35 36 accessController, err := newAccessController(options) 37 if err != nil { 38 t.Fatal("error creating access controller") 39 } 40 41 tempFile.Close() 42 43 var userNumber = 0 44 45 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 46 ctx := context.WithRequest(ctx, r) 47 authCtx, err := accessController.Authorized(ctx) 48 if err != nil { 49 switch err := err.(type) { 50 case auth.Challenge: 51 err.SetHeaders(w) 52 w.WriteHeader(http.StatusUnauthorized) 53 return 54 default: 55 t.Fatalf("unexpected error authorizing request: %v", err) 56 } 57 } 58 59 userInfo, ok := authCtx.Value("auth.user").(auth.UserInfo) 60 if !ok { 61 t.Fatal("basic accessController did not set auth.user context") 62 } 63 64 if userInfo.Name != testUsers[userNumber] { 65 t.Fatalf("expected user name %q, got %q", testUsers[userNumber], userInfo.Name) 66 } 67 68 w.WriteHeader(http.StatusNoContent) 69 })) 70 71 client := &http.Client{ 72 CheckRedirect: nil, 73 } 74 75 req, _ := http.NewRequest("GET", server.URL, nil) 76 resp, err := client.Do(req) 77 78 if err != nil { 79 t.Fatalf("unexpected error during GET: %v", err) 80 } 81 defer resp.Body.Close() 82 83 // Request should not be authorized 84 if resp.StatusCode != http.StatusUnauthorized { 85 t.Fatalf("unexpected non-fail response status: %v != %v", resp.StatusCode, http.StatusUnauthorized) 86 } 87 88 nonbcrypt := map[string]struct{}{ 89 "bilbo": {}, 90 "DeokMan": {}, 91 } 92 93 for i := 0; i < len(testUsers); i++ { 94 userNumber = i 95 req, err := http.NewRequest("GET", server.URL, nil) 96 if err != nil { 97 t.Fatalf("error allocating new request: %v", err) 98 } 99 100 req.SetBasicAuth(testUsers[i], testPasswords[i]) 101 102 resp, err = client.Do(req) 103 if err != nil { 104 t.Fatalf("unexpected error during GET: %v", err) 105 } 106 defer resp.Body.Close() 107 108 if _, ok := nonbcrypt[testUsers[i]]; ok { 109 // these are not allowed. 110 // Request should be authorized 111 if resp.StatusCode != http.StatusUnauthorized { 112 t.Fatalf("unexpected non-success response status: %v != %v for %s %s", resp.StatusCode, http.StatusUnauthorized, testUsers[i], testPasswords[i]) 113 } 114 } else { 115 // Request should be authorized 116 if resp.StatusCode != http.StatusNoContent { 117 t.Fatalf("unexpected non-success response status: %v != %v for %s %s", resp.StatusCode, http.StatusNoContent, testUsers[i], testPasswords[i]) 118 } 119 } 120 } 121 122 }