Refactor
This commit is contained in:
parent
90248dc946
commit
3dacd6c5cc
@ -8,7 +8,6 @@ import (
|
||||
tb "gopkg.in/tucnak/telebot.v2"
|
||||
"main/core"
|
||||
"main/logger"
|
||||
"main/outlook"
|
||||
"main/util"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -27,43 +26,36 @@ func BindUser(m *tb.Message, cid, cse string) error {
|
||||
}
|
||||
logger.Println("Alias: " + tmp[1])
|
||||
Alias := tmp[1]
|
||||
client := core.NewClient(cid, cse)
|
||||
code := util.GetURLValue(tmp[0], "code")
|
||||
//fmt.Println(code)
|
||||
access, refresh, err := MSFirGetToken(code, cid, cse)
|
||||
err := client.GetTokenWithCode(code)
|
||||
if err != nil {
|
||||
logger.Println("%d Bind error:GetRefreshToken %s \n", m.Chat.ID, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
//token has gotten
|
||||
bot.Send(m.Chat, "Token获取成功!")
|
||||
info, err := outlook.GetUserInfo(access)
|
||||
info, err := client.GetUserInfo()
|
||||
//fmt.Println("TgId:%d Refresh Token: %s\n", m.Chat.ID, refresh)
|
||||
if err != nil {
|
||||
logger.Println("%d Bind error:Getinfo %s \n", m.Chat.ID, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
var u core.Client
|
||||
u.TgId = m.Chat.ID
|
||||
u.RefreshToken = refresh
|
||||
u.RefreshToken = client.RefreshToken
|
||||
//TG的Data传递最高64bytes,一些MsId超过了报错BUTTON_DATA_INVALID (0),采取md5
|
||||
u.MsId = util.Get16MD5Encode(gjson.Get(info, "id").String())
|
||||
u.Uptime = time.Now().Unix()
|
||||
logger.Println(u.Uptime)
|
||||
u.Alias = Alias
|
||||
u.ClientId = cid
|
||||
u.ClientSecret = cse
|
||||
u.Other = ""
|
||||
//MS User Is Exist
|
||||
if MSAppIsExist(u.TgId, u.ClientId) {
|
||||
logger.Println("%d Bind error:MSUserHasExisted\n", m.Chat.ID)
|
||||
return errors.New("该应用已经绑定过了,无需重复绑定")
|
||||
}
|
||||
//MS information has gotten
|
||||
bot.Send(m.Chat, "MS_ID(MD5): "+u.MsId+"\nuserPrincipalName: "+gjson.Get(info, "userPrincipalName").String()+"\ndisplayName: "+gjson.Get(info, "displayName").String()+"\n")
|
||||
if ok, err := core.AddData(u); !ok {
|
||||
logger.Println("%d Bind error: %s\n", m.Chat.ID, err)
|
||||
return err
|
||||
}
|
||||
logger.Println("%d Bind Successfully!\n", m.Chat.ID)
|
||||
@ -118,16 +110,8 @@ func SignTask() {
|
||||
tmpBtn := &tb.ReplyMarkup{InlineKeyboard: inlineKeys}
|
||||
|
||||
se := u.MsId + " ( @" + chat.Username + " )"
|
||||
access, newRefreshToken, err := outlook.GetToken(u.RefreshToken, u.ClientId, u.ClientSecret)
|
||||
|
||||
if err != nil {
|
||||
logger.Println(u.MsId+" ", err)
|
||||
bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn)
|
||||
SignErr = append(SignErr, se)
|
||||
ErrorTimes[u.MsId]++
|
||||
continue
|
||||
}
|
||||
if ok, err := outlook.GetOutLookMails(access); !ok {
|
||||
client := core.NewClient(u.ClientId, u.ClientSecret)
|
||||
if err := client.GetOutlookMails(); err != nil {
|
||||
logger.Println(u.MsId+" ", err)
|
||||
bot.Send(chat, pre+gjson.Get(err.Error(), "error").String(), tmpBtn)
|
||||
ErrorTimes[u.MsId]++
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"io/ioutil"
|
||||
"main/core"
|
||||
"main/logger"
|
||||
"main/outlook"
|
||||
"main/util"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -25,10 +24,8 @@ const (
|
||||
/my 查看已绑定账户信息
|
||||
/bind 绑定新账户
|
||||
/unbind 解绑账户
|
||||
/export 导出账户信息(JSON格式)
|
||||
/export 导出账户信息(JSON)
|
||||
/help 帮助
|
||||
/task 手动执行一次任务(管理员)
|
||||
/log 获取最近日志文件(管理员)
|
||||
源码及使用方法:https://github.com/iyear/E5SubBot
|
||||
`
|
||||
)
|
||||
@ -110,7 +107,7 @@ func bMyInlineBtn(c *tb.Callback) {
|
||||
func bBind1(m *tb.Message) {
|
||||
logger.Println(strconv.FormatInt(m.Chat.ID, 10) + " Start Bind")
|
||||
logger.Println("ReApp: " + strconv.FormatInt(m.Chat.ID, 10))
|
||||
bot.Send(m.Chat, "应用注册: [点击直达]("+outlook.GetMSRegisterAppUrl()+")", tb.ModeMarkdown)
|
||||
bot.Send(m.Chat, "应用注册: [点击直达]("+core.GetMSRegisterAppUrl()+")", tb.ModeMarkdown)
|
||||
_, err := bot.Send(m.Chat, "请回复client_id+空格+client_secret", &tb.ReplyMarkup{ForceReply: true})
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
@ -131,7 +128,7 @@ func bBind2(m *tb.Message) {
|
||||
logger.Println("client_id: " + tmp[0] + " client_secret: " + tmp[1])
|
||||
cid := tmp[0]
|
||||
cse := tmp[1]
|
||||
bot.Send(m.Chat, "授权账户: [点击直达]("+outlook.GetMSAuthUrl(cid)+")", tb.ModeMarkdown)
|
||||
bot.Send(m.Chat, "授权账户: [点击直达]("+core.GetMSAuthUrl(cid)+")", tb.ModeMarkdown)
|
||||
_, err := bot.Send(m.Chat, "请回复http://localhost/…… + 空格 + 别名(用于管理)", &tb.ReplyMarkup{ForceReply: true})
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
@ -194,7 +191,7 @@ func bExport(m *tb.Message) {
|
||||
ms.Other = u.Other
|
||||
MsMini = append(MsMini, ms)
|
||||
}
|
||||
//MarshalIndent是为json+美化,/t表缩进
|
||||
//MarshalIndent json美化,/t缩进
|
||||
export, err := json.MarshalIndent(MsMini, "", "\t")
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
@ -305,7 +302,6 @@ func bLogsInlineBtn(c *tb.Callback) {
|
||||
logfile := &tb.Document{File: tb.FromDisk(bLogBasePath + c.Data), FileName: c.Data, MIME: "text/plain"}
|
||||
_, err := bot.Send(c.Message.Chat, logfile)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return
|
||||
}
|
||||
bot.Respond(c)
|
||||
|
||||
148
core/client.go
148
core/client.go
@ -1,5 +1,14 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tidwall/gjson"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
TgId int64 `gorm:"column:tg_id"`
|
||||
RefreshToken string `gorm:"column:refresh_token"`
|
||||
@ -10,3 +19,142 @@ type Client struct {
|
||||
ClientSecret string `gorm:"column:client_secret"`
|
||||
Other string `gorm:"column:other"`
|
||||
}
|
||||
|
||||
const (
|
||||
msApiUrl string = "https://login.microsoftonline.com"
|
||||
msGraUrl string = "https://graph.microsoft.com"
|
||||
redirectUri string = "http://localhost/e5sub"
|
||||
scope string = "openid offline_access mail.read user.read"
|
||||
)
|
||||
|
||||
func NewClient(clientId string, clientSecret string) *Client {
|
||||
return &Client{
|
||||
ClientId: clientId,
|
||||
ClientSecret: clientSecret,
|
||||
}
|
||||
}
|
||||
func GetMSAuthUrl(clientId string) string {
|
||||
return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + clientId + "&response_type=code&redirect_uri=" + url.QueryEscape(redirectUri) + "&response_mode=query&scope=" + url.QueryEscape(scope)
|
||||
}
|
||||
func GetMSRegisterAppUrl() string {
|
||||
ru := "https://developer.microsoft.com/en-us/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=http://localhost:8000&platform=option-windowsuniversal"
|
||||
deeplink := "/quickstart/graphIO?publicClientSupport=false&appName=e5sub&redirectUrl=http://localhost/e5sub&allowImplicitFlow=false&ru=" + url.QueryEscape(ru)
|
||||
appUrl := "https://apps.dev.microsoft.com/?deepLink=" + url.QueryEscape(deeplink)
|
||||
return appUrl
|
||||
}
|
||||
|
||||
//return access_token and refresh_token
|
||||
func (c *Client) GetTokenWithCode(code string) (error error) {
|
||||
var r http.Request
|
||||
client := &http.Client{}
|
||||
r.ParseForm()
|
||||
r.Form.Add("client_id", c.ClientId)
|
||||
r.Form.Add("client_secret", c.ClientSecret)
|
||||
r.Form.Add("grant_type", "authorization_code")
|
||||
r.Form.Add("scope", scope)
|
||||
r.Form.Add("code", code)
|
||||
r.Form.Add("redirect_uri", redirectUri)
|
||||
body := strings.NewReader(r.Form.Encode())
|
||||
req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if gjson.Get(string(content), "token_type").String() == "Bearer" {
|
||||
c.RefreshToken = gjson.Get(string(content), "refresh_token").String()
|
||||
return nil
|
||||
}
|
||||
return errors.New(string(content))
|
||||
}
|
||||
|
||||
//return access_token and new refresh token
|
||||
func (c *Client) getToken() (access string) {
|
||||
var r http.Request
|
||||
client := &http.Client{}
|
||||
r.ParseForm()
|
||||
r.Form.Add("client_id", c.ClientId)
|
||||
r.Form.Add("client_secret", c.ClientSecret)
|
||||
r.Form.Add("grant_type", "refresh_token")
|
||||
r.Form.Add("scope", scope)
|
||||
r.Form.Add("refresh_token", c.RefreshToken)
|
||||
r.Form.Add("redirect_uri", redirectUri)
|
||||
body := strings.NewReader(r.Form.Encode())
|
||||
//fmt.Println(body)
|
||||
req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
//fmt.Println(string(content))
|
||||
//fmt.Println(gjson.Get(string(content), "access_token").String())
|
||||
if gjson.Get(string(content), "token_type").String() == "Bearer" {
|
||||
c.RefreshToken = gjson.Get(string(content), "refresh_token").String()
|
||||
return gjson.Get(string(content), "access_token").String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
//Get User's Information
|
||||
func (c *Client) GetUserInfo() (json string, error error) {
|
||||
client := http.Client{}
|
||||
req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Authorization", c.getToken())
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if gjson.Get(string(content), "id").String() != "" {
|
||||
//fmt.Println("UserName: " + gjson.Get(string(content), "displayName").String())
|
||||
return string(content), nil
|
||||
}
|
||||
return "", errors.New(string(content))
|
||||
}
|
||||
|
||||
func (c *Client) GetOutlookMails() error {
|
||||
client := http.Client{}
|
||||
req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Authorization", c.getToken())
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Println(string(content))
|
||||
//这里的.需要转义,否则会按路径的方式解析
|
||||
if gjson.Get(string(content), "@odata\\.context").String() != "" {
|
||||
return nil
|
||||
}
|
||||
return errors.New(string(content))
|
||||
}
|
||||
|
||||
@ -1,164 +0,0 @@
|
||||
package outlook
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/tidwall/gjson"
|
||||
"io/ioutil"
|
||||
"main/logger"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
msApiUrl string = "https://login.microsoftonline.com"
|
||||
msGraUrl string = "https://graph.microsoft.com"
|
||||
redirectUri string = "http://localhost/e5sub"
|
||||
scope string = "openid offline_access mail.read user.read"
|
||||
)
|
||||
|
||||
type msClient struct {
|
||||
clientId string
|
||||
clientSecret string
|
||||
}
|
||||
|
||||
func NewMSClient(clientId string, clientSecret string) *msClient {
|
||||
return &msClient{
|
||||
clientId: clientId,
|
||||
clientSecret: clientSecret,
|
||||
}
|
||||
}
|
||||
func GetMSAuthUrl(clientId string) string {
|
||||
return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + clientId + "&response_type=code&redirect_uri=" + url.QueryEscape(redirectUri) + "&response_mode=query&scope=" + url.QueryEscape(scope)
|
||||
}
|
||||
func GetMSRegisterAppUrl() string {
|
||||
ru := "https://developer.microsoft.com/en-us/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=http://localhost:8000&platform=option-windowsuniversal"
|
||||
deeplink := "/quickstart/graphIO?publicClientSupport=false&appName=e5sub&redirectUrl=http://localhost/e5sub&allowImplicitFlow=false&ru=" + url.QueryEscape(ru)
|
||||
appUrl := "https://apps.dev.microsoft.com/?deepLink=" + url.QueryEscape(deeplink)
|
||||
return appUrl
|
||||
}
|
||||
|
||||
//return access_token and refresh_token
|
||||
func (c *msClient) GetTokenWithCode(code string) (access string, refresh string, Error error) {
|
||||
var r http.Request
|
||||
client := &http.Client{}
|
||||
r.ParseForm()
|
||||
r.Form.Add("client_id", c.clientId)
|
||||
r.Form.Add("client_secret", c.clientSecret)
|
||||
r.Form.Add("grant_type", "authorization_code")
|
||||
r.Form.Add("scope", scope)
|
||||
r.Form.Add("code", code)
|
||||
r.Form.Add("redirect_uri", redirectUri)
|
||||
body := strings.NewReader(r.Form.Encode())
|
||||
req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", "", err
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", "", err
|
||||
}
|
||||
if gjson.Get(string(content), "token_type").String() == "Bearer" {
|
||||
return gjson.Get(string(content), "access_token").String(), gjson.Get(string(content), "refresh_token").String(), nil
|
||||
}
|
||||
return "", "", errors.New(string(content))
|
||||
}
|
||||
|
||||
//return access_token and new refresh token
|
||||
func (c *msClient) GetToken(refreshToken string) (access string, newRefreshToken string, Error error) {
|
||||
var r http.Request
|
||||
client := &http.Client{}
|
||||
r.ParseForm()
|
||||
r.Form.Add("client_id", c.clientId)
|
||||
r.Form.Add("client_secret", c.clientSecret)
|
||||
r.Form.Add("grant_type", "refresh_token")
|
||||
r.Form.Add("scope", scope)
|
||||
r.Form.Add("refresh_token", refreshToken)
|
||||
r.Form.Add("redirect_uri", redirectUri)
|
||||
body := strings.NewReader(r.Form.Encode())
|
||||
//fmt.Println(body)
|
||||
req, err := http.NewRequest("POST", msApiUrl+"/common/oauth2/v2.0/token", body)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", "", err
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", "", err
|
||||
}
|
||||
//fmt.Println(string(content))
|
||||
//fmt.Println(gjson.Get(string(content), "access_token").String())
|
||||
if gjson.Get(string(content), "token_type").String() == "Bearer" {
|
||||
return gjson.Get(string(content), "access_token").String(), gjson.Get(string(content), "refresh_token").String(), nil
|
||||
}
|
||||
return "", "", errors.New(string(content))
|
||||
}
|
||||
|
||||
//Get User's Information
|
||||
func GetUserInfo(accesstoken string) (json string, Error error) {
|
||||
client := http.Client{}
|
||||
req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me", nil)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Authorization", accesstoken)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return "", err
|
||||
}
|
||||
if gjson.Get(string(content), "id").String() != "" {
|
||||
//fmt.Println("UserName: " + gjson.Get(string(content), "displayName").String())
|
||||
return string(content), nil
|
||||
}
|
||||
return "", errors.New(string(content))
|
||||
}
|
||||
|
||||
func GetOutLookMails(accesstoken string) (bool, error) {
|
||||
client := http.Client{}
|
||||
req, err := http.NewRequest("GET", msGraUrl+"/v1.0/me/messages", nil)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return false, err
|
||||
}
|
||||
req.Header.Set("Authorization", accesstoken)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logger.Println(err)
|
||||
return false, err
|
||||
}
|
||||
//fmt.Println(string(content))
|
||||
//这里的.需要转义,否则会按路径的方式解析
|
||||
if gjson.Get(string(content), "@odata\\.context").String() != "" {
|
||||
return true, nil
|
||||
}
|
||||
return false, errors.New(string(content))
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user