credential/userpass: login
This commit is contained in:
parent
fedda20c41
commit
0aec679bb4
|
@ -49,6 +49,7 @@ func testAccMap(t *testing.T) logicaltest.TestStep {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
func testAccLogin(t *testing.T) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.WriteOperation,
|
||||
|
|
|
@ -20,11 +20,12 @@ func Backend() *framework.Backend {
|
|||
},
|
||||
|
||||
Unauthenticated: []string{
|
||||
"login",
|
||||
"login/*",
|
||||
},
|
||||
},
|
||||
|
||||
Paths: append([]*framework.Path{
|
||||
pathLogin(&b),
|
||||
pathUsers(&b),
|
||||
}),
|
||||
}
|
||||
|
|
|
@ -9,6 +9,18 @@ import (
|
|||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
func TestBackend_basic(t *testing.T) {
|
||||
b := Backend()
|
||||
|
||||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
Backend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepUser(t, "web", "password", "foo"),
|
||||
testAccStepLogin(t, "web", "password"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_userCrud(t *testing.T) {
|
||||
b := Backend()
|
||||
|
||||
|
@ -23,6 +35,19 @@ func TestBackend_userCrud(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func testAccStepLogin(t *testing.T, user string, pass string) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.WriteOperation,
|
||||
Path: "login/" + user,
|
||||
Data: map[string]interface{}{
|
||||
"password": pass,
|
||||
},
|
||||
Unauthenticated: true,
|
||||
|
||||
Check: logicaltest.TestCheckAuth([]string{"foo"}),
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepUser(
|
||||
t *testing.T, name string, password string, policies string) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package userpass
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
)
|
||||
|
||||
func pathLogin(b *backend) *framework.Path {
|
||||
return &framework.Path{
|
||||
Pattern: `login/(?P<name>\w+)`,
|
||||
Fields: map[string]*framework.FieldSchema{
|
||||
"name": &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
Description: "Username of the user.",
|
||||
},
|
||||
|
||||
"password": &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
Description: "Password for this user.",
|
||||
},
|
||||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
logical.WriteOperation: b.pathLogin,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (b *backend) pathLogin(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
username := strings.ToLower(d.Get("name").(string))
|
||||
|
||||
// Get the user and validate auth
|
||||
user, err := b.User(req.Storage, username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user == nil || user.Password != d.Get("password").(string) {
|
||||
return logical.ErrorResponse("unknown username or password"), nil
|
||||
}
|
||||
|
||||
return &logical.Response{
|
||||
Auth: &logical.Auth{
|
||||
Policies: user.Policies,
|
||||
Metadata: map[string]string{
|
||||
"username": username,
|
||||
},
|
||||
DisplayName: username,
|
||||
},
|
||||
}, nil
|
||||
}
|
|
@ -39,7 +39,7 @@ func pathUsers(b *backend) *framework.Path {
|
|||
}
|
||||
|
||||
func (b *backend) User(s logical.Storage, n string) (*UserEntry, error) {
|
||||
entry, err := s.Get("user/" + n)
|
||||
entry, err := s.Get("user/" + strings.ToLower(n))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ func (b *backend) User(s logical.Storage, n string) (*UserEntry, error) {
|
|||
|
||||
func (b *backend) pathUserDelete(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
err := req.Storage.Delete("user/" + d.Get("name").(string))
|
||||
err := req.Storage.Delete("user/" + strings.ToLower(d.Get("name").(string)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ func (b *backend) pathUserDelete(
|
|||
|
||||
func (b *backend) pathUserRead(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
user, err := b.User(req.Storage, d.Get("name").(string))
|
||||
user, err := b.User(req.Storage, strings.ToLower(d.Get("name").(string)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ func (b *backend) pathUserRead(
|
|||
|
||||
func (b *backend) pathUserWrite(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
name := d.Get("name").(string)
|
||||
name := strings.ToLower(d.Get("name").(string))
|
||||
policies := strings.Split(d.Get("policies").(string), ",")
|
||||
for i, p := range policies {
|
||||
policies[i] = strings.TrimSpace(p)
|
||||
|
@ -117,4 +117,9 @@ Manage users allowed to authenticate.
|
|||
const pathUserHelpDesc = `
|
||||
This endpoint allows you to create, read, update, and delete users
|
||||
that are allowed to authenticate.
|
||||
|
||||
Deleting a user will not revoke auth for prior authenticated users
|
||||
with that name. To do this, do a revoke on "login/<username>" for
|
||||
the username you want revoked. If you don't need to revoke login immediately,
|
||||
then the next renew will cause the lease to expire.
|
||||
`
|
||||
|
|
Loading…
Reference in New Issue