2022-02-13 23:39:27 +08:00
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
2021-07-30 14:15:10 +08:00
//
// 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.
// Casdoor will expose its providers as services to SDK
// We are going to implement those services as APIs here
package controllers
import (
"encoding/json"
2021-09-05 10:30:51 +08:00
"fmt"
2023-03-03 22:44:22 +08:00
"strings"
2021-07-30 14:15:10 +08:00
2022-01-20 14:11:46 +08:00
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"
2021-07-30 14:15:10 +08:00
)
2022-06-21 23:11:29 +08:00
type EmailForm struct {
Title string ` json:"title" `
Content string ` json:"content" `
Sender string ` json:"sender" `
Receivers [ ] string ` json:"receivers" `
2022-06-24 01:47:10 +08:00
Provider string ` json:"provider" `
2022-06-21 23:11:29 +08:00
}
type SmsForm struct {
Content string ` json:"content" `
Receivers [ ] string ` json:"receivers" `
OrgId string ` json:"organizationId" ` // e.g. "admin/built-in"
}
2023-08-19 12:33:00 +08:00
type NotificationForm struct {
Content string ` json:"content" `
}
2021-08-07 22:02:56 +08:00
// SendEmail
2021-07-30 14:15:10 +08:00
// @Title SendEmail
2021-12-03 20:42:36 +08:00
// @Tag Service API
2021-07-30 14:15:10 +08:00
// @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
// @Param clientId query string true "The clientId of the application"
2021-09-05 10:30:51 +08:00
// @Param clientSecret query string true "The clientSecret of the application"
2022-06-21 23:11:29 +08:00
// @Param from body controllers.EmailForm true "Details of the email request"
2023-12-29 15:12:40 +08:00
// @Success 200 {object} controllers.Response The Response object
2024-01-15 23:27:42 +08:00
// @router /send-email [post]
2021-07-30 14:15:10 +08:00
func ( c * ApiController ) SendEmail ( ) {
2024-01-07 21:11:22 +08:00
userId , ok := c . RequireSignedIn ( )
2023-12-30 00:47:10 +08:00
if ! ok {
return
}
2022-06-21 23:11:29 +08:00
var emailForm EmailForm
2021-07-30 14:15:10 +08:00
err := json . Unmarshal ( c . Ctx . Input . RequestBody , & emailForm )
if err != nil {
2021-09-05 10:30:51 +08:00
c . ResponseError ( err . Error ( ) )
2021-07-30 14:15:10 +08:00
return
}
2022-06-24 01:47:10 +08:00
var provider * object . Provider
if emailForm . Provider != "" {
// called by frontend's TestEmailWidget, provider name is set by frontend
2023-05-30 15:49:39 +08:00
provider , err = object . GetProvider ( util . GetId ( "admin" , emailForm . Provider ) )
if err != nil {
c . ResponseError ( err . Error ( ) )
return
}
2022-06-24 01:47:10 +08:00
} else {
// called by Casdoor SDK via Client ID & Client Secret, so the used Email provider will be the application' Email provider or the default Email provider
2023-06-10 15:51:26 +08:00
provider , err = c . GetProviderFromContext ( "Email" )
if err != nil {
c . ResponseError ( err . Error ( ) )
2022-06-24 01:47:10 +08:00
return
}
}
// when receiver is the reserved keyword: "TestSmtpServer", it means to test the SMTP server instead of sending a real Email
if len ( emailForm . Receivers ) == 1 && emailForm . Receivers [ 0 ] == "TestSmtpServer" {
2024-03-11 11:48:00 +08:00
err = object . DailSmtpServer ( provider )
2022-06-24 01:47:10 +08:00
if err != nil {
c . ResponseError ( err . Error ( ) )
return
}
c . ResponseOk ( )
}
2023-02-18 09:31:58 +08:00
if util . IsStringsEmpty ( emailForm . Title , emailForm . Content , emailForm . Sender ) {
2022-12-07 13:13:23 +08:00
c . ResponseError ( fmt . Sprintf ( c . T ( "service:Empty parameters for emailForm: %v" ) , emailForm ) )
2021-07-30 14:15:10 +08:00
return
}
2021-09-05 10:30:51 +08:00
invalidReceivers := [ ] string { }
2021-07-30 14:15:10 +08:00
for _ , receiver := range emailForm . Receivers {
if ! util . IsEmailValid ( receiver ) {
2021-09-05 10:30:51 +08:00
invalidReceivers = append ( invalidReceivers , receiver )
2021-07-30 14:15:10 +08:00
}
}
2021-09-05 10:30:51 +08:00
if len ( invalidReceivers ) != 0 {
2022-12-07 13:13:23 +08:00
c . ResponseError ( fmt . Sprintf ( c . T ( "service:Invalid Email receivers: %s" ) , invalidReceivers ) )
2021-07-30 14:15:10 +08:00
return
}
2024-03-11 11:48:00 +08:00
content := emailForm . Content
if content == "" {
code := "123456"
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
content = strings . Replace ( provider . Content , "%s" , code , 1 )
if ! strings . HasPrefix ( userId , "app/" ) {
var user * object . User
user , err = object . GetUser ( userId )
if err != nil {
c . ResponseError ( err . Error ( ) )
return
}
if user != nil {
content = strings . Replace ( content , "%{user.friendlyName}" , user . GetFriendlyName ( ) , 1 )
}
2024-01-07 21:11:22 +08:00
}
2023-12-30 00:47:10 +08:00
}
2021-07-30 14:15:10 +08:00
for _ , receiver := range emailForm . Receivers {
2023-03-03 22:44:22 +08:00
err = object . SendEmail ( provider , emailForm . Title , content , receiver , emailForm . Sender )
2021-09-05 10:30:51 +08:00
if err != nil {
c . ResponseError ( err . Error ( ) )
return
2021-07-30 14:15:10 +08:00
}
}
2021-09-05 10:30:51 +08:00
c . ResponseOk ( )
2021-07-30 14:15:10 +08:00
}
2021-08-07 22:02:56 +08:00
// SendSms
2021-07-30 14:15:10 +08:00
// @Title SendSms
2021-12-03 20:42:36 +08:00
// @Tag Service API
2021-07-30 14:15:10 +08:00
// @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
// @Param clientId query string true "The clientId of the application"
2021-09-05 10:30:51 +08:00
// @Param clientSecret query string true "The clientSecret of the application"
2022-06-21 23:11:29 +08:00
// @Param from body controllers.SmsForm true "Details of the sms request"
2023-12-29 15:12:40 +08:00
// @Success 200 {object} controllers.Response The Response object
2024-01-15 23:27:42 +08:00
// @router /send-sms [post]
2021-07-30 14:15:10 +08:00
func ( c * ApiController ) SendSms ( ) {
2023-06-10 15:51:26 +08:00
provider , err := c . GetProviderFromContext ( "SMS" )
if err != nil {
c . ResponseError ( err . Error ( ) )
2021-07-30 14:15:10 +08:00
return
}
2022-06-21 23:11:29 +08:00
var smsForm SmsForm
2023-06-10 15:51:26 +08:00
err = json . Unmarshal ( c . Ctx . Input . RequestBody , & smsForm )
2021-09-05 10:30:51 +08:00
if err != nil {
c . ResponseError ( err . Error ( ) )
2021-07-30 14:15:10 +08:00
return
}
2023-08-12 12:52:53 +08:00
if provider . Type != "Custom HTTP SMS" {
invalidReceivers := getInvalidSmsReceivers ( smsForm )
if len ( invalidReceivers ) != 0 {
c . ResponseError ( fmt . Sprintf ( c . T ( "service:Invalid phone receivers: %s" ) , strings . Join ( invalidReceivers , ", " ) ) )
return
}
2021-07-30 14:15:10 +08:00
}
2021-09-05 11:10:27 +08:00
err = object . SendSms ( provider , smsForm . Content , smsForm . Receivers ... )
2021-09-05 10:48:03 +08:00
if err != nil {
c . ResponseError ( err . Error ( ) )
return
}
2021-09-05 10:30:51 +08:00
c . ResponseOk ( )
2021-07-30 14:15:10 +08:00
}
2023-08-19 12:33:00 +08:00
// SendNotification
// @Title SendNotification
// @Tag Service API
// @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
// @Param from body controllers.NotificationForm true "Details of the notification request"
2023-12-29 15:12:40 +08:00
// @Success 200 {object} controllers.Response The Response object
2024-01-15 23:27:42 +08:00
// @router /send-notification [post]
2023-08-19 12:33:00 +08:00
func ( c * ApiController ) SendNotification ( ) {
provider , err := c . GetProviderFromContext ( "Notification" )
if err != nil {
c . ResponseError ( err . Error ( ) )
return
}
var notificationForm NotificationForm
err = json . Unmarshal ( c . Ctx . Input . RequestBody , & notificationForm )
if err != nil {
c . ResponseError ( err . Error ( ) )
return
}
err = object . SendNotification ( provider , notificationForm . Content )
if err != nil {
c . ResponseError ( err . Error ( ) )
return
}
c . ResponseOk ( )
}