mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-06-04 11:25:52 +08:00

* feat: added license manager and feature flags * feat: completed org domain api * chore: checking in saml auth handler code * feat: added signup with sso * feat: added login support for admins * feat: added pem support for certificate * ci(build-workflow): 👷 include EE query-service * fix: 🐛 update package name * chore(ee): 🔧 LD_FLAGS related changes Signed-off-by: Prashant Shahi <prashant@signoz.io> Co-authored-by: Prashant Shahi <prashant@signoz.io> Co-authored-by: nityanandagohain <nityanandagohain@gmail.com>
113 lines
3.1 KiB
Go
113 lines
3.1 KiB
Go
package sqlite
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"go.signoz.io/signoz/ee/query-service/constants"
|
|
"go.signoz.io/signoz/ee/query-service/model"
|
|
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
|
|
basemodel "go.signoz.io/signoz/pkg/query-service/model"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func (m *modelDao) CanUsePassword(ctx context.Context, email string) (bool, basemodel.BaseApiError) {
|
|
domain, apierr := m.GetDomainByEmail(ctx, email)
|
|
if apierr != nil {
|
|
return false, apierr
|
|
}
|
|
|
|
if domain != nil && domain.SsoEnabled {
|
|
// sso is enabled, check if the user has admin role
|
|
userPayload, baseapierr := m.GetUserByEmail(ctx, email)
|
|
|
|
if baseapierr != nil || userPayload == nil {
|
|
return false, baseapierr
|
|
}
|
|
|
|
if userPayload.Role != baseconst.AdminGroup {
|
|
return false, model.BadRequest(fmt.Errorf("auth method not supported"))
|
|
}
|
|
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
// PrecheckLogin is called when the login or signup page is loaded
|
|
// to check sso login is to be prompted
|
|
func (m *modelDao) PrecheckLogin(ctx context.Context, email, sourceUrl string) (*model.PrecheckResponse, basemodel.BaseApiError) {
|
|
|
|
// assume user is valid unless proven otherwise
|
|
resp := &model.PrecheckResponse{IsUser: true, CanSelfRegister: false}
|
|
|
|
// check if email is a valid user
|
|
userPayload, baseApiErr := m.GetUserByEmail(ctx, email)
|
|
if baseApiErr != nil {
|
|
return resp, baseApiErr
|
|
}
|
|
|
|
if userPayload == nil {
|
|
resp.IsUser = false
|
|
}
|
|
ssoAvailable := true
|
|
err := m.checkFeature(model.SSO)
|
|
if err != nil {
|
|
switch err.(type) {
|
|
case basemodel.ErrFeatureUnavailable:
|
|
// do nothing, just skip sso
|
|
ssoAvailable = false
|
|
default:
|
|
zap.S().Errorf("feature check failed", zap.String("featureKey", model.SSO), zap.Error(err))
|
|
return resp, model.BadRequest(err)
|
|
}
|
|
}
|
|
|
|
if ssoAvailable {
|
|
|
|
// find domain from email
|
|
orgDomain, apierr := m.GetDomainByEmail(ctx, email)
|
|
if apierr != nil {
|
|
var emailDomain string
|
|
emailComponents := strings.Split(email, "@")
|
|
if len(emailComponents) > 0 {
|
|
emailDomain = emailComponents[1]
|
|
}
|
|
zap.S().Errorf("failed to get org domain from email", zap.String("emailDomain", emailDomain), apierr.ToError())
|
|
return resp, apierr
|
|
}
|
|
|
|
if orgDomain != nil && orgDomain.SsoEnabled {
|
|
// saml is enabled for this domain, lets prepare sso url
|
|
|
|
if sourceUrl == "" {
|
|
sourceUrl = constants.GetDefaultSiteURL()
|
|
}
|
|
|
|
// parse source url that generated the login request
|
|
var err error
|
|
escapedUrl, _ := url.QueryUnescape(sourceUrl)
|
|
siteUrl, err := url.Parse(escapedUrl)
|
|
if err != nil {
|
|
zap.S().Errorf("failed to parse referer", err)
|
|
return resp, model.InternalError(fmt.Errorf("failed to generate login request"))
|
|
}
|
|
|
|
// build Idp URL that will authenticat the user
|
|
// the front-end will redirect user to this url
|
|
resp.SsoUrl, err = orgDomain.BuildSsoUrl(siteUrl)
|
|
|
|
if err != nil {
|
|
zap.S().Errorf("failed to prepare saml request for domain", zap.String("domain", orgDomain.Name), err)
|
|
return resp, model.InternalError(err)
|
|
}
|
|
|
|
// set SSO to true, as the url is generated correctly
|
|
resp.SSO = true
|
|
}
|
|
}
|
|
return resp, nil
|
|
}
|