|
1 | 1 | package controllers
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "crypto/hmac" |
| 5 | + "crypto/sha1" |
| 6 | + "encoding/hex" |
4 | 7 | "io/ioutil"
|
| 8 | + "os/exec" |
5 | 9 | "path/filepath"
|
6 | 10 | "strings"
|
7 | 11 |
|
| 12 | + "github.com/broqiang/mdblog/app/mylog" |
| 13 | + |
8 | 14 | "github.com/broqiang/mdblog/app/config"
|
9 | 15 | "github.com/broqiang/mdblog/app/mdfile"
|
10 | 16 | "github.com/gin-gonic/gin"
|
@@ -67,3 +73,69 @@ func mergeH(c *gin.Context, h gin.H) gin.H {
|
67 | 73 | func ToKeywords(works ...string) string {
|
68 | 74 | return strings.Join(works, ",")
|
69 | 75 | }
|
| 76 | + |
| 77 | +// Webhook github 钩子 |
| 78 | +func Webhook(c *gin.Context) { |
| 79 | + singn := c.GetHeader("X-Hub-Signature") |
| 80 | + body, err := ioutil.ReadAll(c.Request.Body) |
| 81 | + if err != nil { |
| 82 | + mylog.LogErr.Printf("github hook %v", err) |
| 83 | + return |
| 84 | + } |
| 85 | + |
| 86 | + if !checkSecret(singn, body) { |
| 87 | + mylog.Error("github hook check secret failure.") |
| 88 | + return |
| 89 | + } |
| 90 | + |
| 91 | + pullDocs() |
| 92 | + |
| 93 | + // 从新初始化博客列表的内容 |
| 94 | + mdfile.Model.Reload() |
| 95 | +} |
| 96 | + |
| 97 | +// 向 github 发起 pull 请求,更新文档 |
| 98 | +func pullDocs() { |
| 99 | + // 获取文档保存的路径 |
| 100 | + docPath := filepath.Join(config.Root, config.Cfg.MarkdownDir) |
| 101 | + // 执行 git pull |
| 102 | + cmd := exec.Command("git", "pull") |
| 103 | + // 切换到命令要执行的目录 |
| 104 | + cmd.Dir = docPath |
| 105 | + |
| 106 | + // 执行,并返回结果 |
| 107 | + res, err := cmd.Output() |
| 108 | + |
| 109 | + if err == nil { |
| 110 | + mylog.Infof("git pull success. \n%s", res) |
| 111 | + } else { |
| 112 | + mylog.Errorf("git pull failure, %v", err) |
| 113 | + } |
| 114 | + |
| 115 | +} |
| 116 | + |
| 117 | +// 检测 github 传过来的 key |
| 118 | +func checkSecret(singn string, body []byte) bool { |
| 119 | + if len(singn) != 45 || !strings.HasPrefix(singn, "sha1=") { |
| 120 | + return false |
| 121 | + } |
| 122 | + |
| 123 | + // github 中对应的加密串, 从配置文件去获取 |
| 124 | + secret := []byte(config.Cfg.Secret) |
| 125 | + |
| 126 | + // 通过加密串和 body 计算签名 |
| 127 | + mac := hmac.New(sha1.New, secret) |
| 128 | + mac.Write(body) |
| 129 | + mKey := mac.Sum(nil) |
| 130 | + |
| 131 | + // Hex 解码 |
| 132 | + singnature := make([]byte, 20) |
| 133 | + hex.Decode(singnature, []byte(singn[5:])) |
| 134 | + |
| 135 | + // 比较签名是否一直 |
| 136 | + if hmac.Equal(singnature, mKey) { |
| 137 | + return true |
| 138 | + } |
| 139 | + |
| 140 | + return false |
| 141 | +} |
0 commit comments