mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-03 20:30:41 +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>
143 lines
3.4 KiB
Go
143 lines
3.4 KiB
Go
package model
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/pkg/errors"
|
|
saml2 "github.com/russellhaering/gosaml2"
|
|
"go.signoz.io/signoz/ee/query-service/saml"
|
|
basemodel "go.signoz.io/signoz/pkg/query-service/model"
|
|
)
|
|
|
|
type SSOType string
|
|
|
|
const (
|
|
SAML SSOType = "SAML"
|
|
GoogleAuth SSOType = "GOOGLE_AUTH"
|
|
)
|
|
|
|
type SamlConfig struct {
|
|
SamlEntity string `json:"samlEntity"`
|
|
SamlIdp string `json:"samlIdp"`
|
|
SamlCert string `json:"samlCert"`
|
|
}
|
|
|
|
// OrgDomain identify org owned web domains for auth and other purposes
|
|
type OrgDomain struct {
|
|
Id uuid.UUID `json:"id"`
|
|
Name string `json:"name"`
|
|
OrgId string `json:"orgId"`
|
|
SsoEnabled bool `json:"ssoEnabled"`
|
|
SsoType SSOType `json:"ssoType"`
|
|
SamlConfig *SamlConfig `json:"samlConfig"`
|
|
Org *basemodel.Organization
|
|
}
|
|
|
|
// Valid is used a pipeline function to check if org domain
|
|
// loaded from db is valid
|
|
func (od *OrgDomain) Valid(err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if od.Id == uuid.Nil || od.OrgId == "" {
|
|
return fmt.Errorf("both id and orgId are required")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ValidNew cheks if the org domain is valid for insertion in db
|
|
func (od *OrgDomain) ValidNew() error {
|
|
|
|
if od.OrgId == "" {
|
|
return fmt.Errorf("orgId is required")
|
|
}
|
|
|
|
if od.Name == "" {
|
|
return fmt.Errorf("name is required")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// LoadConfig loads config params from json text
|
|
func (od *OrgDomain) LoadConfig(jsondata string) error {
|
|
d := *od
|
|
err := json.Unmarshal([]byte(jsondata), &d)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to marshal json to OrgDomain{}")
|
|
}
|
|
*od = d
|
|
return nil
|
|
}
|
|
|
|
func (od *OrgDomain) GetSAMLEntityID() string {
|
|
if od.SamlConfig != nil {
|
|
return od.SamlConfig.SamlEntity
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (od *OrgDomain) GetSAMLIdpURL() string {
|
|
if od.SamlConfig != nil {
|
|
return od.SamlConfig.SamlIdp
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (od *OrgDomain) GetSAMLCert() string {
|
|
if od.SamlConfig != nil {
|
|
return od.SamlConfig.SamlCert
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// PrepareSamlRequest creates a request accordingly gosaml2
|
|
func (od *OrgDomain) PrepareSamlRequest(siteUrl *url.URL) (*saml2.SAMLServiceProvider, error) {
|
|
|
|
// this is the url Idp will call after login completion
|
|
acs := fmt.Sprintf("%s://%s/%s",
|
|
siteUrl.Scheme,
|
|
siteUrl.Host,
|
|
"api/v1/complete/saml")
|
|
|
|
// this is the address of the calling url, useful to redirect user
|
|
sourceUrl := fmt.Sprintf("%s://%s%s",
|
|
siteUrl.Scheme,
|
|
siteUrl.Host,
|
|
siteUrl.Path)
|
|
|
|
// ideally this should be some unique ID for each installation
|
|
// but since we dont have UI to support it, we default it to
|
|
// host. this issuer is an identifier of service provider (signoz)
|
|
// on id provider (e.g. azure, okta). Azure requires this id to be configured
|
|
// in their system, while others seem to not care about it.
|
|
// currently we default it to host from window.location (received from browser)
|
|
issuer := siteUrl.Host
|
|
|
|
return saml.PrepareRequest(issuer, acs, sourceUrl, od.GetSAMLEntityID(), od.GetSAMLIdpURL(), od.GetSAMLCert())
|
|
}
|
|
|
|
func (od *OrgDomain) BuildSsoUrl(siteUrl *url.URL) (ssoUrl string, err error) {
|
|
|
|
sp, err := od.PrepareSamlRequest(siteUrl)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
fmtDomainId := strings.Replace(od.Id.String(), "-", ":", -1)
|
|
|
|
relayState := fmt.Sprintf("%s://%s%s?domainId=%s",
|
|
siteUrl.Scheme,
|
|
siteUrl.Host,
|
|
siteUrl.Path,
|
|
fmtDomainId)
|
|
|
|
return sp.BuildAuthURL(relayState)
|
|
}
|