groupsync

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package groupsync decides what a directory synchronisation should do.

Bu paketin varlık sebebi tek bir soru: dizinden gelen bilgiye bakarak KİMİN yetkisi iptal edilmeli? Cevabı yanlış vermek, bir LDAP kesintisinde şirketin tamamını dışarıda bırakmak demek.

Karar mantığı BİLEREK saf: I/O yok, saat yok, veritabanı yok. Böylece "dizin çöktüğünde kimsenin yetkisi iptal edilmez" özelliği bir tablo testiyle milisaniyelerde ispatlanabiliyor — tartışılmak yerine.

Index

Constants

View Source
const (
	KeyEnabled            = "sync.enabled"
	KeyInterval           = "sync.interval"
	KeyGrace              = "sync.grace"
	KeyDryRun             = "sync.dry_run"
	KeyMaxZeroFraction    = "sync.max_zero_fraction"
	KeyMinZeroFloor       = "sync.min_zero_floor"
	KeyMaxUnknownFraction = "sync.max_unknown_fraction"
	KeyMaxRevokePerRun    = "sync.max_revoke_per_run"
)

Ayar anahtarları. Panelden yazılabilenler httpapi'deki beyaz listede.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Interval time.Duration
	Timeout  time.Duration
	DryRun   bool
	Limits   Limits
}

Config, Runner'ın ayarları.

type Directory

type Directory interface {
	Lookup(context.Context, auth.Identity) (ldap.LookupResult, error)
	Probe(context.Context) error
}

Directory, senkronizasyonun dizinden istediği tek şey.

⚠️ auth.GroupSource DEĞİL, ve bu bilinçli: ClaimGroups (OIDC claim kaynağı) bu soruları cevaplayamaz — bir claim ancak kullanıcı giriş yaparken gelir, "bu kişi hâlâ var mı" diye sorulamaz. ClaimGroups'u bu arayüze uydurmak, OIDC-only bir kurulumda sessizce herkesi iptal eden bir döngü başlatmak olurdu.

type InvalidSettingError

type InvalidSettingError struct{ Key, Got, Want string }

InvalidSettingError, saklanan bir ayarın okunamaması.

func (*InvalidSettingError) Error

func (e *InvalidSettingError) Error() string

type Limits

type Limits struct {
	// Grace, kullanıcı dizinde bulunamadıktan sonra iptal için beklenen
	// süre. Kısa bir çoğaltma gecikmesi ya da bakım penceresi yetkileri
	// silmesin diye.
	Grace time.Duration

	// MaxZeroFraction / MinZeroFloor, "kaç kişi sıfır SSO rolüne
	// düşerse bu bir kesintidir" eşiği. İkisi BİRLİKTE aşılmalı: küçük
	// kurumlarda oran tek kişiyle aşılır, büyüklerinde taban tek başına
	// anlamsız kalır.
	MaxZeroFraction float64
	MinZeroFloor    int

	// MaxUnknownFraction, dizinin cevaplayamadığı kullanıcı oranı için
	// tavan. Aşılırsa dizin sağlıklı değildir ve hiçbir karar verilmez.
	MaxUnknownFraction float64

	// MaxRevokePerRun, tek koşuda iptal edilebilecek kullanıcı sayısı.
	MaxRevokePerRun int
}

Limits, patlama yarıçapı tavanları.

func DefaultLimits

func DefaultLimits() Limits

DefaultLimits, makul ve MUHAFAZAKÂR başlangıç değerleri.

type Observation

type Observation struct {
	Username string

	// Presence, dizinin bu kullanıcı hakkında söylediği (üç değerli).
	Presence ldap.Presence

	// MappedRoles, dizindeki gruplarının karşılığı olan roller.
	// Presence != PresencePresent iken anlamsızdır.
	MappedRoles []string

	// MissingSince, bu kullanıcının İLK kez dizinde bulunamadığı an.
	// Sıfır ise şu ana kadar hep bulunmuş.
	MissingSince time.Time

	// ManualRoles, elle verilmiş rol sayısı. Senkronizasyon bunlara
	// DOKUNMAZ (bkz. göç 005) — ama rapor bunu ayrıca söylemeli, yoksa
	// operatör "iptal edildi" okuyup erişimin tamamen bittiğini sanar.
	ManualRoles int

	/*
	 * SSORoles, kullanıcının ŞU AN sahip olduğu SSO kaynaklı rol sayısı.
	 *
	 * ⚠️ TAVANLARIN DOĞRU SAYMASI İÇİN ŞART. Bu alan yokken "sıfıra
	 * düşecek" sayacı, dizinde bulunamayan HERKESİ sayıyordu — çoktan
	 * iptal edilmiş, yıllar önce ayrılmış kullanıcılar dahil. Onlar
	 * users tablosundan hiç çıkmıyor (DeleteUser oturum kaydı olanı
	 * reddediyor, sso_only hiç temizlenmiyor), yani her koşuda yeniden
	 * sayılıyorlardı.
	 *
	 * Sonucu ölçüldü: mezun sayısı MinZeroFloor'u ve MaxZeroFraction'ı
	 * geçtiği anda koşu iptal ediliyor — ve bir daha ASLA geçmiyor,
	 * çünkü sayı yalnızca büyüyor. Patlama yarıçapı koruması, kalıcı ve
	 * sessiz bir "hiç kimse iptal edilemez" moduna dönüşüyordu.
	 */
	SSORoles int
}

