1package credsutil
2
3import (
4	"fmt"
5	"time"
6
7	"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
8)
9
10const (
11	NoneLength int = -1
12)
13
14// SQLCredentialsProducer implements CredentialsProducer and provides a generic credentials producer for most sql database types.
15type SQLCredentialsProducer struct {
16	DisplayNameLen int
17	RoleNameLen    int
18	UsernameLen    int
19	Separator      string
20}
21
22func (scp *SQLCredentialsProducer) GenerateUsername(config dbplugin.UsernameConfig) (string, error) {
23	username := "v"
24
25	displayName := config.DisplayName
26	if scp.DisplayNameLen > 0 && len(displayName) > scp.DisplayNameLen {
27		displayName = displayName[:scp.DisplayNameLen]
28	} else if scp.DisplayNameLen == NoneLength {
29		displayName = ""
30	}
31
32	if len(displayName) > 0 {
33		username = fmt.Sprintf("%s%s%s", username, scp.Separator, displayName)
34	}
35
36	roleName := config.RoleName
37	if scp.RoleNameLen > 0 && len(roleName) > scp.RoleNameLen {
38		roleName = roleName[:scp.RoleNameLen]
39	} else if scp.RoleNameLen == NoneLength {
40		roleName = ""
41	}
42
43	if len(roleName) > 0 {
44		username = fmt.Sprintf("%s%s%s", username, scp.Separator, roleName)
45	}
46
47	userUUID, err := RandomAlphaNumeric(20, false)
48	if err != nil {
49		return "", err
50	}
51
52	username = fmt.Sprintf("%s%s%s", username, scp.Separator, userUUID)
53	username = fmt.Sprintf("%s%s%s", username, scp.Separator, fmt.Sprint(time.Now().Unix()))
54	if scp.UsernameLen > 0 && len(username) > scp.UsernameLen {
55		username = username[:scp.UsernameLen]
56	}
57
58	return username, nil
59}
60
61func (scp *SQLCredentialsProducer) GeneratePassword() (string, error) {
62	password, err := RandomAlphaNumeric(20, true)
63	if err != nil {
64		return "", err
65	}
66
67	return password, nil
68}
69
70func (scp *SQLCredentialsProducer) GenerateExpiration(ttl time.Time) (string, error) {
71	return ttl.Format("2006-01-02 15:04:05-0700"), nil
72}
73