mirror of
https://github.com/go-gitea/gitea.git
synced 2026-06-15 08:04:04 +00:00
Closes #37670. Today, org members in Gitea only see teams they're a member of. In larger orgs that hurts onboarding and discoverability — there's no way to look up which team owns what without asking around. GitHub solves this with a per-team visibility setting; this PR brings the same model to Gitea. ## What changes - Every team gets a `visibility` setting: - `private` *(default)* — only team members and org owners can see the team. Same as today's behavior. - `limited` — listable by any member of the organization. Members and the repos the team has access to are visible too. Non-org-members still see nothing. - `public` — listable by any signed-in user. - The Owners team visibility is fixed and cannot be changed via settings. - Existing teams default to `private`, so this is a no-op for anyone who doesn't change anything. ## API - `Team`, `CreateTeamOption`, `EditTeamOption` all gain a `visibility` field (string enum: `private` | `limited` | `public`). - `GET /orgs/{org}/teams` and `/orgs/{org}/teams/search` now apply the same visibility rules as the web UI: - site admins and org owners still see every team - other org members see their own teams plus any `limited` or `public` team - `private` teams are no longer leaked through these endpoints - Swagger/OpenAPI specs regenerated. ## UI View from admin2 (not an owner): <img width="1669" height="726" src="https://github.com/user-attachments/assets/daf4bccb-644b-4426-b178-71963aeaf73b" /> View from admin (owner): <img width="2559" height="863" src="https://github.com/user-attachments/assets/4f22cebc-e9df-4fd2-8ed4-724d31fadb7a" /> --------- Signed-off-by: bircni <bircni@icloud.com> Co-authored-by: TheFox0x7 <thefox0x7@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
98 lines
2.7 KiB
Go
98 lines
2.7 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// generate-openapi converts Gitea's Swagger 2.0 spec into an OpenAPI 3.0 spec.
|
|
//
|
|
// Gitea generates a Swagger 2.0 spec from code annotations (make generate-swagger).
|
|
// This tool converts it to OAS3 so that SDK generators and tools that require
|
|
// OAS3 (e.g. progenitor for Rust) can consume it directly. The conversion also
|
|
// deduplicates inline enum definitions into named schema components, producing
|
|
// cleaner SDK output with proper enum types instead of anonymous strings.
|
|
//
|
|
// Run: go run build/generate-openapi.go
|
|
// Output: templates/swagger/v1_openapi3_json.tmpl
|
|
|
|
//go:build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
|
|
"gitea.dev/build/openapi3gen"
|
|
|
|
"github.com/getkin/kin-openapi/openapi3"
|
|
)
|
|
|
|
const (
|
|
swaggerSpecPath = "templates/swagger/v1_json.tmpl"
|
|
openapi3OutPath = "templates/swagger/v1_openapi3_json.tmpl"
|
|
|
|
appSubUrlVar = "{{.SwaggerAppSubUrl}}"
|
|
appVerVar = "{{.SwaggerAppVer}}"
|
|
|
|
appSubUrlPlaceholder = "GITEA_APP_SUB_URL_PLACEHOLDER"
|
|
appVerPlaceholder = "0.0.0-gitea-placeholder"
|
|
)
|
|
|
|
var (
|
|
appSubUrlRe = regexp.MustCompile(regexp.QuoteMeta(appSubUrlVar))
|
|
appVerRe = regexp.MustCompile(regexp.QuoteMeta(appVerVar))
|
|
|
|
enumScanDirs = []string{
|
|
"modules/structs",
|
|
"modules/commitstatus",
|
|
}
|
|
)
|
|
|
|
func main() {
|
|
astEnumMap, err := openapi3gen.ScanSwaggerEnumTypes(enumScanDirs)
|
|
if err != nil {
|
|
log.Fatalf("scanning swagger:enum annotations: %v", err)
|
|
}
|
|
names := make([]string, 0, len(astEnumMap))
|
|
for _, ns := range astEnumMap {
|
|
names = append(names, ns...)
|
|
}
|
|
sort.Strings(names)
|
|
fmt.Fprintf(os.Stderr, "discovered %d swagger:enum types: %s\n", len(names), strings.Join(names, ", "))
|
|
|
|
data, err := os.ReadFile(swaggerSpecPath)
|
|
if err != nil {
|
|
log.Fatalf("reading swagger spec: %v", err)
|
|
}
|
|
|
|
cleaned := appSubUrlRe.ReplaceAll(data, []byte(appSubUrlPlaceholder))
|
|
cleaned = appVerRe.ReplaceAll(cleaned, []byte(appVerPlaceholder))
|
|
|
|
oas3, err := openapi3gen.Convert(cleaned, astEnumMap)
|
|
if err != nil {
|
|
log.Fatalf("converting to openapi 3.0: %v", err)
|
|
}
|
|
|
|
oas3.Servers = openapi3.Servers{
|
|
{URL: appSubUrlPlaceholder + "/api/v1"},
|
|
}
|
|
|
|
out, err := json.MarshalIndent(oas3, "", " ")
|
|
if err != nil {
|
|
log.Fatalf("marshaling openapi 3.0: %v", err)
|
|
}
|
|
|
|
result := strings.ReplaceAll(string(out), appSubUrlPlaceholder, appSubUrlVar)
|
|
result = strings.ReplaceAll(result, appVerPlaceholder, appVerVar)
|
|
result = strings.TrimSpace(result)
|
|
|
|
if err := os.WriteFile(openapi3OutPath, []byte(result), 0o644); err != nil {
|
|
log.Fatalf("writing openapi 3.0 spec: %v", err)
|
|
}
|
|
|
|
fmt.Printf("Generated %s\n", openapi3OutPath)
|
|
}
|