package repository import ( "database/sql" "github.com/wmms/wmms/internal/model" "github.com/wmms/wmms/pkg/database" ) // Authorization is evaluated from current database grants and enabled roles on // every call, so role changes and grant revocation do not wait for JWT expiry. func (r *OrganizationRepository) ListAccessible(userID int64) (*model.OrganizationAccess, error) { rows, err := database.DB.Query(`SELECT o.id,o.code,o.name,o.status,o.default_timezone,o.created_at,o.updated_at, COALESCE(g.is_default,0) FROM organizations o LEFT JOIN user_organizations g ON g.organization_id=o.id AND g.user_id=? WHERE o.status='active' AND (g.user_id IS NOT NULL OR EXISTS( SELECT 1 FROM user_roles ur JOIN roles r ON r.id=ur.role_id WHERE ur.user_id=? AND r.code='super_admin' AND r.enabled=1)) ORDER BY o.id`, userID, userID) if err != nil { return nil, err } defer rows.Close() access := &model.OrganizationAccess{Organizations: make([]model.Organization, 0)} for rows.Next() { var item model.Organization var isDefault bool if err := rows.Scan(&item.ID, &item.Code, &item.Name, &item.Status, &item.DefaultTimezone, &item.CreatedAt, &item.UpdatedAt, &isDefault); err != nil { return nil, err } access.Organizations = append(access.Organizations, item) if isDefault { id := item.ID access.DefaultOrganizationID = &id } } return access, rows.Err() } func (r *OrganizationRepository) CanAccess(userID, organizationID int64) (bool, error) { var allowed bool err := database.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM organizations o WHERE o.id=? AND o.status='active' AND (EXISTS(SELECT 1 FROM user_organizations g WHERE g.user_id=? AND g.organization_id=o.id) OR EXISTS(SELECT 1 FROM user_roles ur JOIN roles r ON r.id=ur.role_id WHERE ur.user_id=? AND r.code='super_admin' AND r.enabled=1)))`, organizationID, userID, userID).Scan(&allowed) if err == sql.ErrNoRows { return false, nil } return allowed, err }