Skip to content

Commit

Permalink
Introduce a --enterprise flag (#5340)
Browse files Browse the repository at this point in the history
  • Loading branch information
willdurand authored Jun 14, 2024
1 parent 7cb36f3 commit 625435c
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 7 deletions.
11 changes: 8 additions & 3 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,12 @@ <h2 id="web-extensions-%2F-manifest.json" tabindex="-1">Web Extensions / manifes
<tr>
<td><code>APPLICATIONS_INVALID</code></td>
<td>error</td>
<td>The <code>applications</code> property is no longer accepted in Manifest Version 3 and above.</td>
<td>The <code>applications</code> property is no longer accepted in Manifest Version 3 and above</td>
</tr>
<tr>
<td><code>VERSION_FORMAT_DEPRECATED</code></td>
<td>warning</td>
<td>The version string should be simplified.</td>
<td>The version string should be simplified</td>
</tr>
<tr>
<td><code>VERSION_FORMAT_INVALID</code></td>
Expand All @@ -596,7 +596,12 @@ <h2 id="web-extensions-%2F-manifest.json" tabindex="-1">Web Extensions / manifes
<tr>
<td><code>ADMIN_INSTALL_ONLY_PROP_RESERVED</code></td>
<td>error</td>
<td>The &quot;admin_install_only&quot; property is reserved and can only be used in enterprise add-ons</td>
<td>The <code>browser_specific_settings.gecko.admin_install_only</code> property is reserved and can only be used in enterprise add-ons</td>
</tr>
<tr>
<td><code>ADMIN_INSTALL_ONLY_REQUIRED</code></td>
<td>error</td>
<td>The <code>browser_specific_settings.gecko.admin_install_only</code> property must be set to &quot;true&quot; in an enterprise add-on</td>
</tr>
</tbody>
</table>
Expand Down
7 changes: 4 additions & 3 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,13 @@ Rules are sorted by severity.
| `EXTENSION_ID_REQUIRED` | error | The extension ID is mandatory for Manifest Version 3 (and above) extensions |
| `HIDDEN_NO_ACTION` | error | The `hidden` and `browser_action`/`page_action` (or `action`) properties are mutually exclusive |
| `APPLICATIONS_DEPRECATED` | warning | The `applications` property in the manifest is deprecated and will no longer be accepted in Manifest Version 3 and above. Use `browser_specific_settings` instead. |
| `APPLICATIONS_INVALID` | error | The `applications` property is no longer accepted in Manifest Version 3 and above. |
| `VERSION_FORMAT_DEPRECATED` | warning | The version string should be simplified. |
| `APPLICATIONS_INVALID` | error | The `applications` property is no longer accepted in Manifest Version 3 and above |
| `VERSION_FORMAT_DEPRECATED` | warning | The version string should be simplified |
| `VERSION_FORMAT_INVALID` | error | The version string is not valid because its format is too complex. |
| `MANIFEST_V3_FIREFOX_ANDROID_LIMITATIONS` | warning | The extension is marked as compatible with a Firefox for Android version that doesn't fully support Manifest Version 3 |
| `INCOGNITO_SPLIT_UNSUPPORTED` | warning | The incognito "split" value is unsupported in Firefox |
| `ADMIN_INSTALL_ONLY_PROP_RESERVED` | error | The "admin_install_only" property is reserved and can only be used in enterprise add-ons |
| `ADMIN_INSTALL_ONLY_PROP_RESERVED` | error | The `browser_specific_settings.gecko.admin_install_only` property is reserved and can only be used in enterprise add-ons |
| `ADMIN_INSTALL_ONLY_REQUIRED` | error | The `browser_specific_settings.gecko.admin_install_only` property must be set to "true" in an enterprise add-on |

### Static Theme / manifest.json

Expand Down
2 changes: 2 additions & 0 deletions src/linter.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ export default class Linter {
),
selfHosted: this.config.selfHosted,
schemaValidatorOptions: {
enterprise: this.config.enterprise,
privileged: this.config.privileged,
minManifestVersion: this.config.minManifestVersion,
maxManifestVersion: this.config.maxManifestVersion,
Expand Down Expand Up @@ -446,6 +447,7 @@ export default class Linter {
// list of disabled rules for js scanner
disabledRules: this.config.disableLinterRules,
existingFiles: this.io.files,
enterprise: this.config.enterprise,
privileged: this.config.privileged,
});

Expand Down
9 changes: 9 additions & 0 deletions src/messages/manifestjson.js
Original file line number Diff line number Diff line change
Expand Up @@ -840,3 +840,12 @@ export const ADMIN_INSTALL_ONLY_PROP_RESERVED = {
only be used in enterprise add-ons.`),
file: MANIFEST_JSON,
};

export const ADMIN_INSTALL_ONLY_REQUIRED = {
code: 'ADMIN_INSTALL_ONLY_REQUIRED',
message: i18n._(`"/browser_specific_settings/gecko/admin_install_only"
property must be set to "true"."`),
description: i18n._(`The "admin_install_only" property must be set to "true"
in an enterprise add-on.`),
file: MANIFEST_JSON,
};
14 changes: 13 additions & 1 deletion src/parsers/manifestjson.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export default class ManifestJSONParser extends JSONParser {

this.io = io;
this.isAlreadySigned = isAlreadySigned;
this.isEnterpriseAddon = this.schemaValidatorOptions?.enterprise ?? false;
this.isPrivilegedAddon = this.schemaValidatorOptions?.privileged ?? false;
this.restrictedPermissions = restrictedPermissions;
this._validate();
Expand Down Expand Up @@ -520,7 +521,18 @@ export default class ManifestJSONParser extends JSONParser {
};
}

if (
// We only want `admin_install_only` to be set in `bss` when `--enterprise`
// is set, otherwise we don't want the flag _at all_, which includes both
// `bss` and `applications`.
if (this.isEnterpriseAddon) {
if (
this.parsedJSON.browser_specific_settings?.gecko?.admin_install_only !==
true
) {
this.collector.addError(messages.ADMIN_INSTALL_ONLY_REQUIRED);
this.isValid = false;
}
} else if (
typeof this.parsedJSON.applications?.gecko?.admin_install_only !==
'undefined'
) {
Expand Down
1 change: 1 addition & 0 deletions src/scanners/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default class BaseScanner {
* @property {import('../parsers/manifestjson').Metadata} addonMetadata
* @property {import('../collector').default} collector
* @property {string[]} disabledRules
* @property {boolean} enterprise
* @property {string[]} existingFiles
* @property {boolean} privileged
*
Expand Down
5 changes: 5 additions & 0 deletions src/yargs-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ const options = {
type: 'boolean',
default: false,
},
enterprise: {
describe: 'Treat the input file (or directory) as an enterprise extension',
type: 'boolean',
default: false,
},
privileged: {
describe: 'Treat the input file (or directory) as a privileged extension',
type: 'boolean',
Expand Down
120 changes: 120 additions & 0 deletions tests/unit/parsers/test.manifestjson.js
Original file line number Diff line number Diff line change
Expand Up @@ -5563,5 +5563,125 @@ describe('ManifestJSONParser', () => {
]);
}
);

it('emits an error when the enterprise option is false', () => {
const linter = new Linter({ _: ['bar'] });

const manifestJSONParser = new ManifestJSONParser(
JSON.stringify({
manifest_version: 2,
name: 'some name',
version: '1',
browser_specific_settings: {
gecko: { id: '@test-id', admin_install_only: true },
},
}),
linter.collector,
{ schemaValidatorOptions: { enterprise: false } }
);

expect(manifestJSONParser.isValid).toEqual(false);
expect(linter.collector.warnings).toEqual([]);
expect(linter.collector.errors).toEqual([
expect.objectContaining(messages.ADMIN_INSTALL_ONLY_PROP_RESERVED),
]);
});

it('does not emit an error when the enterprise option is passed', () => {
const linter = new Linter({ _: ['bar'] });

const manifestJSONParser = new ManifestJSONParser(
JSON.stringify({
manifest_version: 2,
name: 'some name',
version: '1',
browser_specific_settings: {
gecko: { id: '@test-id', admin_install_only: true },
},
}),
linter.collector,
{ schemaValidatorOptions: { enterprise: true } }
);

expect(manifestJSONParser.isValid).toEqual(true);
expect(linter.collector.warnings).toEqual([]);
expect(linter.collector.errors).toEqual([]);
});

it('emits an error when the enterprise option is passed but the value is false', () => {
const linter = new Linter({ _: ['bar'] });

const manifestJSONParser = new ManifestJSONParser(
JSON.stringify({
manifest_version: 2,
name: 'some name',
version: '1',
browser_specific_settings: {
gecko: { id: '@test-id', admin_install_only: false },
},
}),
linter.collector,
{ schemaValidatorOptions: { enterprise: true } }
);

expect(manifestJSONParser.isValid).toEqual(false);
expect(linter.collector.warnings).toEqual([]);
expect(linter.collector.errors).toEqual([
expect.objectContaining(messages.ADMIN_INSTALL_ONLY_REQUIRED),
]);
});

it('emits an error when the enterprise option is passed and the flag is set in applications', () => {
const linter = new Linter({ _: ['bar'] });

const manifestJSONParser = new ManifestJSONParser(
JSON.stringify({
manifest_version: 2,
name: 'some name',
version: '1',
applications: {
gecko: { id: '@test-id', admin_install_only: true },
},
}),
linter.collector,
{ schemaValidatorOptions: { enterprise: true } }
);

expect(manifestJSONParser.isValid).toEqual(false);
expect(linter.collector.warnings).toEqual([
expect.objectContaining(messages.APPLICATIONS_DEPRECATED),
]);
expect(linter.collector.errors).toEqual([
expect.objectContaining(messages.ADMIN_INSTALL_ONLY_REQUIRED),
]);
});

it('emits an error when the enterprise option is passed, the flag is set in applications, and bss is defined', () => {
const linter = new Linter({ _: ['bar'] });

const manifestJSONParser = new ManifestJSONParser(
JSON.stringify({
manifest_version: 2,
name: 'some name',
version: '1',
browser_specific_settings: {
gecko: { id: '@test-id' },
},
applications: {
gecko: { admin_install_only: true },
},
}),
linter.collector,
{ schemaValidatorOptions: { enterprise: true } }
);

expect(manifestJSONParser.isValid).toEqual(false);
expect(linter.collector.warnings).toEqual([
expect.objectContaining(messages.IGNORED_APPLICATIONS_PROPERTY),
]);
expect(linter.collector.errors).toEqual([
expect.objectContaining(messages.ADMIN_INSTALL_ONLY_REQUIRED),
]);
});
});
});

0 comments on commit 625435c

Please sign in to comment.