初始提交:OCI 面板后端(含 GenAI 网关一期)

This commit is contained in:
Wang Defa
2026-07-09 15:31:04 +08:00
commit b9a3e97e84
168 changed files with 31794 additions and 0 deletions
+173
View File
@@ -0,0 +1,173 @@
package api
import (
"net/http"
"github.com/gin-gonic/gin"
"oci-portal/internal/oci"
)
// ---- FederationSAML IdP 与 sign-on 免 MFA ----
// createIdpRequest 的映射 / JIT 字段全部可缺省:布尔用指针区分「未传」,
// 缺省即控制台默认(JIT 开启建用户不更新、分配 Administrators 组、
// 名称 ID 格式无、NameID 映射用户名)。
type createIdpRequest struct {
Name string `json:"name" binding:"required"`
Metadata string `json:"metadata" binding:"required"`
Description string `json:"description"`
IconURL string `json:"iconUrl"`
NameIDFormat string `json:"nameIdFormat"`
AssertionAttribute string `json:"assertionAttribute"`
UserStoreAttribute string `json:"userStoreAttribute"`
JitEnabled *bool `json:"jitEnabled"`
JitCreate *bool `json:"jitCreate"`
JitUpdate *bool `json:"jitUpdate"`
JitAssignAdminGroup *bool `json:"jitAssignAdminGroup"`
JitMapEmail bool `json:"jitMapEmail"`
}
func boolOr(v *bool, def bool) bool {
if v == nil {
return def
}
return *v
}
func (h *ociConfigHandler) listIdentityProviders(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
idps, err := h.svc.IdentityProviders(c.Request.Context(), id)
if err != nil {
respondError(c, err)
return
}
c.JSON(http.StatusOK, idps)
}
func (h *ociConfigHandler) createIdentityProvider(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
var req createIdpRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
idp, err := h.svc.CreateIdentityProvider(c.Request.Context(), id, oci.CreateIdpInput{
Name: req.Name,
Metadata: req.Metadata,
Description: req.Description,
IconURL: req.IconURL,
NameIDFormat: req.NameIDFormat,
AssertionAttribute: req.AssertionAttribute,
UserStoreAttribute: req.UserStoreAttribute,
JitEnabled: boolOr(req.JitEnabled, true),
JitCreate: boolOr(req.JitCreate, true),
JitUpdate: boolOr(req.JitUpdate, false),
JitAssignAdminGroup: boolOr(req.JitAssignAdminGroup, true),
JitMapEmail: req.JitMapEmail,
})
if err != nil {
respondError(c, err)
return
}
c.JSON(http.StatusCreated, idp)
}
func (h *ociConfigHandler) activateIdentityProvider(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
var req struct {
Enabled *bool `json:"enabled" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
idp, err := h.svc.SetIdentityProviderEnabled(c.Request.Context(), id, c.Param("idpId"), *req.Enabled)
if err != nil {
respondError(c, err)
return
}
c.JSON(http.StatusOK, idp)
}
func (h *ociConfigHandler) deleteIdentityProvider(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
if err := h.svc.DeleteIdentityProvider(c.Request.Context(), id, c.Param("idpId")); err != nil {
respondError(c, err)
return
}
c.Status(http.StatusNoContent)
}
func (h *ociConfigHandler) downloadSamlMetadata(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
metadata, err := h.svc.DomainSamlMetadata(c.Request.Context(), id)
if err != nil {
respondError(c, err)
return
}
c.Header("Content-Disposition", `attachment; filename="oci-domain-saml-metadata.xml"`)
c.Data(http.StatusOK, "application/xml", metadata)
}
func (h *ociConfigHandler) listSignOnRules(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
rules, err := h.svc.ConsoleSignOnRules(c.Request.Context(), id)
if err != nil {
respondError(c, err)
return
}
c.JSON(http.StatusOK, rules)
}
func (h *ociConfigHandler) createMfaExemption(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
var req struct {
IdentityProviderID string `json:"identityProviderId" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
rule, err := h.svc.CreateMfaExemption(c.Request.Context(), id, req.IdentityProviderID)
if err != nil {
respondError(c, err)
return
}
c.JSON(http.StatusCreated, rule)
}
func (h *ociConfigHandler) deleteMfaExemption(c *gin.Context) {
id, ok := pathID(c)
if !ok {
return
}
if err := h.svc.DeleteMfaExemption(c.Request.Context(), id, c.Param("ruleId")); err != nil {
respondError(c, err)
return
}
c.Status(http.StatusNoContent)
}