micro-account/pkg/infrsatructure/external/mail_account.go

255 lines
5.1 KiB
Go
Raw Normal View History

2025-02-20 08:18:23 +00:00
package external
import (
"crypto/tls"
"errors"
"fmt"
"github.com/PuerkitoBio/goquery"
"io"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"time"
)
const (
LoginSuccessUrl = "https://mail.fontree.cn/iredadmin/dashboard?checknew" //登录后的重定向地址
CreateUrl = "https://mail.fontree.cn/iredadmin/create/user/"
LoginUrl = "https://mail.fontree.cn/iredadmin/login"
)
type iredCookie struct {
Cookie string
Name string
ExpireAt *time.Time
}
type IRedMail struct {
IsProd bool `json:"isProd"`
Username string `json:"username"`
Password string `json:"password"`
Domain string
*iredCookie
}
type CreateAccountInfo struct {
Username string
Password string
Cn string
}
var ReadMail *IRedMail
func LoadEnv(userName, psw, domain string, isProd bool) {
ReadMail = &IRedMail{
IsProd: isProd,
Username: userName,
Password: psw,
Domain: domain,
}
}
//CreateMailAccount 创建电子邮箱账号
func (m *IRedMail) CreateMailAccount(new CreateAccountInfo) error {
if m.IsProd != true {
fmt.Println("过滤创建邮箱帐号")
return nil
}
//0 登陆
err := m.login()
if err != nil {
return err
}
//1 先去解析csrf_token
csrfToken, err := m.getCsrfTokenBeforeAdd()
if err != nil {
return err
}
fmt.Println(csrfToken, err)
//1 先去解析csrf_token
err = m.createAccount(csrfToken, new)
if err != nil {
return err
}
return nil
}
// login 登陆超管
func (m *IRedMail) login() error {
loginUrl := LoginUrl
values := url.Values{}
values.Set("username", m.Username)
values.Set("password", m.Password)
values.Set("form_login", "Login")
values.Set("lang", "en_US")
// 创建一个表单数据
cookieJar, _ := cookiejar.New(nil)
// 忽略HTTPS证书验证
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
// 创建一个自定义Transport的HTTP客户端
client := &http.Client{Transport: tr, Jar: cookieJar}
// 发起POST请求
res, err := client.PostForm(loginUrl, values)
if err != nil {
log.Fatal(err)
}
// 发送请求
defer res.Body.Close()
if res.Request.URL.String() != LoginSuccessUrl {
msg := res.Request.URL.Query().Get("msg")
return errors.New("超管登录失败提示:" + msg)
}
for _, cookie := range res.Cookies() {
temp := &iredCookie{
Cookie: cookie.Value,
Name: cookie.Name,
}
m.iredCookie = temp
}
return nil
}
// getCsrfTokenBeforeAdd 登陆前获取token
func (m *IRedMail) getCsrfTokenBeforeAdd() (string, error) {
var csrfToken string
var isExist bool
cookieJar, _ := cookiejar.New(nil)
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
// 创建一个HTTP客户端并设置cookie jar
client := &http.Client{
Jar: cookieJar,
Transport: tr,
}
// 创建登录请求
loginURL := CreateUrl + m.Domain
req, err := http.NewRequest("GET", loginURL, nil)
if err != nil {
fmt.Println("创建请求失败:", err)
return "", err
}
// 向请求中添加cookie
cookie := &http.Cookie{
Name: m.iredCookie.Name,
Value: m.iredCookie.Cookie,
}
req.AddCookie(cookie)
// 发送登录请求
res, err := client.Do(req)
if err != nil {
fmt.Println("请求错误", loginURL, err)
return "", err
}
defer res.Body.Close()
if err != nil {
return "", err
}
str, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(str)))
if err != nil {
return "", err
}
doc.Find("input[name='csrf_token']").Each(func(i int, s *goquery.Selection) {
csrfToken, isExist = s.Attr("value")
fmt.Println("查找1---", csrfToken, isExist) // 输出: testUser
})
if isExist == false {
return "", errors.New("没有查找到csrf_token")
}
return csrfToken, nil
}
// createAccount 创建用户mail
func (m *IRedMail) createAccount(csrfToken string, info CreateAccountInfo) error {
cookieJar, _ := cookiejar.New(nil)
values := url.Values{}
values.Set("csrf_token", csrfToken)
values.Set("domainName", m.Domain)
values.Set("username", info.Username)
values.Set("newpw", info.Password)
values.Set("confirmpw", info.Password)
values.Set("cn", info.Cn)
values.Set("preferredLanguage", "zh_CN")
values.Set("mailQuota", "1024")
values.Set("submit_add_user", "Add")
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
// 创建一个HTTP客户端并设置cookie jar
client := &http.Client{
Jar: cookieJar,
Transport: tr,
//CheckRedirect:
}
// 创建登录请求
loginURL := CreateUrl + m.Domain
req, err := http.NewRequest("POST", loginURL, strings.NewReader(values.Encode()))
if err != nil {
fmt.Println("创建请求失败:", err)
return err
}
req.Header.Set("content-type", "application/x-www-form-urlencoded")
// 向请求中添加cookie
cookie := &http.Cookie{
Name: m.Name,
Value: m.Cookie,
}
req.AddCookie(cookie)
// 发送登录请求
res, err := client.Do(req)
if err != nil {
fmt.Println("请求错误", loginURL, err)
return err
}
defer res.Body.Close()
msg := res.Request.URL.Query().Get("msg")
if msg != "CREATED" {
return errors.New("生成mail账号失败:" + msg)
}
return nil
}