mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-18 21:27:51 +00:00
Make resin os configure
safe with device keys for all ResinOS versions
This commit is contained in:
parent
8e95757f47
commit
a8f1d16b26
@ -15,7 +15,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
var authenticateWithApplicationKey, authenticateWithDeviceKey, commandOptions, generateApplicationConfig, generateBaseConfig, generateDeviceConfig;
|
||||
var commandOptions;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
@ -210,14 +210,15 @@ exports.generate = {
|
||||
],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, deviceConfig, form, prettyjson, resin, writeFileAsync;
|
||||
var Promise, _, deviceConfig, form, generateApplicationConfig, generateDeviceConfig, prettyjson, ref, resin, writeFileAsync;
|
||||
Promise = require('bluebird');
|
||||
writeFileAsync = Promise.promisify(require('fs').writeFile);
|
||||
deviceConfig = require('resin-device-config');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
_ = require('lodash');
|
||||
form = require('resin-cli-form');
|
||||
deviceConfig = require('resin-device-config');
|
||||
prettyjson = require('prettyjson');
|
||||
ref = require('../utils/config'), generateDeviceConfig = ref.generateDeviceConfig, generateApplicationConfig = ref.generateApplicationConfig;
|
||||
if ((options.device == null) && (options.application == null)) {
|
||||
throw new Error('You have to pass either a device or an application.\n\nSee the help page for examples:\n\n $ resin help config generate');
|
||||
}
|
||||
@ -243,84 +244,3 @@ exports.generate = {
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
generateBaseConfig = function(application, options) {
|
||||
var Promise, deviceConfig, resin;
|
||||
Promise = require('bluebird');
|
||||
deviceConfig = require('resin-device-config');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise.props({
|
||||
userId: resin.auth.getUserId(),
|
||||
username: resin.auth.whoami(),
|
||||
apiUrl: resin.settings.get('apiUrl'),
|
||||
vpnUrl: resin.settings.get('vpnUrl'),
|
||||
registryUrl: resin.settings.get('registryUrl'),
|
||||
deltaUrl: resin.settings.get('deltaUrl'),
|
||||
pubNubKeys: resin.models.config.getPubNubKeys(),
|
||||
mixpanelToken: resin.models.config.getMixpanelToken()
|
||||
}).then(function(results) {
|
||||
return deviceConfig.generate({
|
||||
application: application,
|
||||
user: {
|
||||
id: results.userId,
|
||||
username: results.username
|
||||
},
|
||||
endpoints: {
|
||||
api: results.apiUrl,
|
||||
vpn: results.vpnUrl,
|
||||
registry: results.registryUrl,
|
||||
delta: results.deltaUrl
|
||||
},
|
||||
pubnub: results.pubNubKeys,
|
||||
mixpanel: {
|
||||
token: results.mixpanelToken
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
generateApplicationConfig = function(application, options) {
|
||||
return generateBaseConfig(application).tap(function(config) {
|
||||
return authenticateWithApplicationKey(config, application.id);
|
||||
});
|
||||
};
|
||||
|
||||
generateDeviceConfig = function(device, deviceApiKey, options) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.application.get(device.application_name).then(function(application) {
|
||||
return generateBaseConfig(application, options).tap(function(config) {
|
||||
if (deviceApiKey != null) {
|
||||
return authenticateWithDeviceKey(config, device.uuid, deviceApiKey);
|
||||
} else {
|
||||
return authenticateWithApplicationKey(config, application.id);
|
||||
}
|
||||
});
|
||||
}).then(function(config) {
|
||||
config.registered_at = Math.floor(Date.now() / 1000);
|
||||
config.deviceId = device.id;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
authenticateWithApplicationKey = function(config, applicationNameOrId) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.application.generateApiKey(applicationNameOrId).then(function(apiKey) {
|
||||
config.apiKey = apiKey;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
authenticateWithDeviceKey = function(config, uuid, customDeviceApiKey) {
|
||||
var Promise, resin;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise["try"](function() {
|
||||
return customDeviceApiKey || resin.models.device.generateDeviceKey(uuid);
|
||||
}).then(function(deviceApiKey) {
|
||||
config.uuid = uuid;
|
||||
config.deviceApiKey = deviceApiKey;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
@ -200,23 +200,26 @@ exports.configure = {
|
||||
}
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, fs, helpers, init, readFileAsync, ref, resin;
|
||||
var Promise, fs, generateDeviceConfig, helpers, init, readFileAsync, resin;
|
||||
fs = require('fs');
|
||||
Promise = require('bluebird');
|
||||
readFileAsync = Promise.promisify(fs.readFile);
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
init = require('resin-device-init');
|
||||
helpers = require('../utils/helpers');
|
||||
generateDeviceConfig = require('../utils/config').generateDeviceConfig;
|
||||
console.info('Configuring operating system image');
|
||||
return Promise.all([
|
||||
resin.models.device.get(params.uuid).then(function(device) {
|
||||
return resin.models.device.get(params.uuid).then(function(device) {
|
||||
return Promise["try"](function() {
|
||||
if (options.config) {
|
||||
return readFileAsync(options.config, 'utf8').then(JSON.parse);
|
||||
}
|
||||
return buildConfig(params.image, device.device_type, options.advanced);
|
||||
}), Promise.resolve((ref = params.deviceApiKey) != null ? ref : resin.models.device.generateDeviceKey(params.uuid))
|
||||
]).spread(function(answers, deviceApiKey) {
|
||||
return init.configure(params.image, params.uuid, deviceApiKey, answers);
|
||||
}).then(function(answers) {
|
||||
return generateDeviceConfig(device, params.deviceApiKey, answers).then(function(config) {
|
||||
return init.configure(params.image, device.device_type, config, answers);
|
||||
});
|
||||
});
|
||||
}).then(helpers.osProgressHandler).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
99
build/utils/config.js
Normal file
99
build/utils/config.js
Normal file
@ -0,0 +1,99 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
var authenticateWithApplicationKey, authenticateWithDeviceKey;
|
||||
|
||||
exports.generateBaseConfig = function(application, options) {
|
||||
var Promise, deviceConfig, resin;
|
||||
Promise = require('bluebird');
|
||||
deviceConfig = require('resin-device-config');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise.props({
|
||||
userId: resin.auth.getUserId(),
|
||||
username: resin.auth.whoami(),
|
||||
apiUrl: resin.settings.get('apiUrl'),
|
||||
vpnUrl: resin.settings.get('vpnUrl'),
|
||||
registryUrl: resin.settings.get('registryUrl'),
|
||||
deltaUrl: resin.settings.get('deltaUrl'),
|
||||
pubNubKeys: resin.models.config.getPubNubKeys(),
|
||||
mixpanelToken: resin.models.config.getMixpanelToken()
|
||||
}).then(function(results) {
|
||||
return deviceConfig.generate({
|
||||
application: application,
|
||||
user: {
|
||||
id: results.userId,
|
||||
username: results.username
|
||||
},
|
||||
endpoints: {
|
||||
api: results.apiUrl,
|
||||
vpn: results.vpnUrl,
|
||||
registry: results.registryUrl,
|
||||
delta: results.deltaUrl
|
||||
},
|
||||
pubnub: results.pubNubKeys,
|
||||
mixpanel: {
|
||||
token: results.mixpanelToken
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.generateApplicationConfig = function(application, options) {
|
||||
return exports.generateBaseConfig(application).tap(function(config) {
|
||||
return authenticateWithApplicationKey(config, application.id);
|
||||
});
|
||||
};
|
||||
|
||||
exports.generateDeviceConfig = function(device, deviceApiKey, options) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.application.get(device.application_name).then(function(application) {
|
||||
return exports.generateBaseConfig(application, options).tap(function(config) {
|
||||
if (deviceApiKey != null) {
|
||||
return authenticateWithDeviceKey(config, device.uuid, deviceApiKey);
|
||||
} else {
|
||||
return authenticateWithApplicationKey(config, application.id);
|
||||
}
|
||||
});
|
||||
}).then(function(config) {
|
||||
config.registered_at = Math.floor(Date.now() / 1000);
|
||||
config.deviceId = device.id;
|
||||
config.uuid = device.uuid;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
authenticateWithApplicationKey = function(config, applicationNameOrId) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.application.generateApiKey(applicationNameOrId).then(function(apiKey) {
|
||||
config.apiKey = apiKey;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
authenticateWithDeviceKey = function(config, uuid, customDeviceApiKey) {
|
||||
var Promise, resin;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise["try"](function() {
|
||||
return customDeviceApiKey || resin.models.device.generateDeviceKey(uuid);
|
||||
}).then(function(deviceApiKey) {
|
||||
config.deviceApiKey = deviceApiKey;
|
||||
return config;
|
||||
});
|
||||
};
|
@ -254,6 +254,7 @@ exports.generate =
|
||||
form = require('resin-cli-form')
|
||||
deviceConfig = require('resin-device-config')
|
||||
prettyjson = require('prettyjson')
|
||||
{ generateDeviceConfig, generateApplicationConfig } = require('../utils/config')
|
||||
|
||||
if not options.device? and not options.application?
|
||||
throw new Error '''
|
||||
@ -284,77 +285,3 @@ exports.generate =
|
||||
|
||||
console.log(prettyjson.render(config))
|
||||
.nodeify(done)
|
||||
|
||||
generateBaseConfig = (application, options) ->
|
||||
Promise = require('bluebird')
|
||||
deviceConfig = require('resin-device-config')
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
|
||||
Promise.props
|
||||
userId: resin.auth.getUserId()
|
||||
username: resin.auth.whoami()
|
||||
apiUrl: resin.settings.get('apiUrl')
|
||||
vpnUrl: resin.settings.get('vpnUrl')
|
||||
registryUrl: resin.settings.get('registryUrl')
|
||||
deltaUrl: resin.settings.get('deltaUrl')
|
||||
pubNubKeys: resin.models.config.getPubNubKeys()
|
||||
mixpanelToken: resin.models.config.getMixpanelToken()
|
||||
.then (results) ->
|
||||
deviceConfig.generate
|
||||
application: application
|
||||
user:
|
||||
id: results.userId
|
||||
username: results.username
|
||||
endpoints:
|
||||
api: results.apiUrl
|
||||
vpn: results.vpnUrl
|
||||
registry: results.registryUrl
|
||||
delta: results.deltaUrl
|
||||
pubnub: results.pubNubKeys
|
||||
mixpanel:
|
||||
token: results.mixpanelToken
|
||||
|
||||
generateApplicationConfig = (application, options) ->
|
||||
generateBaseConfig(application)
|
||||
.tap (config) ->
|
||||
authenticateWithApplicationKey(config, application.id)
|
||||
|
||||
generateDeviceConfig = (device, deviceApiKey, options) ->
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
|
||||
resin.models.application.get(device.application_name)
|
||||
.then (application) ->
|
||||
generateBaseConfig(application, options)
|
||||
.tap (config) ->
|
||||
# Device API keys are only safe for ResinOS 2.0.3+. We could somehow obtain
|
||||
# the expected version for this config and generate one when we know it's safe,
|
||||
# but instead for now we fall back to app keys unsless the user has explicitly opted in.
|
||||
if deviceApiKey?
|
||||
authenticateWithDeviceKey(config, device.uuid, deviceApiKey)
|
||||
else
|
||||
authenticateWithApplicationKey(config, application.id)
|
||||
.then (config) ->
|
||||
# Associate a device, to prevent the supervisor
|
||||
# from creating another one on its own.
|
||||
config.registered_at = Math.floor(Date.now() / 1000)
|
||||
config.deviceId = device.id
|
||||
|
||||
return config
|
||||
|
||||
authenticateWithApplicationKey = (config, applicationNameOrId) ->
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
resin.models.application.generateApiKey(applicationNameOrId)
|
||||
.then (apiKey) ->
|
||||
config.apiKey = apiKey
|
||||
return config
|
||||
|
||||
authenticateWithDeviceKey = (config, uuid, customDeviceApiKey) ->
|
||||
Promise = require('bluebird')
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
|
||||
Promise.try ->
|
||||
customDeviceApiKey || resin.models.device.generateDeviceKey(uuid)
|
||||
.then (deviceApiKey) ->
|
||||
config.uuid = uuid
|
||||
config.deviceApiKey = deviceApiKey
|
||||
return config
|
||||
|
@ -222,20 +222,20 @@ exports.configure =
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
init = require('resin-device-init')
|
||||
helpers = require('../utils/helpers')
|
||||
{ generateDeviceConfig } = require('../utils/config')
|
||||
|
||||
console.info('Configuring operating system image')
|
||||
Promise.all [
|
||||
resin.models.device.get(params.uuid)
|
||||
.then (device) ->
|
||||
Promise.try ->
|
||||
if options.config
|
||||
return readFileAsync(options.config, 'utf8')
|
||||
.then(JSON.parse)
|
||||
return buildConfig(params.image, device.device_type, options.advanced)
|
||||
,
|
||||
Promise.resolve(params.deviceApiKey ? resin.models.device.generateDeviceKey(params.uuid))
|
||||
]
|
||||
.spread (answers, deviceApiKey) ->
|
||||
init.configure(params.image, params.uuid, deviceApiKey, answers)
|
||||
.then (answers) ->
|
||||
generateDeviceConfig(device, params.deviceApiKey, answers)
|
||||
.then (config) ->
|
||||
init.configure(params.image, device.device_type, config, answers)
|
||||
.then(helpers.osProgressHandler)
|
||||
.nodeify(done)
|
||||
|
||||
|
89
lib/utils/config.coffee
Normal file
89
lib/utils/config.coffee
Normal file
@ -0,0 +1,89 @@
|
||||
###
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
###
|
||||
|
||||
exports.generateBaseConfig = (application, options) ->
|
||||
Promise = require('bluebird')
|
||||
deviceConfig = require('resin-device-config')
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
|
||||
Promise.props
|
||||
userId: resin.auth.getUserId()
|
||||
username: resin.auth.whoami()
|
||||
apiUrl: resin.settings.get('apiUrl')
|
||||
vpnUrl: resin.settings.get('vpnUrl')
|
||||
registryUrl: resin.settings.get('registryUrl')
|
||||
deltaUrl: resin.settings.get('deltaUrl')
|
||||
pubNubKeys: resin.models.config.getPubNubKeys()
|
||||
mixpanelToken: resin.models.config.getMixpanelToken()
|
||||
.then (results) ->
|
||||
deviceConfig.generate
|
||||
application: application
|
||||
user:
|
||||
id: results.userId
|
||||
username: results.username
|
||||
endpoints:
|
||||
api: results.apiUrl
|
||||
vpn: results.vpnUrl
|
||||
registry: results.registryUrl
|
||||
delta: results.deltaUrl
|
||||
pubnub: results.pubNubKeys
|
||||
mixpanel:
|
||||
token: results.mixpanelToken
|
||||
|
||||
exports.generateApplicationConfig = (application, options) ->
|
||||
exports.generateBaseConfig(application)
|
||||
.tap (config) ->
|
||||
authenticateWithApplicationKey(config, application.id)
|
||||
|
||||
exports.generateDeviceConfig = (device, deviceApiKey, options) ->
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
|
||||
resin.models.application.get(device.application_name)
|
||||
.then (application) ->
|
||||
exports.generateBaseConfig(application, options)
|
||||
.tap (config) ->
|
||||
# Device API keys are only safe for ResinOS 2.0.3+. We could somehow obtain
|
||||
# the expected version for this config and generate one when we know it's safe,
|
||||
# but instead for now we fall back to app keys unless the user has explicitly opted in.
|
||||
if deviceApiKey?
|
||||
authenticateWithDeviceKey(config, device.uuid, deviceApiKey)
|
||||
else
|
||||
authenticateWithApplicationKey(config, application.id)
|
||||
.then (config) ->
|
||||
# Associate a device, to prevent the supervisor
|
||||
# from creating another one on its own.
|
||||
config.registered_at = Math.floor(Date.now() / 1000)
|
||||
config.deviceId = device.id
|
||||
config.uuid = device.uuid
|
||||
|
||||
return config
|
||||
|
||||
authenticateWithApplicationKey = (config, applicationNameOrId) ->
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
resin.models.application.generateApiKey(applicationNameOrId)
|
||||
.then (apiKey) ->
|
||||
config.apiKey = apiKey
|
||||
return config
|
||||
|
||||
authenticateWithDeviceKey = (config, uuid, customDeviceApiKey) ->
|
||||
Promise = require('bluebird')
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
|
||||
Promise.try ->
|
||||
customDeviceApiKey || resin.models.device.generateDeviceKey(uuid)
|
||||
.then (deviceApiKey) ->
|
||||
config.deviceApiKey = deviceApiKey
|
||||
return config
|
@ -81,7 +81,7 @@
|
||||
"resin-cli-visuals": "^1.4.0",
|
||||
"resin-config-json": "^1.0.0",
|
||||
"resin-device-config": "^4.0.0",
|
||||
"resin-device-init": "^3.0.0",
|
||||
"resin-device-init": "^4.0.0",
|
||||
"resin-docker-build": "^0.4.0",
|
||||
"resin-doodles": "0.0.1",
|
||||
"resin-image-fs": "^2.3.0",
|
||||
|
Loading…
Reference in New Issue
Block a user