无法使Golang库返回除了nil以外的任何内容给控制器。

huangapple go评论87阅读模式
英文:

Can't get Golang library to return anything but nil to controller

问题

Golang初学者在这里,所以我想我可能漏掉了一些明显的东西。尽管经过几天的尝试,我决定寻求一些帮助。:-)

我发布的代码是有效的,除了当用户请求创建一个已存在的同名客户端证书/密钥包时(这是一个OpenVPN服务器管理的WebUI),它不起作用。即使在这种情况下,也不会创建新的客户端包,但会显示一个错误的警告消息,指示已经创建了。

我知道我需要重新设计控制器以根据名称是否存在来显示不同的警告横幅。然而,我在从库中获取除了"nil"之外的任何内容方面都遇到了困难。

Golang控制器代码如下:

func (c *CertificatesController) Post() {
    c.TplName = "certificates.html"
    flash := beego.NewFlash()

    cParams := NewCertParams{}
    if err := c.ParseForm(&cParams); err != nil {
        beego.Error(err)
        flash.Error(err.Error())
        flash.Store(&c.Controller)
    } else {
        if vMap := validateCertParams(cParams); vMap != nil {
            c.Data["validation"] = vMap
        } else {
            if err := lib.CreateCertificate(cParams.Name, cParams.Passphrase); err != nil {
                beego.Error(err)
                flash.Error(err.Error())
                flash.Store(&c.Controller)
            } else {
                fmt.Println(err)
                flash.Success("Certificate for the name \"" + cParams.Name + "\" created")
                flash.Store(&c.Controller)
            }
        }
    }
    c.showCerts()
}

被lib.CreateCertificate调用的库函数如下:

func CreateCertificate(name string, passphrase string) error {
    rsaPath := models.GlobalCfg.OVConfigPath + "easy-rsa"
    rsaIndex := models.GlobalCfg.OVConfigPath + "easy-rsa/pki/index.txt"
    pass := false
    if passphrase != "" {
        pass = true
    }
    certs, err := ReadCerts(rsaIndex)
    if err != nil {
        beego.Error(err)
    }
    Dump(certs)
    exists := false
    for _, v := range certs {
        if v.Details.Name == name {
            exists = true
        }
    }
    if !exists && !pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --batch build-client-full %s nopass",
                rsaPath, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    if !exists && pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --passout=pass:%s build-client-full %s",
                rsaPath, passphrase, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    if exists {
        return err
    }
    return err
}

我已经改变了库中的每个返回值为err,并在控制器的第二个"else"语句中插入了fmt.Println(err),但是我始终只得到nil作为返回值。

英文:

Golang toddler here, so I'd imagine I'm missing something obvious. After experimenting for a couple of days though, I decided to reach out for some help. 无法使Golang库返回除了nil以外的任何内容给控制器。

The code I'm posting is working, except for the situation when a user requests a new client certificate/key package be created (this is an OpenVPN server administrative WebUI), when a client of the same name already exists. And even in that case, no new client package is created, but an incorrect alert message is displayed indicating that it has been.

I know I need to rework the controller to display different alert banners, based on whether the name exists or not. However, I'm stuck on getting anything besides "nil" back from the library.

The Golang controller code is as follows:

    func (c *CertificatesController) Post() {
c.TplName = "certificates.html"
flash := beego.NewFlash()
cParams := NewCertParams{}
if err := c.ParseForm(&cParams); err != nil {
beego.Error(err)
flash.Error(err.Error())
flash.Store(&c.Controller)
} else {
if vMap := validateCertParams(cParams); vMap != nil {
c.Data["validation"] = vMap
} else {
if err := lib.CreateCertificate(cParams.Name, cParams.Passphrase); err != nil {
beego.Error(err)
flash.Error(err.Error())
flash.Store(&c.Controller)
} else {
fmt.Println(err)
flash.Success("Certificate for the name \"" + cParams.Name + "\" created")
flash.Store(&c.Controller)
}
}
}
c.showCerts()
}

