2023-05-05 21:23:59 +08:00
|
|
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package controllers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/casdoor/casdoor/object"
|
|
|
|
"github.com/casdoor/casdoor/util"
|
2024-02-06 20:17:59 +08:00
|
|
|
"github.com/google/uuid"
|
|
|
|
)
|
|
|
|
|
2023-05-05 21:23:59 +08:00
|
|
|
// MfaSetupInitiate
|
|
|
|
// @Title MfaSetupInitiate
|
|
|
|
// @Tag MFA API
|
|
|
|
// @Description setup MFA
|
|
|
|
// @param owner form string true "owner of user"
|
|
|
|
// @param name form string true "name of user"
|
|
|
|
// @param type form string true "MFA auth type"
|
2023-06-30 00:48:39 +08:00
|
|
|
// @Success 200 {object} controllers.Response The Response object
|
2023-05-05 21:23:59 +08:00
|
|
|
// @router /mfa/setup/initiate [post]
|
|
|
|
func (c *ApiController) MfaSetupInitiate() {
|
|
|
|
owner := c.Ctx.Request.Form.Get("owner")
|
|
|
|
name := c.Ctx.Request.Form.Get("name")
|
2023-06-21 18:56:37 +08:00
|
|
|
mfaType := c.Ctx.Request.Form.Get("mfaType")
|
2023-05-05 21:23:59 +08:00
|
|
|
userId := util.GetId(owner, name)
|
|
|
|
|
|
|
|
if len(userId) == 0 {
|
|
|
|
c.ResponseError(http.StatusText(http.StatusBadRequest))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-06-21 18:56:37 +08:00
|
|
|
MfaUtil := object.GetMfaUtil(mfaType, nil)
|
2023-05-05 21:23:59 +08:00
|
|
|
if MfaUtil == nil {
|
|
|
|
c.ResponseError("Invalid auth type")
|
|
|
|
}
|
2023-06-21 18:56:37 +08:00
|
|
|
|
2023-05-30 15:49:39 +08:00
|
|
|
user, err := object.GetUser(userId)
|
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-05-05 21:23:59 +08:00
|
|
|
if user == nil {
|
|
|
|
c.ResponseError("User doesn't exist")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-02-06 20:17:59 +08:00
|
|
|
mfaProps, err := MfaUtil.Initiate(user.GetId())
|
2023-05-05 21:23:59 +08:00
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-02-06 20:17:59 +08:00
|
|
|
recoveryCode := uuid.NewString()
|
|
|
|
mfaProps.RecoveryCodes = []string{recoveryCode}
|
|
|
|
|
2023-05-05 21:23:59 +08:00
|
|
|
resp := mfaProps
|
|
|
|
c.ResponseOk(resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MfaSetupVerify
|
|
|
|
// @Title MfaSetupVerify
|
|
|
|
// @Tag MFA API
|
|
|
|
// @Description setup verify totp
|
|
|
|
// @param secret form string true "MFA secret"
|
|
|
|
// @param passcode form string true "MFA passcode"
|
2023-12-29 15:12:40 +08:00
|
|
|
// @Success 200 {object} controllers.Response The Response object
|
2023-05-05 21:23:59 +08:00
|
|
|
// @router /mfa/setup/verify [post]
|
|
|
|
func (c *ApiController) MfaSetupVerify() {
|
2023-06-21 18:56:37 +08:00
|
|
|
mfaType := c.Ctx.Request.Form.Get("mfaType")
|
2023-05-05 21:23:59 +08:00
|
|
|
passcode := c.Ctx.Request.Form.Get("passcode")
|
2024-11-29 19:50:10 +08:00
|
|
|
secret := c.Ctx.Request.Form.Get("secret")
|
|
|
|
dest := c.Ctx.Request.Form.Get("dest")
|
|
|
|
countryCode := c.Ctx.Request.Form.Get("secret")
|
2023-05-05 21:23:59 +08:00
|
|
|
|
2023-06-21 18:56:37 +08:00
|
|
|
if mfaType == "" || passcode == "" {
|
2023-05-05 21:23:59 +08:00
|
|
|
c.ResponseError("missing auth type or passcode")
|
|
|
|
return
|
|
|
|
}
|
2024-02-06 20:17:59 +08:00
|
|
|
|
|
|
|
config := &object.MfaProps{
|
|
|
|
MfaType: mfaType,
|
|
|
|
}
|
|
|
|
if mfaType == object.TotpType {
|
2024-11-29 19:50:10 +08:00
|
|
|
if secret == "" {
|
2024-02-06 20:17:59 +08:00
|
|
|
c.ResponseError("totp secret is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
config.Secret = secret
|
2024-02-14 23:29:04 +08:00
|
|
|
} else if mfaType == object.SmsType {
|
2024-11-29 19:50:10 +08:00
|
|
|
if dest == "" {
|
2024-02-06 20:17:59 +08:00
|
|
|
c.ResponseError("destination is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
config.Secret = dest
|
|
|
|
if countryCode == "" {
|
2024-02-06 20:17:59 +08:00
|
|
|
c.ResponseError("country code is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
config.CountryCode = countryCode
|
2024-02-14 23:29:04 +08:00
|
|
|
} else if mfaType == object.EmailType {
|
2024-11-29 19:50:10 +08:00
|
|
|
if dest == "" {
|
2024-02-14 23:29:04 +08:00
|
|
|
c.ResponseError("destination is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
config.Secret = dest
|
2024-02-06 20:17:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
mfaUtil := object.GetMfaUtil(mfaType, config)
|
2023-06-21 18:56:37 +08:00
|
|
|
if mfaUtil == nil {
|
|
|
|
c.ResponseError("Invalid multi-factor authentication type")
|
|
|
|
return
|
|
|
|
}
|
2023-05-05 21:23:59 +08:00
|
|
|
|
2024-02-06 20:17:59 +08:00
|
|
|
err := mfaUtil.SetupVerify(passcode)
|
2023-05-05 21:23:59 +08:00
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
} else {
|
|
|
|
c.ResponseOk(http.StatusText(http.StatusOK))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MfaSetupEnable
|
|
|
|
// @Title MfaSetupEnable
|
|
|
|
// @Tag MFA API
|
|
|
|
// @Description enable totp
|
|
|
|
// @param owner form string true "owner of user"
|
|
|
|
// @param name form string true "name of user"
|
|
|
|
// @param type form string true "MFA auth type"
|
2023-12-29 15:12:40 +08:00
|
|
|
// @Success 200 {object} controllers.Response The Response object
|
2023-05-05 21:23:59 +08:00
|
|
|
// @router /mfa/setup/enable [post]
|
|
|
|
func (c *ApiController) MfaSetupEnable() {
|
|
|
|
owner := c.Ctx.Request.Form.Get("owner")
|
|
|
|
name := c.Ctx.Request.Form.Get("name")
|
2023-06-21 18:56:37 +08:00
|
|
|
mfaType := c.Ctx.Request.Form.Get("mfaType")
|
2024-11-29 19:50:10 +08:00
|
|
|
secret := c.Ctx.Request.Form.Get("secret")
|
|
|
|
dest := c.Ctx.Request.Form.Get("dest")
|
|
|
|
countryCode := c.Ctx.Request.Form.Get("secret")
|
|
|
|
recoveryCodes := c.Ctx.Request.Form.Get("recoveryCodes")
|
2023-05-05 21:23:59 +08:00
|
|
|
|
2023-05-30 15:49:39 +08:00
|
|
|
user, err := object.GetUser(util.GetId(owner, name))
|
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-05-05 21:23:59 +08:00
|
|
|
if user == nil {
|
|
|
|
c.ResponseError("User doesn't exist")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-02-06 20:17:59 +08:00
|
|
|
config := &object.MfaProps{
|
|
|
|
MfaType: mfaType,
|
|
|
|
}
|
|
|
|
|
|
|
|
if mfaType == object.TotpType {
|
2024-11-29 19:50:10 +08:00
|
|
|
if secret == "" {
|
2024-02-06 20:17:59 +08:00
|
|
|
c.ResponseError("totp secret is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
config.Secret = secret
|
2024-02-14 23:29:04 +08:00
|
|
|
} else if mfaType == object.EmailType {
|
|
|
|
if user.Email == "" {
|
2024-11-29 19:50:10 +08:00
|
|
|
if dest == "" {
|
2024-02-14 23:29:04 +08:00
|
|
|
c.ResponseError("destination is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
user.Email = dest
|
2024-02-06 20:17:59 +08:00
|
|
|
}
|
2024-02-14 23:29:04 +08:00
|
|
|
} else if mfaType == object.SmsType {
|
|
|
|
if user.Phone == "" {
|
2024-11-29 19:50:10 +08:00
|
|
|
if dest == "" {
|
2024-02-14 23:29:04 +08:00
|
|
|
c.ResponseError("destination is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
user.Phone = dest
|
|
|
|
if countryCode == "" {
|
2024-02-14 23:29:04 +08:00
|
|
|
c.ResponseError("country code is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
user.CountryCode = countryCode
|
2024-02-06 20:17:59 +08:00
|
|
|
}
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
|
|
|
|
if recoveryCodes == "" {
|
2024-02-06 20:17:59 +08:00
|
|
|
c.ResponseError("recovery codes is missing")
|
|
|
|
return
|
|
|
|
}
|
2024-11-29 19:50:10 +08:00
|
|
|
config.RecoveryCodes = []string{recoveryCodes}
|
2024-02-06 20:17:59 +08:00
|
|
|
|
|
|
|
mfaUtil := object.GetMfaUtil(mfaType, config)
|
2023-06-21 18:56:37 +08:00
|
|
|
if mfaUtil == nil {
|
|
|
|
c.ResponseError("Invalid multi-factor authentication type")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-02-06 20:17:59 +08:00
|
|
|
err = mfaUtil.Enable(user)
|
2023-05-05 21:23:59 +08:00
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.ResponseOk(http.StatusText(http.StatusOK))
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteMfa
|
|
|
|
// @Title DeleteMfa
|
|
|
|
// @Tag MFA API
|
|
|
|
// @Description: Delete MFA
|
|
|
|
// @param owner form string true "owner of user"
|
|
|
|
// @param name form string true "name of user"
|
2023-12-29 15:12:40 +08:00
|
|
|
// @Success 200 {object} controllers.Response The Response object
|
2023-05-05 21:23:59 +08:00
|
|
|
// @router /delete-mfa/ [post]
|
|
|
|
func (c *ApiController) DeleteMfa() {
|
|
|
|
owner := c.Ctx.Request.Form.Get("owner")
|
|
|
|
name := c.Ctx.Request.Form.Get("name")
|
|
|
|
userId := util.GetId(owner, name)
|
|
|
|
|
2023-05-30 15:49:39 +08:00
|
|
|
user, err := object.GetUser(userId)
|
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
2023-05-05 21:23:59 +08:00
|
|
|
if user == nil {
|
|
|
|
c.ResponseError("User doesn't exist")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-06-21 18:56:37 +08:00
|
|
|
err = object.DisabledMultiFactorAuth(user)
|
2023-05-30 15:49:39 +08:00
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-06-21 18:56:37 +08:00
|
|
|
c.ResponseOk(object.GetAllMfaProps(user, true))
|
2023-05-05 21:23:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetPreferredMfa
|
|
|
|
// @Title SetPreferredMfa
|
|
|
|
// @Tag MFA API
|
|
|
|
// @Description: Set specific Mfa Preferred
|
|
|
|
// @param owner form string true "owner of user"
|
|
|
|
// @param name form string true "name of user"
|
|
|
|
// @param id form string true "id of user's MFA props"
|
2023-12-29 15:12:40 +08:00
|
|
|
// @Success 200 {object} controllers.Response The Response object
|
2023-05-05 21:23:59 +08:00
|
|
|
// @router /set-preferred-mfa [post]
|
|
|
|
func (c *ApiController) SetPreferredMfa() {
|
2023-06-21 18:56:37 +08:00
|
|
|
mfaType := c.Ctx.Request.Form.Get("mfaType")
|
2023-05-05 21:23:59 +08:00
|
|
|
owner := c.Ctx.Request.Form.Get("owner")
|
|
|
|
name := c.Ctx.Request.Form.Get("name")
|
|
|
|
userId := util.GetId(owner, name)
|
|
|
|
|
2023-05-30 15:49:39 +08:00
|
|
|
user, err := object.GetUser(userId)
|
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
2023-05-05 21:23:59 +08:00
|
|
|
if user == nil {
|
|
|
|
c.ResponseError("User doesn't exist")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-06-21 18:56:37 +08:00
|
|
|
err = object.SetPreferredMultiFactorAuth(user, mfaType)
|
2023-05-30 15:49:39 +08:00
|
|
|
if err != nil {
|
|
|
|
c.ResponseError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
2023-06-21 18:56:37 +08:00
|
|
|
c.ResponseOk(object.GetAllMfaProps(user, true))
|
2023-05-05 21:23:59 +08:00
|
|
|
}
|