Feat experimental WebAuth API

This commit is contained in:
HFO4
2019-12-08 22:17:36 +08:00
parent 0932a10fed
commit f35c585edf
14 changed files with 269 additions and 6 deletions

View File

@@ -1,5 +1,6 @@
package controllers
import "C"
import (
"context"
"github.com/HFO4/cloudreve/models"
@@ -9,10 +10,45 @@ import (
"github.com/HFO4/cloudreve/pkg/util"
"github.com/HFO4/cloudreve/service/explorer"
"github.com/gin-gonic/gin"
"net/http"
"net/url"
"strconv"
)
// Thumb 获取文件缩略图
func Thumb(c *gin.Context) {
// 创建上下文
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
fs, err := filesystem.NewFileSystemFromContext(c)
if err != nil {
c.JSON(200, serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err))
return
}
// 获取文件ID
fileID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(200, serializer.ParamErr("无法解析文件ID", err))
return
}
// 获取缩略图
resp, err := fs.GetThumb(ctx, uint(fileID))
if err != nil {
c.JSON(200, serializer.Err(serializer.CodeNotSet, "无法获取缩略图", err))
return
}
if resp.Redirect {
c.Redirect(http.StatusMovedPermanently, resp.URL)
return
}
http.ServeContent(c.Writer, c.Request, "thumb.png", fs.FileTarget[0].UpdatedAt, resp.Content)
}
// Download 文件下载
func Download(c *gin.Context) {
// 创建上下文

View File

@@ -1,11 +1,109 @@
package controllers
import (
"encoding/json"
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/authn"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/HFO4/cloudreve/pkg/util"
"github.com/HFO4/cloudreve/service/user"
"github.com/duo-labs/webauthn/webauthn"
"github.com/gin-gonic/gin"
)
// StartLoginAuthn 开始注册WebAuthn登录
func StartLoginAuthn(c *gin.Context) {
userName := c.Param("username")
expectedUser, err := model.GetUserByEmail(userName)
if err != nil {
c.JSON(200, serializer.Err(401, "用户邮箱或密码错误", err))
return
}
options, sessionData, err := authn.Authn.BeginLogin(expectedUser)
if err != nil {
c.JSON(200, ErrorResponse(err))
return
}
val, err := json.Marshal(sessionData)
if err != nil {
c.JSON(200, ErrorResponse(err))
return
}
util.SetSession(c, map[string]interface{}{
"registration-session": val,
})
c.JSON(200, serializer.Response{Code: 0, Data: options})
}
// FinishLoginAuthn 完成注册WebAuthn登录
func FinishLoginAuthn(c *gin.Context) {
userName := c.Param("username")
expectedUser, err := model.GetUserByEmail(userName)
if err != nil {
c.JSON(200, serializer.Err(401, "用户邮箱或密码错误", err))
return
}
sessionDataJSON := util.GetSession(c, "registration-session").([]byte)
var sessionData webauthn.SessionData
err = json.Unmarshal(sessionDataJSON, &sessionData)
_, err = authn.Authn.FinishLogin(expectedUser, sessionData, c.Request)
if err != nil {
c.JSON(200, serializer.Err(401, "用户邮箱或密码错误", err))
return
}
util.SetSession(c, map[string]interface{}{
"user_id": expectedUser.ID,
})
c.JSON(200, serializer.BuildUserResponse(expectedUser))
}
// StartRegAuthn 开始注册WebAuthn信息
func StartRegAuthn(c *gin.Context) {
currUser := CurrentUser(c)
options, sessionData, err := authn.Authn.BeginRegistration(currUser)
if err != nil {
c.JSON(200, ErrorResponse(err))
return
}
val, err := json.Marshal(sessionData)
if err != nil {
c.JSON(200, ErrorResponse(err))
return
}
util.SetSession(c, map[string]interface{}{
"registration-session": val,
})
c.JSON(200, serializer.Response{Code: 0, Data: options})
}
// FinishRegAuthn 完成注册WebAuthn信息
func FinishRegAuthn(c *gin.Context) {
currUser := CurrentUser(c)
sessionDataJSON := util.GetSession(c, "registration-session").([]byte)
var sessionData webauthn.SessionData
err := json.Unmarshal(sessionDataJSON, &sessionData)
credential, err := authn.Authn.FinishRegistration(currUser, sessionData, c.Request)
currUser.RegisterAuthn(credential)
if err != nil {
c.JSON(200, ErrorResponse(err))
return
}
c.JSON(200, serializer.Response{Code: 0})
}
// UserLogin 用户登录
func UserLogin(c *gin.Context) {
var service user.UserLoginService