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  }