2022-02-13 23:39:27 +08:00
|
|
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
2020-10-20 21:57:29 +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.
|
|
|
|
|
|
|
|
package controllers
|
|
|
|
|
2021-07-18 07:54:49 +08:00
|
|
|
import (
|
2022-01-15 23:23:14 +08:00
|
|
|
"strings"
|
2021-07-18 07:54:49 +08:00
|
|
|
"time"
|
|
|
|
|
2022-09-29 19:44:08 +08:00
|
|
|
"github.com/beego/beego"
|
|
|
|
"github.com/beego/beego/logs"
|
2022-01-20 14:11:46 +08:00
|
|
|
"github.com/casdoor/casdoor/object"
|
|
|
|
"github.com/casdoor/casdoor/util"
|
2021-07-18 07:54:49 +08:00
|
|
|
)
|
2020-10-20 21:57:29 +08:00
|
|
|
|
2022-08-09 16:50:49 +08:00
|
|
|
// ApiController
|
2021-12-03 20:42:36 +08:00
|
|
|
// controller for handlers under /api uri
|
2020-10-20 21:57:29 +08:00
|
|
|
type ApiController struct {
|
|
|
|
beego.Controller
|
|
|
|
}
|
|
|
|
|
2022-08-09 16:50:49 +08:00
|
|
|
// RootController
|
2021-12-03 20:42:36 +08:00
|
|
|
// controller for handlers directly under / (root)
|
|
|
|
type RootController struct {
|
|
|
|
ApiController
|
|
|
|
}
|
|
|
|
|
2021-07-18 07:54:49 +08:00
|
|
|
type SessionData struct {
|
|
|
|
ExpireTime int64
|
|
|
|
}
|
|
|
|
|
2022-01-13 23:19:36 +08:00
|
|
|
func (c *ApiController) IsGlobalAdmin() bool {
|
2023-04-25 23:05:53 +08:00
|
|
|
isGlobalAdmin, _ := c.isGlobalAdmin()
|
|
|
|
|
|
|
|
return isGlobalAdmin
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ApiController) IsAdmin() bool {
|
|
|
|
isGlobalAdmin, user := c.isGlobalAdmin()
|
2023-05-19 21:24:55 +08:00
|
|
|
if !isGlobalAdmin && user == nil {
|
2023-04-26 16:21:58 +08:00
|
|
|
return false
|
|
|
|
}
|
2023-04-25 23:05:53 +08:00
|
|
|
|
|
|
|
return isGlobalAdmin || user.IsAdmin
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ApiController) isGlobalAdmin() (bool, *object.User) {
|
2022-01-13 23:19:36 +08:00
|
|
|
username := c.GetSessionUsername()
|
2022-01-15 23:23:14 +08:00
|
|
|
if strings.HasPrefix(username, "app/") {
|
|
|
|
// e.g., "app/app-casnode"
|
2023-04-25 23:05:53 +08:00
|
|
|
return true, nil
|
2022-01-15 23:23:14 +08:00
|
|
|
}
|
|
|
|
|
2023-04-25 23:05:53 +08:00
|
|
|
user := c.getCurrentUser()
|
2022-01-15 23:23:14 +08:00
|
|
|
if user == nil {
|
2023-04-25 23:05:53 +08:00
|
|
|
return false, nil
|
2022-01-15 23:23:14 +08:00
|
|
|
}
|
|
|
|
|
2023-04-25 23:05:53 +08:00
|
|
|
return user.Owner == "built-in" || user.IsGlobalAdmin, user
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ApiController) getCurrentUser() *object.User {
|
|
|
|
var user *object.User
|
2023-05-30 15:49:39 +08:00
|
|
|
var err error
|
2023-04-25 23:05:53 +08:00
|
|
|
userId := c.GetSessionUsername()
|
|
|
|
if userId == "" {
|
|
|
|
user = nil
|
|
|
|
} else {
|
2023-05-30 15:49:39 +08:00
|
|
|
user, err = object.GetUser(userId)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2023-04-25 23:05:53 +08:00
|
|
|
}
|
|
|
|
return user
|
2022-01-13 23:19:36 +08:00
|
|
|
}
|
|
|
|
|
2021-08-07 22:02:56 +08:00
|
|
|
// GetSessionUsername ...
|
2021-07-18 07:15:22 +08:00
|
|
|
func (c *ApiController) GetSessionUsername() string {
|
2021-07-18 07:54:49 +08:00
|
|
|
// check if user session expired
|
|
|
|
sessionData := c.GetSessionData()
|
2022-08-20 21:09:32 +08:00
|
|
|
|
2021-07-18 07:54:49 +08:00
|
|
|
if sessionData != nil &&
|
|
|
|
sessionData.ExpireTime != 0 &&
|
|
|
|
sessionData.ExpireTime < time.Now().Unix() {
|
2022-10-29 20:18:02 +08:00
|
|
|
c.ClearUserSession()
|
2021-07-18 07:54:49 +08:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2020-10-20 23:14:03 +08:00
|
|
|
user := c.GetSession("username")
|
|
|
|
if user == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return user.(string)
|
|
|
|
}
|
|
|
|
|
2022-03-19 19:50:05 +08:00
|
|
|
func (c *ApiController) GetSessionApplication() *object.Application {
|
|
|
|
clientId := c.GetSession("aud")
|
|
|
|
if clientId == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2023-05-30 15:49:39 +08:00
|
|
|
application, err := object.GetApplicationByClientId(clientId.(string))
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2022-03-19 19:50:05 +08:00
|
|
|
return application
|
|
|
|
}
|
|
|
|
|
2022-10-29 20:18:02 +08:00
|
|
|
func (c *ApiController) ClearUserSession() {
|
|
|
|
c.SetSessionUsername("")
|
|
|
|
c.SetSessionData(nil)
|
|
|
|
}
|
|
|
|
|
2022-01-26 11:56:01 +08:00
|
|
|
func (c *ApiController) GetSessionOidc() (string, string) {
|
|
|
|
sessionData := c.GetSessionData()
|
|
|
|
if sessionData != nil &&
|
|
|
|
sessionData.ExpireTime != 0 &&
|
|
|
|
sessionData.ExpireTime < time.Now().Unix() {
|
2022-10-29 20:18:02 +08:00
|
|
|
c.ClearUserSession()
|
2022-01-26 11:56:01 +08:00
|
|
|
return "", ""
|
|
|
|
}
|
|
|
|
scopeValue := c.GetSession("scope")
|
|
|
|
audValue := c.GetSession("aud")
|
|
|
|
var scope, aud string
|
|
|
|
var ok bool
|
|
|
|
if scope, ok = scopeValue.(string); !ok {
|
|
|
|
scope = ""
|
|
|
|
}
|
|
|
|
if aud, ok = audValue.(string); !ok {
|
|
|
|
aud = ""
|
|
|
|
}
|
|
|
|
return scope, aud
|
|
|
|
}
|
|
|
|
|
2021-08-07 22:02:56 +08:00
|
|
|
// SetSessionUsername ...
|
2021-07-18 07:15:22 +08:00
|
|
|
func (c *ApiController) SetSessionUsername(user string) {
|
2020-10-20 23:14:03 +08:00
|
|
|
c.SetSession("username", user)
|
2020-10-20 21:57:29 +08:00
|
|
|
}
|
2021-03-28 00:48:34 +08:00
|
|
|
|
2021-08-07 22:02:56 +08:00
|
|
|
// GetSessionData ...
|
2021-07-18 07:54:49 +08:00
|
|
|
func (c *ApiController) GetSessionData() *SessionData {
|
|
|
|
session := c.GetSession("SessionData")
|
|
|
|
if session == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
sessionData := &SessionData{}
|
|
|
|
err := util.JsonToStruct(session.(string), sessionData)
|
|
|
|
if err != nil {
|
2022-08-20 21:09:32 +08:00
|
|
|
logs.Error("GetSessionData failed, error: %s", err)
|
|
|
|
return nil
|
2021-07-18 07:54:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return sessionData
|
|
|
|
}
|
|
|
|
|
2021-08-07 22:02:56 +08:00
|
|
|
// SetSessionData ...
|
2021-07-18 07:54:49 +08:00
|
|
|
func (c *ApiController) SetSessionData(s *SessionData) {
|
|
|
|
if s == nil {
|
|
|
|
c.DelSession("SessionData")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.SetSession("SessionData", util.StructToJson(s))
|
|
|
|
}
|
|
|
|
|
2023-05-05 21:23:59 +08:00
|
|
|
func (c *ApiController) setMfaSessionData(data *object.MfaSessionData) {
|
2023-06-21 18:56:37 +08:00
|
|
|
if data == nil {
|
|
|
|
c.SetSession(object.MfaSessionUserId, nil)
|
|
|
|
return
|
|
|
|
}
|
2023-05-05 21:23:59 +08:00
|
|
|
c.SetSession(object.MfaSessionUserId, data.UserId)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ApiController) getMfaSessionData() *object.MfaSessionData {
|
|
|
|
userId := c.GetSession(object.MfaSessionUserId)
|
|
|
|
if userId == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
data := &object.MfaSessionData{
|
|
|
|
UserId: userId.(string),
|
|
|
|
}
|
|
|
|
return data
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ApiController) setExpireForSession() {
|
|
|
|
timestamp := time.Now().Unix()
|
|
|
|
timestamp += 3600 * 24
|
|
|
|
c.SetSessionData(&SessionData{
|
|
|
|
ExpireTime: timestamp,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-05-30 15:49:39 +08:00
|
|
|
func wrapActionResponse(affected bool, e ...error) *Response {
|
|
|
|
if len(e) != 0 && e[0] != nil {
|
|
|
|
return &Response{Status: "error", Msg: e[0].Error()}
|
|
|
|
} else if affected {
|
2022-08-16 00:20:37 +08:00
|
|
|
return &Response{Status: "ok", Msg: "", Data: "Affected"}
|
2021-03-28 00:48:34 +08:00
|
|
|
} else {
|
2022-08-16 00:20:37 +08:00
|
|
|
return &Response{Status: "ok", Msg: "", Data: "Unaffected"}
|
2021-03-28 00:48:34 +08:00
|
|
|
}
|
|
|
|
}
|
2022-03-06 22:46:02 +08:00
|
|
|
|
|
|
|
func wrapErrorResponse(err error) *Response {
|
|
|
|
if err == nil {
|
|
|
|
return &Response{Status: "ok", Msg: ""}
|
|
|
|
} else {
|
|
|
|
return &Response{Status: "error", Msg: err.Error()}
|
|
|
|
}
|
|
|
|
}
|
2023-04-26 22:18:48 +08:00
|
|
|
|
|
|
|
func (c *ApiController) Finish() {
|
|
|
|
if strings.HasPrefix(c.Ctx.Input.URL(), "/api") {
|
|
|
|
startTime := c.Ctx.Input.GetData("startTime")
|
|
|
|
if startTime != nil {
|
|
|
|
latency := time.Since(startTime.(time.Time)).Milliseconds()
|
2023-04-28 22:11:10 +08:00
|
|
|
object.ApiLatency.WithLabelValues(c.Ctx.Input.URL(), c.Ctx.Input.Method()).Observe(float64(latency))
|
2023-04-26 22:18:48 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
c.Controller.Finish()
|
|
|
|
}
|