2017-02-20 16:45:32 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
2021-09-17 06:12:39 +00:00
|
|
|
"os"
|
2017-02-20 16:45:32 +00:00
|
|
|
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/credentials"
|
2018-09-03 06:44:44 +00:00
|
|
|
|
2020-07-01 12:20:57 +00:00
|
|
|
"github.com/dexidp/dex/api/v2"
|
2017-02-20 16:45:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func newDexClient(hostAndPort, caPath, clientCrt, clientKey string) (api.DexClient, error) {
|
|
|
|
cPool := x509.NewCertPool()
|
2021-09-17 06:12:39 +00:00
|
|
|
caCert, err := os.ReadFile(caPath)
|
2017-02-20 16:45:32 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("invalid CA crt file: %s", caPath)
|
|
|
|
}
|
|
|
|
if cPool.AppendCertsFromPEM(caCert) != true {
|
|
|
|
return nil, fmt.Errorf("failed to parse CA crt")
|
|
|
|
}
|
|
|
|
|
|
|
|
clientCert, err := tls.LoadX509KeyPair(clientCrt, clientKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("invalid client crt file: %s", caPath)
|
|
|
|
}
|
|
|
|
|
|
|
|
clientTLSConfig := &tls.Config{
|
|
|
|
RootCAs: cPool,
|
|
|
|
Certificates: []tls.Certificate{clientCert},
|
|
|
|
}
|
|
|
|
creds := credentials.NewTLS(clientTLSConfig)
|
|
|
|
|
|
|
|
conn, err := grpc.Dial(hostAndPort, grpc.WithTransportCredentials(creds))
|
|
|
|
if err != nil {
|
2019-02-22 19:54:19 +00:00
|
|
|
return nil, fmt.Errorf("dial: %v", err)
|
2017-02-20 16:45:32 +00:00
|
|
|
}
|
|
|
|
return api.NewDexClient(conn), nil
|
|
|
|
}
|
|
|
|
|
2017-03-23 22:50:20 +00:00
|
|
|
func createPassword(cli api.DexClient) error {
|
2017-02-20 16:45:32 +00:00
|
|
|
p := api.Password{
|
|
|
|
Email: "test@example.com",
|
|
|
|
// bcrypt hash of the value "test1" with cost 10
|
|
|
|
Hash: []byte("$2a$10$XVMN/Fid.Ks4CXgzo8fpR.iU1khOMsP5g9xQeXuBm1wXjRX8pjUtO"),
|
|
|
|
Username: "test",
|
|
|
|
UserId: "test",
|
|
|
|
}
|
|
|
|
|
|
|
|
createReq := &api.CreatePasswordReq{
|
|
|
|
Password: &p,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create password.
|
2017-03-23 22:50:20 +00:00
|
|
|
if resp, err := cli.CreatePassword(context.TODO(), createReq); err != nil || resp.AlreadyExists {
|
2017-02-20 16:45:32 +00:00
|
|
|
if resp.AlreadyExists {
|
2017-03-23 22:50:20 +00:00
|
|
|
return fmt.Errorf("Password %s already exists", createReq.Password.Email)
|
2017-02-20 16:45:32 +00:00
|
|
|
}
|
2017-03-23 22:50:20 +00:00
|
|
|
return fmt.Errorf("failed to create password: %v", err)
|
2017-02-20 16:45:32 +00:00
|
|
|
}
|
2017-03-23 22:50:20 +00:00
|
|
|
log.Printf("Created password with email %s", createReq.Password.Email)
|
2017-02-20 16:45:32 +00:00
|
|
|
|
|
|
|
// List all passwords.
|
2017-03-23 22:50:20 +00:00
|
|
|
resp, err := cli.ListPasswords(context.TODO(), &api.ListPasswordReq{})
|
2017-02-20 16:45:32 +00:00
|
|
|
if err != nil {
|
2017-03-23 22:50:20 +00:00
|
|
|
return fmt.Errorf("failed to list password: %v", err)
|
2017-02-20 16:45:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
log.Print("Listing Passwords:\n")
|
|
|
|
for _, pass := range resp.Passwords {
|
|
|
|
log.Printf("%+v", pass)
|
|
|
|
}
|
|
|
|
|
2018-08-06 19:04:56 +00:00
|
|
|
// Verifying correct and incorrect passwords
|
|
|
|
log.Print("Verifying Password:\n")
|
|
|
|
verifyReq := &api.VerifyPasswordReq{
|
|
|
|
Email: "test@example.com",
|
|
|
|
Password: "test1",
|
|
|
|
}
|
|
|
|
verifyResp, err := cli.VerifyPassword(context.TODO(), verifyReq)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to run VerifyPassword for correct password: %v", err)
|
|
|
|
}
|
|
|
|
if !verifyResp.Verified {
|
|
|
|
return fmt.Errorf("failed to verify correct password: %v", verifyResp)
|
|
|
|
}
|
|
|
|
log.Printf("properly verified correct password: %t\n", verifyResp.Verified)
|
|
|
|
|
|
|
|
badVerifyReq := &api.VerifyPasswordReq{
|
|
|
|
Email: "test@example.com",
|
|
|
|
Password: "wrong_password",
|
|
|
|
}
|
|
|
|
badVerifyResp, err := cli.VerifyPassword(context.TODO(), badVerifyReq)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to run VerifyPassword for incorrect password: %v", err)
|
|
|
|
}
|
|
|
|
if badVerifyResp.Verified {
|
|
|
|
return fmt.Errorf("verify returned true for incorrect password: %v", badVerifyResp)
|
|
|
|
}
|
|
|
|
log.Printf("properly failed to verify incorrect password: %t\n", badVerifyResp.Verified)
|
|
|
|
|
|
|
|
log.Print("Listing Passwords:\n")
|
|
|
|
for _, pass := range resp.Passwords {
|
|
|
|
log.Printf("%+v", pass)
|
|
|
|
}
|
|
|
|
|
2017-02-20 16:45:32 +00:00
|
|
|
deleteReq := &api.DeletePasswordReq{
|
|
|
|
Email: p.Email,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete password with email = test@example.com.
|
2017-03-23 22:50:20 +00:00
|
|
|
if resp, err := cli.DeletePassword(context.TODO(), deleteReq); err != nil || resp.NotFound {
|
2017-02-20 16:45:32 +00:00
|
|
|
if resp.NotFound {
|
2017-03-23 22:50:20 +00:00
|
|
|
return fmt.Errorf("Password %s not found", deleteReq.Email)
|
2017-02-20 16:45:32 +00:00
|
|
|
}
|
2017-03-23 22:50:20 +00:00
|
|
|
return fmt.Errorf("failed to delete password: %v", err)
|
|
|
|
}
|
|
|
|
log.Printf("Deleted password with email %s", deleteReq.Email)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
caCrt := flag.String("ca-crt", "", "CA certificate")
|
|
|
|
clientCrt := flag.String("client-crt", "", "Client certificate")
|
|
|
|
clientKey := flag.String("client-key", "", "Client key")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
if *clientCrt == "" || *caCrt == "" || *clientKey == "" {
|
|
|
|
log.Fatal("Please provide CA & client certificates and client key. Usage: ./client --ca-crt=<path ca.crt> --client-crt=<path client.crt> --client-key=<path client key>")
|
|
|
|
}
|
|
|
|
|
|
|
|
client, err := newDexClient("127.0.0.1:5557", *caCrt, *clientCrt, *clientKey)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed creating dex client: %v ", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := createPassword(client); err != nil {
|
|
|
|
log.Fatalf("testPassword failed: %v", err)
|
2017-02-20 16:45:32 +00:00
|
|
|
}
|
|
|
|
}
|