Skip to content

Commit f9e1cee

Browse files
committed
update location of update.xml
1 parent 905d8d9 commit f9e1cee

File tree

2 files changed

+34
-21
lines changed

2 files changed

+34
-21
lines changed

server/cmd/api/api/chromium.go

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,26 +158,6 @@ func (s *ApiService) UploadExtensionsAndRestart(ctx context.Context, request oap
158158
return oapi.UploadExtensionsAndRestart500JSONResponse{InternalErrorJSONResponse: oapi.InternalErrorJSONResponse{Message: "failed to chown extension dir"}}, nil
159159
}
160160

161-
// Check if the zip contains update.xml and .crx files (for policy-installed extensions)
162-
// If they exist, they'll be extracted; if not, they need to be generated separately
163-
updateXMLPath := filepath.Join(dest, "update.xml")
164-
crxPath := filepath.Join(dest, p.name+".crx")
165-
hasUpdateXML := false
166-
hasCRX := false
167-
168-
if _, err := os.Stat(updateXMLPath); err == nil {
169-
hasUpdateXML = true
170-
log.Info("found update.xml in extension zip", "name", p.name)
171-
}
172-
if _, err := os.Stat(crxPath); err == nil {
173-
hasCRX = true
174-
log.Info("found .crx file in extension zip", "name", p.name)
175-
}
176-
177-
if !hasUpdateXML || !hasCRX {
178-
log.Info("extension zip missing update.xml or .crx - these files should be included for policy-installed extensions", "name", p.name, "hasUpdateXML", hasUpdateXML, "hasCRX", hasCRX)
179-
}
180-
181161
log.Info("installed extension", "name", p.name)
182162
}
183163

@@ -199,6 +179,38 @@ func (s *ApiService) UploadExtensionsAndRestart(ctx context.Context, request oap
199179

200180
if requiresEntPolicy {
201181
log.Info("extension requires enterprise policy", "name", p.name)
182+
183+
// Validate that update.xml and .crx files are present for policy-installed extensions
184+
// These files are required for ExtensionInstallForcelist to work
185+
updateXMLPath := filepath.Join(extensionPath, "update.xml")
186+
hasUpdateXML := false
187+
hasCRX := false
188+
189+
if _, err := os.Stat(updateXMLPath); err == nil {
190+
hasUpdateXML = true
191+
log.Info("found update.xml in extension zip", "name", p.name)
192+
}
193+
194+
// Look for any .crx file in the directory
195+
entries, err := os.ReadDir(extensionPath)
196+
if err == nil {
197+
for _, entry := range entries {
198+
if !entry.IsDir() && filepath.Ext(entry.Name()) == ".crx" {
199+
hasCRX = true
200+
log.Info("found .crx file in extension zip", "name", p.name, "crx_file", entry.Name())
201+
break
202+
}
203+
}
204+
}
205+
206+
// Fail if policy extension is missing required files
207+
if !hasUpdateXML || !hasCRX {
208+
return oapi.UploadExtensionsAndRestart400JSONResponse{
209+
BadRequestErrorJSONResponse: oapi.BadRequestErrorJSONResponse{
210+
Message: fmt.Sprintf("extension %s requires enterprise policy (ExtensionInstallForcelist) but is missing required files: update.xml (present: %v), .crx file (present: %v). These files are required for Chrome to install the extension.", p.name, hasUpdateXML, hasCRX),
211+
},
212+
}, nil
213+
}
202214
} else {
203215
// Only add --load-extension flags for non-policy extensions
204216
pathsNeedingFlags = append(pathsNeedingFlags, extensionPath)

server/lib/policy/policy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ func (p *Policy) AddExtension(extensionID, extensionPath string, requiresEnterpr
122122
}
123123

124124
// Add the specific extension
125+
// Use extension-specific update URL to support multiple policy-installed extensions
125126
setting := ExtensionSetting{
126-
UpdateUrl: "http://127.0.0.1:10001/update.xml",
127+
UpdateUrl: fmt.Sprintf("http://127.0.0.1:10001/extensions/%s/update.xml", extensionID),
127128
}
128129

129130
// If the extension requires enterprise policy (like webRequestBlocking),

0 commit comments

Comments
 (0)