Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a59426a
docs(auth): define SAT RBAC v2 precedence, classification, and capabi…
kelleyloder May 15, 2026
d256a0c
docs(auth): switch to routing-based auth selection (Option C) and def…
kelleyloder May 15, 2026
2b669f2
return 401 on invalid auth token
kelleyloder May 19, 2026
87e1e7d
Merge branch 'develop' into sat-rbac-capabilities-v2
kelleyloder May 20, 2026
658921e
changes to work locally as-is in acl moe or idp_service mode
kelleyloder May 20, 2026
bdd2d3d
git merge develop
kelleyloder May 21, 2026
c3bd773
added old open spec changes that got reverted
kelleyloder May 21, 2026
25d9e25
renamed file with trailing invisible characters
kelleyloder May 22, 2026
e35763d
Initial check-in to support multi-tenant
pt-nguyen Apr 23, 2026
995a1b1
Handled tenant_id for DeleteAllEntities
pt-nguyen Apr 29, 2026
1d1da52
Fix flaky tests: add SkipIfMockDatabase pattern, unique IDs, and sequ…
RahulRengeshOfficial Apr 29, 2026
4eafee5
Updated truncateTable to support tenantId param
pt-nguyen Apr 29, 2026
e967891
Fixed test failures due to missing tenantId in context
pt-nguyen Apr 29, 2026
99adc1b
Fixed tests
pt-nguyen Apr 30, 2026
0205d88
Fixed tests
pt-nguyen Apr 30, 2026
fc43c61
Fixed tests failures
pt-nguyen May 12, 2026
1c1441e
Updated due to changes from PenetrationMetrics to PenetrationData
pt-nguyen May 19, 2026
eafc74c
Fixed tenantId is not set in contextMap for some of the APIs
pt-nguyen May 20, 2026
713232e
fix: port idempotent test fixes to multi-tenant branch
RahulRengeshOfficial May 21, 2026
0b4e2f2
Fixed test failures
pt-nguyen May 21, 2026
4d183fc
feat: update tag handling to support multi-tenant architecture (#131)
mdolina Jun 1, 2026
fa3575a
fix: update member insertion query to use 'updated' timestamp instead…
mdolina Jun 1, 2026
a57bb70
refactor: change updated timestamp to use time.Now() in AddMembers fu…
mdolina Jun 3, 2026
b06daeb
updated Makefile, fixed failing tagging tests
kelleyloder Jun 2, 2026
4e53320
changes for multi-tenancy sat v2
kelleyloder Jun 25, 2026
3b36953
fix failing unit tests
kelleyloder Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ build: ## Build a version
go build -v -ldflags="-X ${REPO}/common.BinaryBranch=${BRANCH} -X ${REPO}/common.BinaryVersion=${Version} -X ${REPO}/common.BinaryBuildTime=${BUILDTIME}" -o bin/xconfadmin-${GOOS}-${GOARCH} main.go

test:
ulimit -n 10000 ; go test ./... -p 1 -parallel 1 -cover -count=1 -timeout=45m

test-verbose:
bash contrib/scripts/run_tests_with_summary.sh

localtest:
export RUN_IN_LOCAL=true ; go test ./... -cover -count=1 -failfast

cover:
go test ./... -count=1 -coverprofile=coverage.out -timeout=45m
go test ./... -count=1 -p 1 -coverprofile=coverage.out -timeout=45m

html:
go tool cover -html=coverage.out
Expand Down
45 changes: 24 additions & 21 deletions adminapi/adminapi_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,50 +112,53 @@ func WebServerInjection(ws *xhttp.WebconfigServer, xc *dataapi.XconfConfigs) {
Xc = xc
}

func initDB() {
queries.CreateFirmwareRuleTemplates() // Initialize FirmwareRule templates
initAppSettings() // Initialize Application settings
func initDB(tenantId string) error {
// Initialize FirmwareRule templates
if err := queries.CreateFirmwareRuleTemplates(tenantId); err != nil {
return err
}
// Initialize Application settings
if err := initAppSettings(tenantId); err != nil {
return err
}
return nil
}

func initAppSettings() {
settings, err := common.GetAppSettings()
func initAppSettings(tenantId string) error {
settings, err := common.GetAppSettings(tenantId)
if err != nil {
panic(err)
return err
}
if _, ok := settings[common.PROP_LOCKDOWN_ENABLED]; !ok {
common.SetAppSetting(common.PROP_LOCKDOWN_ENABLED, false)
common.SetAppSetting(tenantId, common.PROP_LOCKDOWN_ENABLED, false)
}
if _, ok := settings[common.PROP_CANARY_MAXSIZE]; !ok {
common.SetAppSetting(common.PROP_CANARY_MAXSIZE, common.CanarySize)
common.SetAppSetting(tenantId, common.PROP_CANARY_MAXSIZE, common.CanarySize)
}
if _, ok := settings[common.PROP_CANARY_DISTRIBUTION_PERCENTAGE]; !ok {
common.SetAppSetting(common.PROP_CANARY_DISTRIBUTION_PERCENTAGE, common.CanaryDistributionPercentage)
common.SetAppSetting(tenantId, common.PROP_CANARY_DISTRIBUTION_PERCENTAGE, common.CanaryDistributionPercentage)
}
if _, ok := settings[common.PROP_CANARY_FW_UPGRADE_STARTTIME]; !ok {
common.SetAppSetting(common.PROP_CANARY_FW_UPGRADE_STARTTIME, common.CanaryFwUpgradeStartTime)
common.SetAppSetting(tenantId, common.PROP_CANARY_FW_UPGRADE_STARTTIME, common.CanaryFwUpgradeStartTime)
}
if _, ok := settings[common.PROP_CANARY_FW_UPGRADE_ENDTIME]; !ok {
common.SetAppSetting(common.PROP_CANARY_FW_UPGRADE_ENDTIME, common.CanaryFwUpgradeEndTime)
common.SetAppSetting(tenantId, common.PROP_CANARY_FW_UPGRADE_ENDTIME, common.CanaryFwUpgradeEndTime)
}

if _, ok := settings[common.PROP_LOCKDOWN_STARTTIME]; !ok {
common.SetAppSetting(common.PROP_LOCKDOWN_STARTTIME, common.DefaultLockdownStartTime)
common.SetAppSetting(tenantId, common.PROP_LOCKDOWN_STARTTIME, common.DefaultLockdownStartTime)
}

if _, ok := settings[common.PROP_LOCKDOWN_ENDTIME]; !ok {
common.SetAppSetting(common.PROP_LOCKDOWN_ENDTIME, common.DefaultLockdownEndTime)
common.SetAppSetting(tenantId, common.PROP_LOCKDOWN_ENDTIME, common.DefaultLockdownEndTime)
}

if _, ok := settings[common.PROP_LOCKDOWN_MODULES]; !ok {
common.SetAppSetting(common.PROP_LOCKDOWN_MODULES, common.DefaultLockdownModules)
common.SetAppSetting(tenantId, common.PROP_LOCKDOWN_MODULES, common.DefaultLockdownModules)
}

if _, ok := settings[common.PROP_PRECOOK_LOCKDOWN_ENABLED]; !ok {
common.SetAppSetting(common.PROP_LOCKDOWN_ENABLED, common.DefaultPrecookLockdownEnabled)
common.SetAppSetting(tenantId, common.PROP_PRECOOK_LOCKDOWN_ENABLED, common.DefaultPrecookLockdownEnabled)
}

if _, ok := settings[common.PROP_CANARY_TIMEZONE_LIST]; !ok {
common.SetAppSetting(common.PROP_CANARY_TIMEZONE_LIST, common.DefaultCanaryTimezone)
common.SetAppSetting(tenantId, common.PROP_CANARY_TIMEZONE_LIST, common.DefaultCanaryTimezone)
}

return nil
}
9 changes: 9 additions & 0 deletions adminapi/auth/auth_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ func BasicAuthHandler(w http.ResponseWriter, r *http.Request) {

var authRequest AuthRequest
err := json.NewDecoder(r.Body).Decode(&authRequest)
if err != nil {
if xw, ok := w.(*xwhttp.XResponseWriter); ok {
if body := xw.Body(); body != "" {
if err2 := json.Unmarshal([]byte(body), &authRequest); err2 == nil {
err = nil
}
}
}
}
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
Expand Down
25 changes: 25 additions & 0 deletions adminapi/auth/idp_service_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ func GetAdminUIUrlFromCookies(r *http.Request) string {
}

func LogoutHandler(w http.ResponseWriter, r *http.Request) {
if Ws == nil || Ws.IdpServiceConnector == nil {
xhttp.WriteXconfResponse(w, http.StatusServiceUnavailable, []byte("IDP/Xerxes connector is not configured"))
return
}

http.SetCookie(w, xhttp.NewErasedAuthTokenCookie())

idpAuthServer := Ws.XW_XconfServer.ServerConfig.GetString("xconfwebconfig.xconf.idp_service_name")
Expand All @@ -72,7 +77,22 @@ func LogoutAfterHandler(w http.ResponseWriter, r *http.Request) {
xhttp.WriteXconfResponseWithHeaders(w, headers, http.StatusFound, []byte(""))
}

func AclLogoutHandler(w http.ResponseWriter, r *http.Request) {
http.SetCookie(w, xhttp.NewErasedAuthTokenCookie())

adminUrl := fmt.Sprintf("%s/#/authorization", GetAdminUIUrlFromCookies(r))
headers := map[string]string{
"Location": adminUrl,
}
xhttp.WriteXconfResponseWithHeaders(w, headers, http.StatusFound, []byte(""))
}

func CodeHandler(w http.ResponseWriter, r *http.Request) {
if Ws == nil || Ws.IdpServiceConnector == nil {
xhttp.WriteXconfResponse(w, http.StatusServiceUnavailable, []byte("IDP/Xerxes connector is not configured"))
return
}

codeList, ok := r.URL.Query()["code"]
if !ok {
xhttp.WriteXconfResponse(w, http.StatusBadRequest, []byte(""))
Expand Down Expand Up @@ -101,6 +121,11 @@ func CodeHandler(w http.ResponseWriter, r *http.Request) {
}

func LoginUrlHandler(w http.ResponseWriter, r *http.Request) {
if Ws == nil || Ws.IdpServiceConnector == nil {
xhttp.WriteXconfResponse(w, http.StatusServiceUnavailable, []byte("IDP/Xerxes connector is not configured"))
return
}

idpAuthServer := Ws.XW_XconfServer.ServerConfig.GetString("xconfwebconfig.xconf.idp_service_name")
continueUrl := GetAdminUIUrlFromCookies(r) + Ws.XW_XconfServer.ServerConfig.GetString(fmt.Sprintf("xconfwebconfig.%v.idp_code_path", idpAuthServer), "/"+getAuthProvider()+"/code")
loginUrl := Ws.IdpServiceConnector.GetFullLoginUrl(continueUrl)
Expand Down
Loading