From 5d41b605b99a85b22ca5318e5c9b9c48bf2d5706 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Mon, 14 Oct 2024 22:21:10 +0000 Subject: [PATCH] add better ldap response error handling --- app/app.go | 31 +++++++++++++++++-------------- app/ldap.go | 15 +++++++++++---- app/utils.go | 24 +++++++++++++++++++----- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/app/app.go b/app/app.go index b22f0ef..b9b0898 100644 --- a/app/app.go +++ b/app/app.go @@ -15,7 +15,7 @@ import ( ) var LDAPSessions map[string]*LDAPClient -var APIVersion = "1.0.3" +var APIVersion = "1.0.4" func Run() { gob.Register(LDAPClient{}) @@ -25,7 +25,10 @@ func Run() { configPath := flag.String("config", "config.json", "path to config.json file") flag.Parse() - config := GetConfig(*configPath) + config, err := GetConfig(*configPath) + if err != nil { + log.Fatal("Error when reading config file: ", err) + } log.Printf("Read in config from %s\n", *configPath) gin.SetMode(gin.ReleaseMode) @@ -109,7 +112,7 @@ func Run() { } status, res := LDAPSession.GetAllUsers() - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) router.POST("/users/:userid", func(c *gin.Context) { @@ -135,7 +138,7 @@ func Run() { return } status, res = LDAPSession.AddUser(c.Param("userid"), body) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) } else { // user already exists, attempt to modify user var body UserOptional // all user attributes optional for new users if err := c.ShouldBind(&body); err != nil { // attempt to bind user data @@ -143,7 +146,7 @@ func Run() { return } status, res = LDAPSession.ModUser(c.Param("userid"), body) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) } }) @@ -162,7 +165,7 @@ func Run() { } status, res := LDAPSession.GetUser(c.Param("userid")) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) router.DELETE("/users/:userid", func(c *gin.Context) { @@ -180,7 +183,7 @@ func Run() { } status, res := LDAPSession.DelUser(c.Param("userid")) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) router.GET("/groups", func(c *gin.Context) { @@ -198,7 +201,7 @@ func Run() { } status, res := LDAPSession.GetAllGroups() - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) router.GET("/groups/:groupid", func(c *gin.Context) { @@ -216,7 +219,7 @@ func Run() { } status, res := LDAPSession.GetGroup(c.Param("groupid")) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) router.POST("/groups/:groupid", func(c *gin.Context) { @@ -243,10 +246,10 @@ func Run() { status, res := LDAPSession.GetGroup(c.Param("groupid")) if status != 200 && ldap.IsErrorWithCode(res["error"].(error), ldap.LDAPResultNoSuchObject) { // group does not already exist, create new group status, res = LDAPSession.AddGroup(c.Param("groupid"), body) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) } else { // group already exists, attempt to modify group status, res = LDAPSession.ModGroup(c.Param("groupid"), body) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) } }) @@ -265,7 +268,7 @@ func Run() { } status, res := LDAPSession.DelGroup(c.Param("groupid")) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) router.POST("/groups/:groupid/members/:userid", func(c *gin.Context) { @@ -283,7 +286,7 @@ func Run() { } status, res := LDAPSession.AddUserToGroup(c.Param("userid"), c.Param("groupid")) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) router.DELETE("/groups/:groupid/members/:userid", func(c *gin.Context) { @@ -301,7 +304,7 @@ func Run() { } status, res := LDAPSession.DelUserFromGroup(c.Param("userid"), c.Param("groupid")) - c.JSON(status, res) + c.JSON(status, HandleResponse(res)) }) log.Printf("Starting LDAP API on port %s\n", strconv.Itoa(config.ListenPort)) diff --git a/app/ldap.go b/app/ldap.go index 8c9bec2..35a4604 100644 --- a/app/ldap.go +++ b/app/ldap.go @@ -1,6 +1,7 @@ package app import ( + "errors" "fmt" "net/http" @@ -96,8 +97,11 @@ func (l LDAPClient) GetUser(uid string) (int, gin.H) { func (l LDAPClient) AddUser(uid string, user UserRequired) (int, gin.H) { if user.CN == "" || user.SN == "" || user.UserPassword == "" || user.Mail == "" { return http.StatusBadRequest, gin.H{ - "ok": false, - "error": "Missing one of required fields: cn, sn, mail, userpassword", + "ok": false, + "error": ldap.NewError( + ldap.LDAPResultUnwillingToPerform, + errors.New("missing one of required fields: cn, sn, mail, userpassword"), + ), } } @@ -128,8 +132,11 @@ func (l LDAPClient) AddUser(uid string, user UserRequired) (int, gin.H) { func (l LDAPClient) ModUser(uid string, user UserOptional) (int, gin.H) { if user.CN == "" && user.SN == "" && user.UserPassword == "" && user.Mail == "" { return http.StatusBadRequest, gin.H{ - "ok": false, - "error": "Requires one of fields: cn, sn, mail, userpassword", + "ok": false, + "error": ldap.NewError( + ldap.LDAPResultUnwillingToPerform, + errors.New("requires one of fields: cn, sn, mail, userpassword"), + ), } } diff --git a/app/utils.go b/app/utils.go index c4e139a..341b407 100644 --- a/app/utils.go +++ b/app/utils.go @@ -2,7 +2,6 @@ package app import ( "encoding/json" - "log" "os" "github.com/gin-gonic/gin" @@ -23,17 +22,17 @@ type Config struct { } } -func GetConfig(configPath string) Config { +func GetConfig(configPath string) (Config, error) { content, err := os.ReadFile(configPath) if err != nil { - log.Fatal("Error when opening config file: ", err) + return Config{}, err } var config Config err = json.Unmarshal(content, &config) if err != nil { - log.Fatal("Error during parsing config file: ", err) + return Config{}, err } - return config + return config, nil } type Login struct { // login body struct @@ -126,3 +125,18 @@ type UserRequired struct { // add or modify user body struct type Group struct { // add or modify group body struct } + +func HandleResponse(response gin.H) gin.H { + if response["error"] != nil { + err := response["error"].(error) + LDAPerr := err.(*ldap.Error) + response["error"] = gin.H{ + "code": LDAPerr.ResultCode, + "result": ldap.LDAPResultCodeMap[LDAPerr.ResultCode], + "message": LDAPerr.Err.Error(), + } + return response + } else { + return response + } +}