And the library function that's called via lib.CreateCertificate:

    func CreateCertificate(name string, passphrase string) error {
rsaPath := models.GlobalCfg.OVConfigPath + "easy-rsa"
rsaIndex := models.GlobalCfg.OVConfigPath + "easy-rsa/pki/index.txt"
pass := false
if passphrase != "" {
pass = true
}
certs, err := ReadCerts(rsaIndex)
if err != nil {
//		beego.Debug(string(output))
beego.Error(err)
//		return err
}
Dump(certs)
exists := false
for _, v := range certs {
if v.Details.Name == name {
exists = true
}
}
if !exists && !pass {
cmd := exec.Command("/bin/bash", "-c",
fmt.Sprintf(
"%s/easyrsa --batch build-client-full %s nopass",
rsaPath, name))
cmd.Dir = models.GlobalCfg.OVConfigPath
output, err := cmd.CombinedOutput()
if err != nil {
beego.Debug(string(output))
beego.Error(err)
return err
}
return nil
}
if !exists && pass {
cmd := exec.Command("/bin/bash", "-c",
fmt.Sprintf(
"%s/easyrsa --passout=pass:%s build-client-full %s",
rsaPath, passphrase, name))
cmd.Dir = models.GlobalCfg.OVConfigPath
output, err := cmd.CombinedOutput()
if err != nil {
beego.Debug(string(output))
beego.Error(err)
return err
}
return nil
}
if exists {
return err
}
return err
}

I've gone so far as changing every return in the library to err, and inserting a fmt.Println(err) in the controller's second "else" statement, but nil is all I ever get back.

答案1

得分: 0

所以,我成功找到了解决方法。再进行了一些搜索后,我找到了一个帖子,至少与我试图实现的目标相邻。最后,我只需要在我的证书库中添加/更改3行代码。我需要导入"errors"库,以newError := errors.New("Error! There is already a valid or invalid certificate for that name")的形式添加自定义错误,并且只需将最后的返回语句改为return newError。我确实学到了关于Go如何处理错误的一些知识!

以下是更新后的证书库代码:

func CreateCertificate(name string, passphrase string) error {
    rsaPath := models.GlobalCfg.OVConfigPath + "easy-rsa"
    rsaIndex := models.GlobalCfg.OVConfigPath + "easy-rsa/pki/index.txt"
    pass := false
    newError := errors.New("Error! There is already a valid or invalid certificate for that name")
    if passphrase != "" {
        pass = true
    }
    certs, err := ReadCerts(rsaIndex)
    if err != nil {
        // beego.Debug(string(output))
        beego.Error(err)
        // return err
    }
    Dump(certs)
    exists := false
    for _, v := range certs {
        if v.Details.Name == name {
            exists = true
        }
    }
    if !exists && !pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --batch build-client-full %s nopass",
                rsaPath, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    if !exists && pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --passout=pass:%s build-client-full %s",
                rsaPath, passphrase, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    return newError
}

现在,如果我尝试添加一个已经存在的OpenVPN客户端名称:

无法使Golang库返回除了nil以外的任何内容给控制器。

英文:

So, I was able to figure out how to deal with this. A bit more googling and I found a post that was at least adjacent to what I was trying to accomplish. In the end, I only needed to add/change 3 lines in my certificates library. I needed to import the "errors" library, add a custom error in the form newError := errors.New("Error! There is already a valid or invalid certificate for that name") and change only the last return to return newError. I definitely learned a thing-or-two about how Go handles errors!

Here's the updated code for the certificates library:

    func CreateCertificate(name string, passphrase string) error {
rsaPath := models.GlobalCfg.OVConfigPath + "easy-rsa"
rsaIndex := models.GlobalCfg.OVConfigPath + "easy-rsa/pki/index.txt"
pass := false
newError := errors.New("Error! There is already a valid or invalid certificate for that name")
if passphrase != "" {
pass = true
}
certs, err := ReadCerts(rsaIndex)
if err != nil {
//		beego.Debug(string(output))
beego.Error(err)
//		return err
}
Dump(certs)
exists := false
for _, v := range certs {
if v.Details.Name == name {
exists = true
}
}
if !exists && !pass {
cmd := exec.Command("/bin/bash", "-c",
fmt.Sprintf(
"%s/easyrsa --batch build-client-full %s nopass",
rsaPath, name))
cmd.Dir = models.GlobalCfg.OVConfigPath
output, err := cmd.CombinedOutput()
if err != nil {
beego.Debug(string(output))
beego.Error(err)
return err
}
return nil
}
if !exists && pass {
cmd := exec.Command("/bin/bash", "-c",
fmt.Sprintf(
"%s/easyrsa --passout=pass:%s build-client-full %s",
rsaPath, passphrase, name))
cmd.Dir = models.GlobalCfg.OVConfigPath
output, err := cmd.CombinedOutput()
if err != nil {
beego.Debug(string(output))
beego.Error(err)
return err
}
return nil
}
return newError
}

Now, if I try to add an OpenVPN client with a name that already exists:

无法使Golang库返回除了nil以外的任何内容给控制器。

huangapple
  • 本文由 发表于 2022年12月14日 09:50:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/74792791.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定