fix(calendar): harden enterprise live paths
This commit is contained in:
parent
c1e22e5627
commit
e968c2f65f
@ -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)
|
||||
}
|
||||
|
||||
|
||||
@ -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 })
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
const (
|
||||
transparencyOpaque = "opaque"
|
||||
transparencyTransparent = "transparent"
|
||||
visibilityPublic = "public"
|
||||
sendUpdatesNone = "none"
|
||||
)
|
||||
|
||||
|
||||
@ -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,
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user