Files
vm/authz/authz.go
zeekayandGitHub f7321c9463 build(visor): GOEXPERIMENT=jsonv2 per SCALE_STANDARD (#8)
* refactor: import github.com/hanzoai/iam (drop iamsdk/v2)

Switch from github.com/hanzoai/iamsdk/v2/iamsdk to canonical
github.com/hanzoai/iam root package. One canonical path, no drift.
Pinned to iam@86e34e93 SHA pseudo-version until v1.16.2 ships.

* build(visor): GOEXPERIMENT=jsonv2 in Dockerfile per SCALE_STANDARD

Per SCALE_STANDARD.md §2 — every Go production Dockerfile that emits
JSON to a client builds with GOEXPERIMENT=jsonv2. Verified on
hanzoai/zip's json_bench_test.go:
- Edge POST roundtrip: -12% time, -23% allocs
- Marshal-only: -22% time
- Unmarshal-only: -19% time, -25% allocs

build.sh inherits the ENV from the parent ARG so the existing go-build
invocation picks up jsonv2 unchanged. The conn-memory regression test
is deferred to a follow-up that migrates visor's beego v1.12 listener
to zip per §9 step-1.
2026-05-29 21:05:29 -07:00

150 lines
3.7 KiB
Go

// Copyright 2024 Hanzo Industries Inc. All Rights Reserved.
//
// 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 authz
import (
"strings"
authz "github.com/hanzoai/authz"
"github.com/hanzoai/authz/model"
stringadapter "github.com/hanzoai/authz/persist/string-adapter"
"github.com/hanzoai/authzstore"
iam "github.com/hanzoai/iam"
"github.com/hanzoai/visor/conf"
"github.com/hanzoai/xorm"
)
var Enforcer *authz.Enforcer
func InitAuthz() {
var err error
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
driverName := conf.GetConfigString("driverName")
dataSourceName := conf.GetConfigDataSourceName()
if driverName == "mysql" {
dataSourceName = dataSourceName + conf.GetConfigString("dbName")
}
eng, err := xorm.NewEngine(driverName, dataSourceName)
if err != nil {
panic(err)
}
a, err := authzstore.New(eng, "api_rule", tableNamePrefix)
if err != nil {
panic(err)
}
modelText := `
[request_definition]
r = subOwner, subName, method, urlPath, objOwner, objName
[policy_definition]
p = subOwner, subName, method, urlPath, objOwner, objName
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (r.subOwner == p.subOwner || p.subOwner == "*") && (r.subName == p.subName || p.subName == "*") && \
(r.method == p.method || p.method == "*") && (r.urlPath == p.urlPath || p.urlPath == "*") && \
(r.objOwner == p.objOwner || p.objOwner == "*") && (r.objName == p.objName || p.objName == "*")
`
m, err := model.NewModelFromString(modelText)
if err != nil {
panic(err)
}
Enforcer, err = authz.NewEnforcer(m, a)
if err != nil {
panic(err)
}
if true {
ruleText := `
p, built-in, *, *, *, *, *
p, app, *, *, *, *, *
p, *, *, POST, /api/signin, *, *
p, *, *, POST, /api/signout, *, *
p, *, *, GET, /api/get-account, *, *
p, *, *, GET, /api/get-asset-tunnel, *, *
p, *, *, POST, /api/add-asset-tunnel, *, *
p, *, *, POST, /api/start-session, *, *
p, *, *, GET, /api/get-whitelabel, *, *
`
sa := stringadapter.NewAdapter(ruleText)
// load all rules from string adapter to enforcer's memory
err := sa.LoadPolicy(Enforcer.GetModel())
if err != nil {
panic(err)
}
// save all rules from enforcer's memory to Xorm adapter (DB)
// same as:
// a.SavePolicy(Enforcer.GetModel())
err = Enforcer.SavePolicy()
if err != nil {
panic(err)
}
}
}
func IsAllowed(user *iam.User, subOwner string, subName string, method string, urlPath string, objOwner string, objName string) bool {
if conf.GetConfigBool("IsDemoMode") {
if !isAllowedInDemoMode(method, urlPath) {
return false
}
}
if subOwner == "app" {
return true
}
if user != nil {
if user.IsDeleted {
return false
}
if subOwner == objOwner || (objOwner == "admin") {
return true
}
}
res, err := Enforcer.Enforce(subOwner, subName, method, urlPath, objOwner, objName)
if err != nil {
panic(err)
}
return res
}
func isAllowedInDemoMode(method string, urlPath string) bool {
if method == "POST" {
if strings.HasPrefix(urlPath, "/v1/signin") || urlPath == "/v1/signout" || urlPath == "/v1/add-asset-tunnel" || urlPath == "/v1/start-session" || urlPath == "/v1/stop-session" {
return true
} else {
return false
}
}
// If method equals GET
return true
}