Make Authenticate issue an HTTP request
diff --git a/authenticate.go b/authenticate.go
index 754823c..54be5a4 100644
--- a/authenticate.go
+++ b/authenticate.go
@@ -1,17 +1,61 @@
 package gophercloud
 
+import (
+	"github.com/racker/perigee"
+)
+
 type AuthOptions struct {
 	Username, Password, TenantId string
 }
 
-func (c *Context) Authenticate(provider string, options AuthOptions) (*int, error) {
-	_, err := c.ProviderByName(provider)
+type AuthContainer struct {
+	Auth Auth `json:"auth"`
+}
+
+type Auth struct {
+	PasswordCredentials PasswordCredentials `json:"passwordCredentials"`
+	TenantId string `json:"tenantId,omitempty"`
+}
+
+type PasswordCredentials struct {
+	Username string `json:"username"`
+	Password string `json:"password"`
+}
+
+type ProviderAccess interface {
+	// ...
+}
+
+func (c *Context) Authenticate(provider string, options AuthOptions) (ProviderAccess, error) {
+	p, err := c.ProviderByName(provider)
 	if err != nil {
 		return nil, err
 	}
-
 	if (options.Username == "") || (options.Password == "") {
 		return nil, ErrCredentials
 	}
+
+	err = perigee.Post(p.AuthEndpoint, perigee.Options{
+		CustomClient: c.httpClient,
+		ReqBody:      &AuthContainer{
+			Auth: Auth{
+				PasswordCredentials: PasswordCredentials{
+					Username: options.Username,
+					Password: options.Password,
+				},
+				TenantId: options.TenantId,
+			},
+		},
+	})
 	return nil, nil
+
+	// if err != nil {
+	// 	return err
+	// }
+
+	// c.isAuthenticated = true
+	// c.token = id.access.Access.Token.Id
+	// c.expires = id.access.Access.Token.Expires
+	// c.tenantId = id.access.Access.Token.Tenant.Id
+	// c.tenantName = id.access.Access.Token.Tenant.Name
 }
diff --git a/authenticate_test.go b/authenticate_test.go
index 596df40..f8bbd95 100644
--- a/authenticate_test.go
+++ b/authenticate_test.go
@@ -2,10 +2,48 @@
 
 import (
 	"testing"
+	"net/http"
+	"io/ioutil"
+	"strings"
 )
 
+
+type testTransport struct {
+	called int
+	response string
+}
+
+func (t *testTransport) RoundTrip(req *http.Request) (rsp *http.Response, err error) {
+	t.called++;
+
+	headers := make(http.Header)
+	headers.Add("Content-Type", "application/xml; charset=UTF-8")
+
+	body := ioutil.NopCloser(strings.NewReader(t.response))
+
+	rsp = &http.Response{
+		Status: "200 OK",
+		StatusCode: 200,
+		Proto: "HTTP/1.1",
+		ProtoMajor: 1,
+		ProtoMinor: 1,
+		Header: headers,
+		Body: body,
+		ContentLength: -1,
+		TransferEncoding: nil,
+		Close: true,
+		Trailer: nil,
+		Request: req,
+	}
+	return
+}
+
 func TestAuthProvider(t *testing.T) {
 	c := TestContext()
+	tt := &testTransport{}
+	c.UseCustomClient(&http.Client{
+		Transport: tt,
+	})
 
 	_, err := c.Authenticate("", AuthOptions{})
 	if err == nil {
@@ -18,7 +56,7 @@
 		return
 	}
 
-	err = c.RegisterProvider("provider", &Provider{})
+	err = c.RegisterProvider("provider", &Provider{AuthEndpoint: "/"})
 	if err != nil {
 		t.Error(err)
 		return
@@ -28,11 +66,15 @@
 		t.Error(err)
 		return
 	}
+	if tt.called != 1 {
+		t.Error("Expected transport to be called once.")
+		return
+	}
 }
 
 func TestUserNameAndPassword(t *testing.T) {
 	c := TestContext()
-	c.RegisterProvider("provider", &Provider{})
+	c.RegisterProvider("provider", &Provider{AuthEndpoint: "/"})
 
 	auths := []AuthOptions{
 		AuthOptions{},
diff --git a/context.go b/context.go
index 0a73890..a35242c 100644
--- a/context.go
+++ b/context.go
@@ -1,11 +1,24 @@
 package gophercloud
 
+import (
+	"net/http"
+)
+
 type Context struct {
+	// providerMap serves as a directory of supported providers.
 	providerMap map[string]*Provider
+
+	// httpClient refers to the current HTTP client interface to use.
+	httpClient *http.Client
 }
 
 func TestContext() *Context {
 	return &Context{
 		providerMap: make(map[string]*Provider),
+		httpClient: &http.Client{},
 	}
 }
+
+func (c *Context) UseCustomClient(hc *http.Client) {
+	c.httpClient = hc;
+}
diff --git a/errors.go b/errors.go
index 53397e1..079f0ae 100644
--- a/errors.go
+++ b/errors.go
@@ -7,3 +7,4 @@
 var ErrNotImplemented = fmt.Errorf("Not implemented")
 var ErrProvider = fmt.Errorf("Missing or incorrect provider")
 var ErrCredentials = fmt.Errorf("Missing or incomplete credentials")
+var ErrConfiguration = fmt.Errorf("Missing or incomplete configuration")
diff --git a/provider.go b/provider.go
index f2249c3..9d66fe1 100644
--- a/provider.go
+++ b/provider.go
@@ -4,12 +4,16 @@
 )
 
 type Provider struct {
-	// empty.
+	AuthEndpoint string
 }
 
 var providerMap = make(map[string]*Provider)
 
 func (c *Context) RegisterProvider(name string, p *Provider) error {
+	if p.AuthEndpoint == "" {
+		return ErrConfiguration
+	}
+
 	c.providerMap[name] = p
 	return nil
 }
diff --git a/provider_test.go b/provider_test.go
index df3d877..8c37dae 100644
--- a/provider_test.go
+++ b/provider_test.go
@@ -13,7 +13,13 @@
 		return
 	}
 
-	_ = c.RegisterProvider("aProvider", &Provider{})
+	err = c.RegisterProvider("aProvider", &Provider{})
+	if err != ErrConfiguration {
+		t.Error("Unexpected error/nil when registering a provider w/out an auth endpoint\n  %s", err)
+		return
+	}
+
+	_ = c.RegisterProvider("aProvider", &Provider{AuthEndpoint: "http://localhost/auth"})
 	_, err = c.ProviderByName("aProvider")
 	if err != nil {
 		t.Error(err)