You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
synctv/server/handlers/vendors/vendorBilibili/login.go

208 lines
5.2 KiB
Go

package vendorBilibili
import (
"errors"
"net/http"
"github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op"
"github.com/synctv-org/synctv/internal/vendor"
"github.com/synctv-org/synctv/server/model"
"github.com/synctv-org/vendors/api/bilibili"
)
func NewQRCode(ctx *gin.Context) {
r, err := vendor.BilibiliClient("").NewQRCode(ctx, &bilibili.Empty{})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(r))
}
type QRCodeLoginReq struct {
Key string `json:"key"`
}
func (r *QRCodeLoginReq) Validate() error {
if r.Key == "" {
return errors.New("key is empty")
}
return nil
}
func (r *QRCodeLoginReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(r)
}
func LoginWithQR(ctx *gin.Context) {
user := ctx.MustGet("user").(*op.User)
req := QRCodeLoginReq{}
if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
resp, err := vendor.BilibiliClient("").LoginWithQRCode(ctx, &bilibili.LoginWithQRCodeReq{
Key: req.Key,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
switch resp.Status {
case bilibili.QRCodeStatus_EXPIRED:
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"status": "expired",
}))
return
case bilibili.QRCodeStatus_SCANNED:
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"status": "scanned",
}))
return
case bilibili.QRCodeStatus_NOTSCANNED:
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"status": "notScanned",
}))
return
case bilibili.QRCodeStatus_SUCCESS:
_, err = db.CreateOrSaveBilibiliVendor(user.ID, &dbModel.BilibiliVendor{
Cookies: resp.Cookies,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"status": "success",
}))
default:
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorStringResp("unknown status"))
return
}
}
func NewCaptcha(ctx *gin.Context) {
r, err := vendor.BilibiliClient("").NewCaptcha(ctx, &bilibili.Empty{})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(r))
}
type SMSReq struct {
Token string `json:"token"`
Challenge string `json:"challenge"`
Validate_ string `json:"validate"`
Telephone string `json:"telephone"`
}
func (r *SMSReq) Validate() error {
if r.Token == "" {
return errors.New("token is empty")
}
if r.Challenge == "" {
return errors.New("challenge is empty")
}
if r.Validate_ == "" {
return errors.New("validate is empty")
}
if r.Telephone == "" {
return errors.New("telephone is empty")
}
return nil
}
func (r *SMSReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(r)
}
func NewSMS(ctx *gin.Context) {
var req SMSReq
if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
r, err := vendor.BilibiliClient("").NewSMS(ctx, &bilibili.NewSMSReq{
Phone: req.Telephone,
Token: req.Token,
Challenge: req.Challenge,
Validate: req.Validate_,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"captchaKey": r.CaptchaKey,
}))
}
type SMSLoginReq struct {
Telephone string `json:"telephone"`
CaptchaKey string `json:"captchaKey"`
Code string `json:"code"`
}
func (r *SMSLoginReq) Validate() error {
if r.Telephone == "" {
return errors.New("telephone is empty")
}
if r.CaptchaKey == "" {
return errors.New("captchaKey is empty")
}
if r.Code == "" {
return errors.New("code is empty")
}
return nil
}
func (r *SMSLoginReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(r)
}
func LoginWithSMS(ctx *gin.Context) {
var req SMSLoginReq
if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
c, err := vendor.BilibiliClient("").LoginWithSMS(ctx, &bilibili.LoginWithSMSReq{
Phone: req.Telephone,
CaptchaKey: req.CaptchaKey,
Code: req.Code,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
user := ctx.MustGet("user").(*op.User)
_, err = db.CreateOrSaveBilibiliVendor(user.ID, &dbModel.BilibiliVendor{
Cookies: c.Cookies,
})
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.Status(http.StatusNoContent)
}
func Logout(ctx *gin.Context) {
user := ctx.MustGet("user").(*op.User)
err := db.DeleteBilibiliVendor(user.ID)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.Status(http.StatusNoContent)
}