Skip to content

Commit

Permalink
v2.6.2 (#177)
Browse files Browse the repository at this point in the history
1、修复邮件插入失败
2、插件支持设置页面
3、修复pop3邮箱拉取权限判断
4、修复非管理员账户的附件权限判断

Co-authored-by: jinnrry <i@jinnrry.com>
  • Loading branch information
Jinnrry and Jinnrry authored Jul 27, 2024
1 parent 729eb96 commit e6a56b1
Show file tree
Hide file tree
Showing 28 changed files with 432 additions and 224 deletions.
2 changes: 0 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ COPY --from=febuild /work/dist /work/server/http_server/dist
RUN apk update && apk add git
RUN cd /work/server && go build -ldflags "-s -w -X 'main.version=${VERSION}' -X 'main.goVersion=$(go version)' -X 'main.gitHash=$(git show -s --format=%H)' -X 'main.buildTime=$(TZ=UTC-8 date +%Y-%m-%d" "%H:%M:%S)'" -o pmail main.go
RUN cd /work/server/hooks/telegram_push && go build -ldflags "-s -w" -o output/telegram_push telegram_push.go
RUN cd /work/server/hooks/web_push && go build -ldflags "-s -w" -o output/web_push web_push.go
RUN cd /work/server/hooks/wechat_push && go build -ldflags "-s -w" -o output/wechat_push wechat_push.go
RUN cd /work/server/hooks/spam_block && go build -ldflags "-s -w" -o output/spam_block spam_block.go

Expand All @@ -32,7 +31,6 @@ RUN apk add --no-cache tzdata \

COPY --from=serverbuild /work/server/pmail .
COPY --from=serverbuild /work/server/hooks/telegram_push/output/* ./plugins/
COPY --from=serverbuild /work/server/hooks/web_push/output/* ./plugins/
COPY --from=serverbuild /work/server/hooks/wechat_push/output/* ./plugins/
COPY --from=serverbuild /work/server/hooks/spam_block/output/* ./plugins/

Expand Down
2 changes: 0 additions & 2 deletions DockerfileGithubAction
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ COPY server .
RUN apk update && apk add git
RUN go build -ldflags "-s -w -X 'main.version=${VERSION}' -X 'main.goVersion=$(go version)' -X 'main.gitHash=${GITHASH}' -X 'main.buildTime=$(TZ=UTC-8 date +%Y-%m-%d" "%H:%M:%S)'" -o pmail main.go
RUN cd /work/hooks/telegram_push && go build -ldflags "-s -w" -o output/telegram_push telegram_push.go
RUN cd /work/hooks/web_push && go build -ldflags "-s -w" -o output/web_push web_push.go
RUN cd /work/hooks/wechat_push && go build -ldflags "-s -w" -o output/wechat_push wechat_push.go
RUN cd /work/hooks/spam_block && go build -ldflags "-s -w" -o output/spam_block spam_block.go

Expand All @@ -26,7 +25,6 @@ RUN apk add --no-cache tzdata \

COPY --from=serverbuild /work/pmail .
COPY --from=serverbuild /work/hooks/telegram_push/output/* ./plugins/
COPY --from=serverbuild /work/hooks/web_push/output/* ./plugins/
COPY --from=serverbuild /work/hooks/wechat_push/output/* ./plugins/
COPY --from=serverbuild /work/hooks/spam_block/output/* ./plugins/

Expand Down
8 changes: 1 addition & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ telegram_push:
cd server/hooks/telegram_push && CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o output/telegram_push_mac_amd64 telegram_push.go
cd server/hooks/telegram_push && CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w" -o output/telegram_push_mac_arm64 telegram_push.go

web_push:
cd server/hooks/web_push && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o output/web_push_linux_amd64 web_push.go
cd server/hooks/web_push && CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o output/web_push_windows_amd64.exe web_push.go
cd server/hooks/web_push && CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o output/web_push_mac_amd64 web_push.go
cd server/hooks/web_push && CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w" -o output/web_push_mac_arm64 web_push.go

wechat_push:
cd server/hooks/wechat_push && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o output/wechat_push_linux_amd64 wechat_push.go
Expand All @@ -41,7 +36,7 @@ spam_block:



plugin: telegram_push wechat_push web_push
plugin: telegram_push wechat_push


package: clean
Expand All @@ -53,7 +48,6 @@ package: clean
cp -r server/config/ssl output/config/
cp -r server/config/config.json output/config/
mv server/hooks/telegram_push/output/* output/plugins
mv server/hooks/web_push/output/* output/plugins
mv server/hooks/wechat_push/output/* output/plugins
cp README.md output/

Expand Down
6 changes: 6 additions & 0 deletions fe/src/components/HomeHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
<el-tab-pane v-if="$userInfos.is_admin" :label="lang.user_management">
<UserManagement />
</el-tab-pane>

<el-tab-pane :label="lang.plugin_settings">
<PluginSettings />
</el-tab-pane>

</el-tabs>
</el-drawer>

Expand All @@ -41,6 +46,7 @@ import GroupSettings from './GroupSettings.vue';
import RuleSettings from './RuleSettings.vue';
import UserManagement from './UserManagement.vue';
import { getCurrentInstance } from 'vue'
import PluginSettings from './PluginSettings.vue';
const app = getCurrentInstance()
const $http = app.appContext.config.globalProperties.$http
const $isLogin = app.appContext.config.globalProperties.$isLogin
Expand Down
35 changes: 35 additions & 0 deletions fe/src/components/PluginSettings.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<template>
<div id="main">
<el-tabs>
<el-tab-pane v-for="(src, name) in pluginList" :label="name">
<iframe :src="src"></iframe>
</el-tab-pane>
</el-tabs>
</div>
</template>

<script setup>
import { reactive, ref, getCurrentInstance } from 'vue'
const app = getCurrentInstance()
const $http = app.appContext.config.globalProperties.$http
const pluginList = reactive({})
$http.get('/api/plugin/list').then(res => {
if (res.data != null && res.data.length > 0) {
for (let i = 0; i < res.data.length; i++) {
let name = res.data[i];
pluginList[name] = "/api/plugin/settings/"+ name +"/index.html";
}
}
})
</script>

<style scoped>
iframe{
width: 100%;
border: 0;
}
</style>
2 changes: 2 additions & 0 deletions fe/src/i18n/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var lang = {
"editUser": "Edit Account",
"user_name": "User Name",
"user_management": "user management",
"plugin_settings": "Plugin Settings",
"lang": "en",
"submit": "submit",
"compose": "compose",
Expand Down Expand Up @@ -117,6 +118,7 @@ var zhCN = {
"newUser": "新增用户",
"editUser": "编辑用户",
"user_management": "用户管理",
"plugin_settings": "插件设置",
"lang": "zhCn",
"submit": "提交",
"compose": "发件",
Expand Down
2 changes: 1 addition & 1 deletion server/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"SSLPublicKeyPath": "./config/ssl/public.crt",
"dbDSN": "./config/pmail_temp.db",
"dbType": "sqlite",
"httpsEnabled": 1,
"httpsEnabled": 2,
"spamFilterLevel": 0,
"httpPort": 80,
"httpsPort": 443,
Expand Down
46 changes: 46 additions & 0 deletions server/controllers/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package controllers

import (
"github.com/Jinnrry/pmail/dto/response"
"github.com/Jinnrry/pmail/hooks"
"github.com/Jinnrry/pmail/utils/context"
"io"
"net/http"
"strings"
)

func GetPluginList(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
ret := []string{}
for s, _ := range hooks.HookList {
ret = append(ret, s)
}
response.NewSuccessResponse(ret).FPrint(w)

}

func SettingsHtml(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
args := strings.Split(req.RequestURI, "/")
if len(args) < 4 {
response.NewErrorResponse(response.ParamsError, "404", "").FPrint(w)
return
}

pluginName := args[4]
if plugin, ok := hooks.HookList[pluginName]; ok {
dt, err := io.ReadAll(req.Body)
if err != nil {
response.NewErrorResponse(response.ParamsError, err.Error(), "").FPrint(w)
return
}
html := plugin.SettingsHtml(ctx,
strings.Join(args[4:], "/"),
string(dt),
)
w.Header().Set("Content-Type", "text/html; charset=utf-8")

w.Write([]byte(html))
return

}
response.NewErrorResponse(response.ParamsError, "404", "")
}
4 changes: 3 additions & 1 deletion server/dto/parsemail/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ type Email struct {
Date string
Status int // 0未发送,1已发送,2发送失败,3删除
MessageId int64
Size int
}

func NewEmailFromReader(to []string, r io.Reader) *Email {
func NewEmailFromReader(to []string, r io.Reader, size int) *Email {
ret := &Email{}
m, err := message.Read(r)
if err != nil {
log.Errorf("email解析错误! Error %+v", err)
}

ret.Size = size
ret.From = buildUser(m.Header.Get("From"))

if len(to) > 0 {
Expand Down
47 changes: 45 additions & 2 deletions server/hooks/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,47 @@ func (h *HookSender) ReceiveParseAfter(ctx *context.Context, email *parsemail.Em

}

// GetName 获取插件名称
func (h *HookSender) GetName(ctx *context.Context) string {

dto := framework.HookDTO{
Ctx: ctx,
}
body, _ := json.Marshal(dto)

ret, errL := h.httpc.Post("http://plugin/GetName", "application/json", strings.NewReader(string(body)))
if errL != nil {
log.WithContext(ctx).Errorf("[%s] Error! %v", h.name, errL)
return ""
}

body, _ = io.ReadAll(ret.Body)

return string(body)
}

// SettingsHtml 插件页面
func (h *HookSender) SettingsHtml(ctx *context.Context, url string, requestData string) string {

dto := framework.SettingsHtmlRequest{
Ctx: ctx,
URL: url,
RequestData: requestData,
}
body, _ := json.Marshal(dto)

ret, errL := h.httpc.Post("http://plugin/SettingsHtml", "application/json", strings.NewReader(string(body)))
if errL != nil {
log.WithContext(ctx).Errorf("[%s] Error! %v", h.name, errL)
return ""
}

body, _ = io.ReadAll(ret.Body)

return string(body)

}

func NewHookSender(socketPath string, name string, serverVersion string) *HookSender {
httpc := http.Client{
Timeout: time.Second * 10,
Expand Down Expand Up @@ -214,8 +255,10 @@ func Init(serverVersion string) {
}
}
if loadSucc {
HookList[info.Name()] = NewHookSender(socketPath, info.Name(), serverVersion)
log.Infof("[%s] Plugin Load Success!", info.Name())
hk := NewHookSender(socketPath, info.Name(), serverVersion)
hkName := hk.GetName(&context.Context{})
HookList[hkName] = hk
log.Infof("[%s] Plugin Load Success!", hkName)
}

}
Expand Down
37 changes: 37 additions & 0 deletions server/hooks/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"time"
)

Expand All @@ -27,6 +28,10 @@ type EmailHook interface {
ReceiveParseAfter(ctx *context.Context, email *parsemail.Email)
// ReceiveSaveAfter 邮件落库以后执行(收信规则后执行) 异步执行
ReceiveSaveAfter(ctx *context.Context, email *parsemail.Email, ue []*models.UserEmail)
// GetName 获取插件名称
GetName(ctx *context.Context) string
// SettingsHtml 插件页面
SettingsHtml(ctx *context.Context, url string, requestData string) string
}

// HookDTO PMail 主程序和插件通信的结构体
Expand All @@ -39,6 +44,12 @@ type HookDTO struct {
UserEmail []*models.UserEmail
}

type SettingsHtmlRequest struct {
Ctx *context.Context // 上下文
URL string
RequestData string
}

type Plugin struct {
name string
hook EmailHook
Expand Down Expand Up @@ -160,6 +171,32 @@ func (p *Plugin) Run() {
writer.Write(body)
log.Debugf("[%s] ReceiveSaveAfter End", p.name)
})
mux.HandleFunc("/GetName", func(writer http.ResponseWriter, request *http.Request) {
log.Debugf("[%s] GetName Start", p.name)
var hookDTO HookDTO
body, _ := io.ReadAll(request.Body)
err := json.Unmarshal(body, &hookDTO)
if err != nil {
log.Errorf("params error %+v", err)
return
}
name := strings.ReplaceAll(p.hook.GetName(hookDTO.Ctx), " ", "")
writer.Write([]byte(name))
log.Debugf("[%s] GetName End", p.name)
})
mux.HandleFunc("/SettingsHtml", func(writer http.ResponseWriter, request *http.Request) {
log.Debugf("[%s] SettingsHtml Start", p.name)
var hookDTO SettingsHtmlRequest
body, _ := io.ReadAll(request.Body)
err := json.Unmarshal(body, &hookDTO)
if err != nil {
log.Errorf("params error %+v", err)
return
}
html := p.hook.SettingsHtml(hookDTO.Ctx, hookDTO.URL, hookDTO.RequestData)
writer.Write([]byte(html))
log.Debugf("[%s] SettingsHtml End", p.name)
})

server := http.Server{
ReadTimeout: 5 * time.Second,
Expand Down
11 changes: 3 additions & 8 deletions server/hooks/spam_block/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,11 @@ curl -X POST http://localhost:8501/v1/models/emotion_model:predict -d '{

4、将spam_block插件移动到pmail插件目录

5、在插件位置新建配置文件`spam_block_config.json`内容类似
5、设置插件

```json
{
"apiURL": "http://localhost:8501/v1/models/emotion_model:predict",
"apiTimeout": 3000
}
```
PMail后台->右上角设置按钮->插件设置->SpamBlock

apiURL表示模型api访问地址,如果你是使用Docker部署,PMail和tensorflow/serving容器需要设置为相同网络才能通信,并且需要把localhost替换为tensorflow/serving的容器名称
接口地址表示模型api访问地址,如果你是使用Docker部署,PMail和tensorflow/serving容器需要设置为相同网络才能通信,并且需要把localhost替换为tensorflow/serving的容器名称

# 模型效果

Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion server/hooks/spam_block/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
datasets==2.20.0
numpy==1.20.3
retvec==1.0.1
tensorflow==2.8.4
tensorflow==2.12.1
beautifulsoup4
lxml
Loading

0 comments on commit e6a56b1

Please sign in to comment.