implement better ldap tls handling, fix naming for groupnames and usernames in path params
This commit is contained in:
@@ -19,8 +19,10 @@ type PVEConfig struct {
|
|||||||
|
|
||||||
type LDAPConfig struct {
|
type LDAPConfig struct {
|
||||||
BaseDN string `json:""`
|
BaseDN string `json:""`
|
||||||
LdapURL string
|
Hostname string
|
||||||
StartTLS bool
|
StartTLS bool
|
||||||
|
TLS bool
|
||||||
|
Verify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|||||||
+35
-15
@@ -19,30 +19,50 @@ type LDAPClient struct {
|
|||||||
|
|
||||||
// returns a new LDAPClient from the config
|
// returns a new LDAPClient from the config
|
||||||
func NewClientFromCredentials(config common.LDAPConfig, username common.Username, password string) (*LDAPClient, int, error) {
|
func NewClientFromCredentials(config common.LDAPConfig, username common.Username, password string) (*LDAPClient, int, error) {
|
||||||
LDAPConn, err := ldap.DialURL(config.LdapURL)
|
ldapclient := LDAPClient{}
|
||||||
if err != nil {
|
|
||||||
return nil, http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.StartTLS {
|
if config.TLS {
|
||||||
err = LDAPConn.StartTLS(&tls.Config{})
|
tlsConfig := &tls.Config{
|
||||||
|
InsecureSkipVerify: !config.Verify,
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("ldaps://%s", config.Hostname)
|
||||||
|
LDAPConn, err := ldap.DialURL(url, ldap.DialWithTLSConfig(tlsConfig))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, http.StatusInternalServerError, err
|
return nil, http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
ldapclient.config = &config
|
||||||
|
ldapclient.client = LDAPConn
|
||||||
|
} else if config.StartTLS {
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
InsecureSkipVerify: !config.Verify,
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("ldap://%s", config.Hostname)
|
||||||
|
LDAPConn, err := ldap.DialURL(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
err = LDAPConn.StartTLS(tlsConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
ldapclient.config = &config
|
||||||
|
ldapclient.client = LDAPConn
|
||||||
|
} else {
|
||||||
|
url := fmt.Sprintf("ldap://%s", config.Hostname)
|
||||||
|
LDAPConn, err := ldap.DialURL(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
ldapclient.config = &config
|
||||||
|
ldapclient.client = LDAPConn
|
||||||
}
|
}
|
||||||
|
|
||||||
ldap := LDAPClient{
|
userdn := fmt.Sprintf("uid=%s,ou=people,%s", username.UserID, ldapclient.config.BaseDN)
|
||||||
config: &config,
|
err := ldapclient.client.Bind(userdn, password)
|
||||||
client: LDAPConn,
|
|
||||||
}
|
|
||||||
|
|
||||||
userdn := fmt.Sprintf("uid=%s,ou=people,%s", username.UserID, ldap.config.BaseDN)
|
|
||||||
err = ldap.client.Bind(userdn, password)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, http.StatusUnauthorized, err
|
return nil, http.StatusUnauthorized, err
|
||||||
} else {
|
} else {
|
||||||
return &ldap, http.StatusOK, nil
|
return &ldapclient, http.StatusOK, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+48
-46
@@ -199,14 +199,14 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.GET("/groups/:groupid", func(c *gin.Context) {
|
router.GET("/groups/:groupname", func(c *gin.Context) {
|
||||||
groupid, ok := c.Params.Get("groupid")
|
groupname_str, ok := c.Params.Get("groupname")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupname, err := common.ParseGroupname(groupid)
|
groupname, err := common.ParseGroupname(groupname_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
}
|
}
|
||||||
@@ -225,14 +225,14 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/groups/:groupid", func(c *gin.Context) {
|
router.POST("/groups/:groupname", func(c *gin.Context) {
|
||||||
groupid, ok := c.Params.Get("groupid")
|
groupname_str, ok := c.Params.Get("groupname")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupname, err := paas.ParseGroupname(groupid)
|
groupname, err := paas.ParseGroupname(groupname_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -252,14 +252,14 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.DELETE("/groups/:groupid", func(c *gin.Context) {
|
router.DELETE("/groups/:groupname", func(c *gin.Context) {
|
||||||
groupid, ok := c.Params.Get("groupid")
|
groupname_str, ok := c.Params.Get("groupname")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupname, err := paas.ParseGroupname(groupid)
|
groupname, err := paas.ParseGroupname(groupname_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -279,20 +279,20 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/pools/:poolid/groups/:groupid", func(c *gin.Context) {
|
router.POST("/pools/:poolid/groups/:groupname", func(c *gin.Context) {
|
||||||
poolid, ok := c.Params.Get("poolid")
|
poolid, ok := c.Params.Get("poolid")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupid, ok := c.Params.Get("groupid")
|
groupname_str, ok := c.Params.Get("groupname")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupname, err := paas.ParseGroupname(groupid)
|
groupname, err := paas.ParseGroupname(groupname_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -312,20 +312,20 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.DELETE("/pools/:poolid/groups/:groupid", func(c *gin.Context) {
|
router.DELETE("/pools/:poolid/groups/:groupname", func(c *gin.Context) {
|
||||||
poolid, ok := c.Params.Get("poolid")
|
poolid, ok := c.Params.Get("poolid")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupid, ok := c.Params.Get("groupid")
|
groupname_str, ok := c.Params.Get("groupname")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupname, err := paas.ParseGroupname(groupid)
|
groupname, err := paas.ParseGroupname(groupname_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -345,14 +345,14 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.GET("/users/:userid", func(c *gin.Context) {
|
router.GET("/users/:username", func(c *gin.Context) {
|
||||||
userid, ok := c.Params.Get("userid")
|
username_str, ok := c.Params.Get("username")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter poolid")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
username, err := common.ParseUsername(userid)
|
username, err := common.ParseUsername(username_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
}
|
}
|
||||||
@@ -371,14 +371,14 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/users/:userid", func(c *gin.Context) {
|
router.POST("/users/:username", func(c *gin.Context) {
|
||||||
userid, ok := c.Params.Get("userid")
|
username_str, ok := c.Params.Get("username")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
username, err := paas.ParseUsername(userid)
|
username, err := paas.ParseUsername(username_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -411,14 +411,14 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.DELETE("/users/:userid", func(c *gin.Context) {
|
router.DELETE("/users/:username", func(c *gin.Context) {
|
||||||
userid, ok := c.Params.Get("userid")
|
username_str, ok := c.Params.Get("username")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
username, err := paas.ParseUsername(userid)
|
username, err := paas.ParseUsername(username_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -438,26 +438,26 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/groups/:groupid/users/:userid", func(c *gin.Context) {
|
router.POST("/groups/:groupname/users/:username", func(c *gin.Context) {
|
||||||
groupid, ok := c.Params.Get("groupid")
|
groupname_str, ok := c.Params.Get("groupname")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userid, ok := c.Params.Get("userid")
|
username_str, ok := c.Params.Get("username")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter userid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter username")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupname, err := paas.ParseGroupname(groupid)
|
groupname, err := paas.ParseGroupname(groupname_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
username, err := paas.ParseUsername(userid)
|
username, err := paas.ParseUsername(username_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -477,26 +477,26 @@ func Run(configPath *string, localDBPath *string) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.DELETE("/groups/:groupid/users/:userid", func(c *gin.Context) {
|
router.DELETE("/groups/:groupname/users/:username", func(c *gin.Context) {
|
||||||
groupid, ok := c.Params.Get("groupid")
|
groupname_str, ok := c.Params.Get("groupname")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter groupname")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userid, ok := c.Params.Get("userid")
|
username_str, ok := c.Params.Get("username")
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter userid")})
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Missing required path parameter username")})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
groupname, err := paas.ParseGroupname(groupid)
|
groupname, err := paas.ParseGroupname(groupname_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
username, err := paas.ParseUsername(userid)
|
username, err := paas.ParseUsername(username_str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
@@ -585,8 +585,10 @@ func GetRealmsFromPVE(config *common.Config) map[string]Realm {
|
|||||||
if realm.Type == "ldap" {
|
if realm.Type == "ldap" {
|
||||||
ldapconfig := common.LDAPConfig{
|
ldapconfig := common.LDAPConfig{
|
||||||
BaseDN: realm.BaseDN,
|
BaseDN: realm.BaseDN,
|
||||||
LdapURL: fmt.Sprintf("ldap://%s", realm.Server1),
|
Hostname: realm.Server1,
|
||||||
StartTLS: false, // todo fix startlts
|
TLS: realm.Mode == "ldaps",
|
||||||
|
StartTLS: realm.Mode == "ldap+starttls",
|
||||||
|
Verify: bool(realm.Verify),
|
||||||
}
|
}
|
||||||
realms[realm.Realm] = Realm{
|
realms[realm.Realm] = Realm{
|
||||||
Type: realm.Type,
|
Type: realm.Type,
|
||||||
|
|||||||
Reference in New Issue
Block a user