update database.go, go.mod, go.sum, google_oauth.go, Makefile, styles.css, telegram_oauth.go
This commit is contained in:
1 parent
c05aa6b2f8
commit
d24b3837f1
7 files changed
+731
No files matched your search
@@ -0,0 +1,116 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"esauth/pkg/repository"
|
||||
"esauth/pkg/service"
|
||||
"esauth/pkg/util"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type TelegramOAuth struct {
|
||||
Service *service.Service
|
||||
Repo *repository.Repository
|
||||
BotId string
|
||||
BotToken string
|
||||
}
|
||||
|
||||
func (t TelegramOAuth) HandleTelegramOAuthCallback(c *gin.Context) {
|
||||
// Получаем хеш и параметры из запроса.
|
||||
hash := c.Query("hash")
|
||||
|
||||
// Собираем параметры для формирования data-check-string.
|
||||
params := map[string]string{
|
||||
"id": c.Query("id"),
|
||||
"first_name": c.Query("first_name"),
|
||||
"last_name": c.Query("last_name"),
|
||||
"username": c.Query("username"),
|
||||
"auth_date": c.Query("auth_date"),
|
||||
"photo_url": c.Query("photo_url"),
|
||||
}
|
||||
|
||||
// Удаляем пустые значения из параметров.
|
||||
var validParams []string
|
||||
for key, value := range params {
|
||||
if value != "" {
|
||||
validParams = append(validParams, fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
}
|
||||
|
||||
// Сортируем параметры в алфавитном порядке.
|
||||
sort.Strings(validParams)
|
||||
dataCheckString := strings.Join(validParams, "\n")
|
||||
|
||||
// Генерируем секретный ключ через SHA256 от botToken.
|
||||
secretKey := sha256.Sum256([]byte(t.BotToken))
|
||||
|
||||
// Вычисляем HMAC-SHA256 от data-check-string с использованием secretKey.
|
||||
h := hmac.New(sha256.New, secretKey[:])
|
||||
h.Write([]byte(dataCheckString))
|
||||
calculatedHash := hex.EncodeToString(h.Sum(nil))
|
||||
|
||||
// Сравниваем вычисленный хеш с переданным.
|
||||
if calculatedHash != hash {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, "Invalid hash")
|
||||
return
|
||||
}
|
||||
|
||||
// Проверка времени auth_date, чтобы избежать устаревших данных.
|
||||
date, _ := strconv.ParseInt(params["auth_date"], 10, 64)
|
||||
if time.Now().Unix()-int64(date) > 86400 {
|
||||
util.NewErrorResponse(c, http.StatusUnauthorized, "Authorization request expired")
|
||||
return
|
||||
}
|
||||
|
||||
user, _ := t.Repo.FindUser("telegram_id = ?", params["id"])
|
||||
usertoken := c.Query("usertoken")
|
||||
currentUserId, err := t.Service.ParseToken(usertoken)
|
||||
if err == nil {
|
||||
currentUser, _ := t.Repo.GetUser(currentUserId)
|
||||
if (user.Id != currentUser.Id) && (user.Id != 0) {
|
||||
util.NewErrorResponse(c, http.StatusUnauthorized, fmt.Sprintf("This account already conntected to user %d", user.Id))
|
||||
return
|
||||
}
|
||||
user = currentUser
|
||||
}
|
||||
|
||||
if user.Username == "" {
|
||||
user.Username = params["username"]
|
||||
}
|
||||
if user.FirstName == "" {
|
||||
user.FirstName = params["first_name"]
|
||||
}
|
||||
if user.LastName == "" {
|
||||
user.LastName = params["last_name"]
|
||||
}
|
||||
if user.PictureURL == "" {
|
||||
user.PictureURL = params["photo_url"]
|
||||
}
|
||||
if user.Email == "" {
|
||||
user.Email = ""
|
||||
}
|
||||
|
||||
user.TelegramId = params["id"]
|
||||
_, err = t.Service.CreateUser(&user)
|
||||
if err != nil {
|
||||
t.Service.SaveUser(&user)
|
||||
}
|
||||
|
||||
tkn, err := t.Service.GenerateToken(user.Id)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Redirect(http.StatusMovedPermanently, "/?token="+tkn)
|
||||
c.Abort()
|
||||
}
|
||||
Reference in new issue
Block a user