Observation, tek bir kullanıcı hakkında dizinden öğrenilenler.

type Plan

type Plan struct {
	// Apply, uygulanacak rol kümeleri.
	Apply []UserRoles

	// Hold, dizinde bulunamayan ama Grace süresi dolmamış kullanıcılar.
	Hold []string

	// Unknown, dizinin cevaplayamadığı kullanıcılar. Bunlara DOKUNULMAZ.
	Unknown []string

	// Abort boş değilse HİÇBİR ŞEY uygulanmaz ve sebebi budur.
	Abort string
}

Plan, bir senkronizasyon koşusunda ne yapılacağı.

func BuildPlan

func BuildPlan(now time.Time, obs []Observation, limits Limits) Plan

BuildPlan, gözlemlerden bir koşu planı çıkarır.

⚠️ EN ÖNEMLİ TASARIM KARARI: "dizinde yok" ile "dizinde var ama artık hiçbir gruba üye değil" AYNI sayaçta toplanıyor.

Sebebi somut: yarım geri yüklenmiş ya da eksik çoğaltılmış bir dizin kullanıcı aramasını düzgün cevaplar, grup aramasını BOŞ cevaplar. Kişi bazında bakan bir mantık bunu meşru bir iptal olarak okur ve herkesi siler. Yalnızca toplam sayaç bunu görebilir.

type Report

type Report struct {
	Outcome string
	Reason  string

	Considered, Present, Absent, Unknown, Revoked, RolesChanged int

	// KeptManual, iptal edilmiş ama elle verilmiş rolleri DURAN
	// kullanıcılar. Ayrı raporlanıyor çünkü "iptal edildi" okuyup
	// erişimin tamamen bittiğini sanmak kolay.
	KeptManual []string

	/*
	 * StampErrors, yazılamayan varlık damgası sayısı.
	 *
	 * ⚠️ "ok" ÇIKTISI TAM OLMAYABİLİR ve bunu söylemek gerekiyor.
	 * Yazılamayan bir damga, bir sonraki koşunun zamanı yanlış
	 * okuması demek: grace penceresi baştan başlar (iptal hiç
	 * gelmez) ya da dizinde duran biri doğrulanmamış sayılır.
	 * Sıfırdan büyükse koşu "bir şey yapmadım" değil, "bir kısmını
	 * kaydedemedim" demektir.
	 */
	StampErrors int
}

Report, bir koşunun sonucu.

type Runner

type Runner struct {
	// contains filtered or unexported fields
}

Runner, periyodik senkronizasyonu yürütür.

func NewRunner

func NewRunner(db *store.Store, open func(context.Context) (Directory, error),
	cfg Config, logger *slog.Logger) *Runner

func (*Runner) RunOnce

func (r *Runner) RunOnce(ctx context.Context, trigger string) (Report, error)

RunOnce, tek bir senkronizasyon koşusu yapar.

func (*Runner) Start

func (r *Runner) Start(ctx context.Context)

Start, periyodik döngüyü çalıştırır ve ctx bitene kadar döner.

func (*Runner) UseSettings

func (r *Runner) UseSettings(fn func(context.Context) (Settings, error))

UseSettings, ayarları her koşuda yeniden okuyan kaynağı bağlar. Start'tan ÖNCE çağrılmalı.

type Settings

type Settings struct {
	Enabled bool
	Config  Config

	/*
	 * IgnoredKeys, ayarlar tablosunda duran ama ARTIK OKUNMAYAN
	 * anahtarlar (patlama yarıçapı tavanları; gerekçe LoadSettings'te).
	 *
	 * ⚠️ Çağıranın bunu bildirmesi ŞART. Bir değeri yok saymak ile
	 * yok saydığını söylemek arasındaki fark, operatörün yürürlükte
	 * sandığı bir ayarla çalışıp çalışmadığıdır.
	 */
	IgnoredKeys []string
}

Settings, bir koşunun ayarları ve açık olup olmadığı.

func LoadSettings

func LoadSettings(ctx context.Context, db *store.Store, fallback Settings) (Settings, error)

* LoadSettings, saklanan ayarları okur; olmayanlar için fallback. * * ⚠️ HATALI DEĞER VARSAYILANA DÜŞMEZ, HATA DÖNER. Bir operatörün * "max_revoke_per_run: 2O" (harf O) yazması, sessizce varsayılana * dönmekle sonuçlansaydı, patlama yarıçapı tavanı sandığından başka bir * değerde çalışırdı — ve bu, yetki iptal eden bir döngüde tam olarak * fark edilmemesi en pahalı şey.

type UserRoles

type UserRoles struct {
	Username string
	Roles    []string

	// Revoking, bu uygulamanın kullanıcıyı SIFIR SSO rolüne düşürdüğünü
	// söyler — rapor ve denetim için.
	Revoking bool

	// ManualRoles, iptalden SONRA elinde kalan elle verilmiş rol sayısı.
	ManualRoles int
}

UserRoles, bir kullanıcıya uygulanacak yeni SSO rol kümesi.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL