Files
oc-auth/main.go

142 lines
5.2 KiB
Go

package main
import (
"context"
"encoding/json"
"oc-auth/conf"
"oc-auth/infrastructure"
auth_connectors "oc-auth/infrastructure/auth_connector"
_ "oc-auth/routers"
"strings"
"time"
oclib "cloud.o-forge.io/core/oc-lib"
"cloud.o-forge.io/core/oc-lib/tools"
beego "github.com/beego/beego/v2/server/web"
)
const appname = "oc-auth"
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and JWT token.
func main() {
oclib.InitAPI(appname)
// Load the right config file
o := oclib.GetConfLoader(appname)
conf.GetConfig().AdminRole = o.GetStringDefault("ADMIN_ROLE", "admin")
conf.GetConfig().PublicKeyPath = o.GetStringDefault("PUBLIC_KEY_PATH", "./pem/public.pem")
conf.GetConfig().PrivateKeyPath = o.GetStringDefault("PRIVATE_KEY_PATH", "./pem/private.pem")
conf.GetConfig().ClientSecret = o.GetStringDefault("CLIENT_SECRET", "oc-auth-got-secret")
conf.GetConfig().OAuth2ClientSecretName = o.GetStringDefault("OAUTH2_CLIENT_SECRET_NAME", "oc-oauth2-client-secret")
conf.GetConfig().OAuth2ClientSecretNamespace = o.GetStringDefault("NAMESPACE", "default")
conf.GetConfig().Auth = o.GetStringDefault("AUTH", "hydra")
conf.GetConfig().AuthConnectorHost = o.GetStringDefault("AUTH_CONNECTOR_HOST", "localhost")
conf.GetConfig().AuthConnectPublicHost = o.GetStringDefault("AUTH_CONNECTOR_PUBLIC_HOST", "localhost")
conf.GetConfig().AuthConnectorPort = o.GetIntDefault("AUTH_CONNECTOR_PORT", 4444)
conf.GetConfig().AuthConnectorAdminPort = o.GetStringDefault("AUTH_CONNECTOR_ADMIN_PORT", "4445/admin")
conf.GetConfig().PermissionConnectorWriteHost = o.GetStringDefault("PERMISSION_CONNECTOR_WRITE_HOST", "keto")
conf.GetConfig().PermissionConnectorReadHost = o.GetStringDefault("PERMISSION_CONNECTOR_READ_HOST", "keto")
conf.GetConfig().PermissionConnectorPort = o.GetStringDefault("PERMISSION_CONNECTOR_PORT", "4466")
conf.GetConfig().PermissionConnectorAdminPort = o.GetStringDefault("PERMISSION_CONNECTOR_ADMIN_PORT", "4467")
conf.GetConfig().Origin = o.GetStringDefault("ADMIN_ORIGIN", "http://localhost:8000")
conf.GetConfig().AdminOrigin = o.GetStringDefault("ADMIN_ORIGIN", "http://localhost:8001")
conf.GetConfig().OAuthRedirectURI = o.GetStringDefault("OAUTH_REDIRECT_URI", "http://google.com")
conf.GetConfig().OAdminAuthRedirectURI = o.GetStringDefault("ADMIN_OAUTH_REDIRECT_URI", "http://chatgpt.com")
conf.GetConfig().Local = o.GetBoolDefault("LOCAL", true)
// config LDAPauth
conf.GetConfig().SourceMode = o.GetStringDefault("SOURCE_MODE", "ldap")
conf.GetConfig().LDAPEndpoints = o.GetStringDefault("LDAP_ENDPOINTS", "ldap:389")
conf.GetConfig().LDAPBindDN = o.GetStringDefault("LDAP_BINDDN", "cn=admin,dc=example,dc=com")
conf.GetConfig().LDAPBindPW = o.GetStringDefault("LDAP_BINDPW", "password")
conf.GetConfig().LDAPBaseDN = o.GetStringDefault("LDAP_BASEDN", "dc=example,dc=com")
conf.GetConfig().LDAPUserBaseDN = o.GetStringDefault("LDAP_USER_BASEDN", "ou=users,dc=example,dc=com")
conf.GetConfig().LDAPRoleBaseDN = o.GetStringDefault("LDAP_ROLE_BASEDN", "ou=AppRoles,dc=example,dc=com")
go generateRole()
go discovery()
beego.Run()
}
func generateRole() {
logger := oclib.GetLogger()
defer func() {
if r := recover(); r != nil {
logger.Error().Msgf("generateRole recovered from panic: %v", r)
}
}()
if conf.GetConfig().SourceMode == "ldap" {
for {
ldap := auth_connectors.New()
roles, err := ldap.GetRoles(context.Background())
if err == nil {
logger.Info().Msgf("Syncing %d LDAP role groups to Keto", len(roles))
for _, role := range roles {
for r, m := range role.Members {
infrastructure.GetPermissionConnector("").CreateRole(r)
for _, p := range m {
infrastructure.GetPermissionConnector("").BindRole(r, p)
}
}
}
break
} else {
logger.Error().Msg("Failed to get LDAP roles, retrying in 10s: " + err.Error())
time.Sleep(10 * time.Second)
continue
}
}
}
}
func discovery() {
logger := oclib.GetLogger()
defer func() {
if r := recover(); r != nil {
logger.Error().Msgf("discovery recovered from panic: %v", r)
}
}()
for {
api := tools.API{}
conn := infrastructure.GetPermissionConnector("")
logger.Info().Msg("Starting permission discovery")
_, _, err := conn.CreateRole(conf.GetConfig().AdminRole)
if err != nil {
if !strings.Contains(err.Error(), "already exist") {
logger.Error().Msg("Failed to create admin role, retrying in 10s: " + err.Error())
time.Sleep(10 * time.Second)
continue
}
}
if _, _, err := conn.BindRole(conf.GetConfig().AdminRole, "admin"); err != nil {
logger.Error().Msg("Failed to admin bind role: " + err.Error())
}
addPermissions := func(m tools.NATSResponse) {
var resp map[string][]interface{}
json.Unmarshal(m.Payload, &resp)
for k, v := range resp {
for _, p := range v {
if _, _, err := conn.CreatePermission(k, p.(string), true); err != nil {
logger.Error().Msg("Failed to admin create permission: " + err.Error())
}
}
}
}
api.ListenRouter(addPermissions)
b, _ := json.Marshal(map[string]interface{}{})
tools.NewNATSCaller().SetNATSPub(tools.DISCOVERY, tools.NATSResponse{
FromApp: "oc-auth",
Datatype: -1,
User: "root",
Method: tools.GET.EnumIndex(),
Payload: b,
})
break
}
}