332 lines
6.7 KiB
Go
332 lines
6.7 KiB
Go
|
package mail
|
|||
|
|
|||
|
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 = "http://106.12.56.142/admin/box/new?new=true"
|
|||
|
LoginUrl = "http://106.12.56.142/admin/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 登陆
|
|||
|
cookies, 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(cookies, new)
|
|||
|
if err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
// login 登陆超管
|
|||
|
func (m *IRedMail) login() ([]*http.Cookie, error) {
|
|||
|
|
|||
|
cookies, csrfToken, err := m.getCsrfTokenAndCookieBeforeLogin()
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
fmt.Println(cookies, csrfToken)
|
|||
|
|
|||
|
loginUrl := LoginUrl
|
|||
|
values := url.Values{}
|
|||
|
values.Set("email", m.Username)
|
|||
|
values.Set("password", m.Password)
|
|||
|
values.Set("_csrf_token", csrfToken)
|
|||
|
// 忽略HTTPS证书验证
|
|||
|
tr := &http.Transport{
|
|||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|||
|
}
|
|||
|
|
|||
|
tempCookieJar, _ := cookiejar.New(nil)
|
|||
|
u, err := url.Parse("http://106.12.56.142")
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
tempCookieJar.SetCookies(u, cookies)
|
|||
|
|
|||
|
// 创建一个自定义Transport的HTTP客户端
|
|||
|
//client := &http.Client{Transport: tr, Jar:cookies }
|
|||
|
client := &http.Client{Transport: tr, Jar: tempCookieJar}
|
|||
|
|
|||
|
// 发起POST请求
|
|||
|
res, err := client.PostForm(loginUrl, values)
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
// 发送请求
|
|||
|
defer res.Body.Close()
|
|||
|
//fmt.Println(res.)
|
|||
|
str, err := io.ReadAll(res.Body)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
fmt.Println("成功")
|
|||
|
fmt.Println(string(str))
|
|||
|
|
|||
|
/*
|
|||
|
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 res.Cookies(), nil
|
|||
|
}
|
|||
|
|
|||
|
// getCsrfTokenAndCookieBeforeLogin 登陆前获取token
|
|||
|
func (m *IRedMail) getCsrfTokenAndCookieBeforeLogin() ([]*http.Cookie, 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 := LoginUrl
|
|||
|
req, err := http.NewRequest("GET", loginURL, nil)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("创建请求失败:", err)
|
|||
|
return nil, "", err
|
|||
|
}
|
|||
|
|
|||
|
// 发送登录请求
|
|||
|
res, err := client.Do(req)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
fmt.Println("请求错误", loginURL, err)
|
|||
|
return nil, "", err
|
|||
|
}
|
|||
|
|
|||
|
defer res.Body.Close()
|
|||
|
if err != nil {
|
|||
|
return nil, "", err
|
|||
|
}
|
|||
|
str, err := io.ReadAll(res.Body)
|
|||
|
if err != nil {
|
|||
|
return nil, "", err
|
|||
|
}
|
|||
|
|
|||
|
// 解析HTML
|
|||
|
doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(str)))
|
|||
|
if err != nil {
|
|||
|
return nil, "", 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 nil, "", errors.New("没有查找到csrf_token")
|
|||
|
}
|
|||
|
|
|||
|
return res.Cookies(), csrfToken, 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(cookies []*http.Cookie, info CreateAccountInfo) error {
|
|||
|
cookieJar, _ := cookiejar.New(nil)
|
|||
|
|
|||
|
values := url.Values{}
|
|||
|
values.Set("name", info.Cn)
|
|||
|
values.Set("user", info.Username)
|
|||
|
values.Set("domain", m.Domain)
|
|||
|
values.Set("passwordPlaintext", info.Password)
|
|||
|
|
|||
|
tr := &http.Transport{
|
|||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|||
|
}
|
|||
|
u, err := url.Parse("http://106.12.56.142")
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
cookieJar.SetCookies(u, cookies)
|
|||
|
|
|||
|
// 创建一个HTTP客户端,并设置cookie jar
|
|||
|
client := &http.Client{
|
|||
|
Jar: cookieJar,
|
|||
|
Transport: tr,
|
|||
|
//CheckRedirect:
|
|||
|
}
|
|||
|
|
|||
|
// 创建登录请求
|
|||
|
loginURL := CreateUrl
|
|||
|
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")
|
|||
|
|
|||
|
// 发送登录请求
|
|||
|
res, err := client.Do(req)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
fmt.Println("请求错误", loginURL, err)
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
defer res.Body.Close()
|
|||
|
|
|||
|
fmt.Println("状态码", res.StatusCode)
|
|||
|
fmt.Println("状态码", res.Status)
|
|||
|
|
|||
|
return nil
|
|||
|
}
|