fix(calendar): harden enterprise live paths

This commit is contained in:
Peter Steinberger 2026-03-09 05:16:01 +00:00
parent c1e22e5627
commit e968c2f65f
9 changed files with 108 additions and 4 deletions

View File

@ -463,10 +463,10 @@ func (c *AuthKeepCmd) Run(ctx context.Context, _ *RootFlags) error {
return err
}
if err := os.WriteFile(destPath, data, 0o600); err != nil {
if err := writePrivateFile(destPath, data, 0o600); err != nil {
return fmt.Errorf("write service account: %w", err)
}
if err := os.WriteFile(genericPath, data, 0o600); err != nil {
if err := writePrivateFile(genericPath, data, 0o600); err != nil {
return fmt.Errorf("write service account: %w", err)
}

View File

@ -490,6 +490,12 @@ func TestCalendarCreateCmd_EventTypeWorkingLocation(t *testing.T) {
if gotEvent.WorkingLocationProperties == nil || gotEvent.WorkingLocationProperties.Type != "officeLocation" {
t.Fatalf("unexpected working location props: %#v", gotEvent.WorkingLocationProperties)
}
if gotEvent.Transparency != transparencyTransparent {
t.Fatalf("expected transparent working location, got %q", gotEvent.Transparency)
}
if gotEvent.Visibility != "public" {
t.Fatalf("expected public working location visibility, got %q", gotEvent.Visibility)
}
}
func TestCalendarUpdateCmd_EventTypeOOO(t *testing.T) {
@ -549,6 +555,59 @@ func TestCalendarUpdateCmd_EventTypeOOO(t *testing.T) {
}
}
func TestCalendarUpdateCmd_EventTypeWorkingLocationDefaults(t *testing.T) {
origNew := newCalendarService
t.Cleanup(func() { newCalendarService = origNew })
var gotEvent calendar.Event
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := strings.TrimPrefix(r.URL.Path, "/calendar/v3")
if r.Method == http.MethodPatch && path == "/calendars/cal@example.com/events/ev" {
_ = json.NewDecoder(r.Body).Decode(&gotEvent)
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"id": "ev",
})
return
}
http.NotFound(w, r)
}))
defer srv.Close()
svc, err := calendar.NewService(context.Background(),
option.WithoutAuthentication(),
option.WithHTTPClient(srv.Client()),
option.WithEndpoint(srv.URL+"/"),
)
if err != nil {
t.Fatalf("NewService: %v", err)
}
newCalendarService = func(context.Context, string) (*calendar.Service, error) { return svc, nil }
ctx := newCalendarJSONOutputContext(t, os.Stdout, os.Stderr)
cmd := &CalendarUpdateCmd{}
if err := runKong(t, cmd, []string{
"cal@example.com",
"ev",
"--event-type", "working-location",
"--working-location-type", "office",
"--working-office-label", "HQ",
}, ctx, &RootFlags{Account: "a@b.com"}); err != nil {
t.Fatalf("runKong: %v", err)
}
if gotEvent.EventType != eventTypeWorkingLocation {
t.Fatalf("expected workingLocation event type, got %q", gotEvent.EventType)
}
if gotEvent.Transparency != transparencyTransparent {
t.Fatalf("expected transparent working location, got %q", gotEvent.Transparency)
}
if gotEvent.Visibility != "public" {
t.Fatalf("expected public working location visibility, got %q", gotEvent.Visibility)
}
}
func TestCalendarUpdateCmd_SendUpdates(t *testing.T) {
origNew := newCalendarService
t.Cleanup(func() { newCalendarService = origNew })

View File

@ -133,9 +133,19 @@ func applyEventTypeTransparencyDefault(transparency, eventType string) string {
if transparency == "" && (eventType == eventTypeFocusTime || eventType == eventTypeOutOfOffice) {
return transparencyOpaque
}
if transparency == "" && eventType == eventTypeWorkingLocation {
return transparencyTransparent
}
return transparency
}
func applyEventTypeVisibilityDefault(visibility, eventType string) string {
if visibility == "" && eventType == eventTypeWorkingLocation {
return visibilityPublic
}
return visibility
}
func (c *CalendarCreateCmd) applyCreateEventType(event *calendar.Event, eventType string) error {
switch eventType {
case eventTypeDefault:
@ -646,6 +656,14 @@ func (c *CalendarUpdateCmd) applyEventTypeProperties(kctx *kong.Context, patch *
patch.Transparency = transparencyOpaque
changed = true
}
if eventTypeRequested && !flagProvided(kctx, "transparency") && eventType == eventTypeWorkingLocation {
patch.Transparency = transparencyTransparent
changed = true
}
if eventTypeRequested && !flagProvided(kctx, "visibility") && eventType == eventTypeWorkingLocation {
patch.Visibility = visibilityPublic
changed = true
}
switch eventType {
case eventTypeFocusTime:

View File

@ -74,7 +74,7 @@ func buildCalendarCreatePlan(c *CalendarCreateCmd) (*calendarCreatePlan, error)
Recurrence: buildRecurrence(c.Recurrence),
Reminders: reminders,
ColorId: colorID,
Visibility: visibility,
Visibility: applyEventTypeVisibilityDefault(visibility, eventType),
Transparency: applyEventTypeTransparencyDefault(transparency, eventType),
ConferenceData: buildConferenceData(c.WithMeet),
Attachments: buildAttachments(c.Attachments),

View File

@ -9,6 +9,7 @@ import (
const (
transparencyOpaque = "opaque"
transparencyTransparent = "transparent"
visibilityPublic = "public"
sendUpdatesNone = "none"
)

View File

@ -37,6 +37,8 @@ func (c *CalendarWorkingLocationCmd) Run(ctx context.Context, flags *RootFlags)
Start: &calendar.EventDateTime{Date: strings.TrimSpace(c.From)},
End: &calendar.EventDateTime{Date: strings.TrimSpace(c.To)},
EventType: eventTypeWorkingLocation,
Visibility: visibilityPublic,
Transparency: transparencyTransparent,
WorkingLocationProperties: props,
}

View File

@ -125,6 +125,12 @@ func TestCalendarWorkingLocation_RunJSON(t *testing.T) {
if gotEvent.EventType != "workingLocation" {
t.Fatalf("unexpected event type: %q", gotEvent.EventType)
}
if gotEvent.Transparency != transparencyTransparent {
t.Fatalf("unexpected transparency: %q", gotEvent.Transparency)
}
if gotEvent.Visibility != "public" {
t.Fatalf("unexpected visibility: %q", gotEvent.Visibility)
}
if gotEvent.Summary != "Working from HQ" {
t.Fatalf("unexpected summary: %q", gotEvent.Summary)
}

View File

@ -60,3 +60,19 @@ func createUserOutputFile(path string) (*os.File, string, error) {
DirMode: 0o700,
})
}
func writePrivateFile(path string, data []byte, mode os.FileMode) error {
if mode == 0 {
mode = 0o600
}
// Path is resolved by the caller. This helper is for app-owned/private outputs.
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) //nolint:gosec // caller controls target path semantics
if err != nil {
return err
}
if _, err := f.Write(data); err != nil {
_ = f.Close()
return err
}
return f.Close()
}

View File

@ -43,7 +43,9 @@ PY
run_required "calendar" "calendar delete event" gog calendar delete primary "$ev_id" --force >/dev/null
if ! skip "calendar-enterprise"; then
if is_consumer_account "$ACCOUNT"; then
echo "==> calendar enterprise event types (skipped; Workspace/enterprise only)"
elif ! skip "calendar-enterprise"; then
local focus_json focus_id ooo_json ooo_id wl_json wl_id
focus_json=$(gog calendar create primary --event-type focus-time --from "$START" --to "$END" --json 2>/dev/null || true)
if [ -n "$focus_json" ]; then