<commit_before>var storage = Rhaboo.perishable(window.location.href);
var historyIndex = 0,
		historyUndo = 0;

var app = angular.module('NetopeerGUIApp', ['JSONedit', 'ngTraverse', 'NetopeerGUIServices'])

	.controller('ConfigurationController', function ($scope, $filter, $http, $window, $timeout, traverse, AjaxService) {

		storage.write('revisions', []);
		storage.erase('revisions');
		storage.write('revisions', []);

		$scope.hasUndo = function() {
			return (historyIndex - historyUndo - 1) <= 0;
		};
		$scope.hasRedo = function() {
			return (historyIndex - historyUndo) >= storage.revisions.length;
		};
		var isUndo = false,
				isRedo = false;

		$scope.reload = function() {
			AjaxService.reloadData()
				.then(function successCallback(data) {
					$scope.jsonData = data.data;
				}, function errorCallback(data) {
					alert('error');
					console.log('data');
				});
		};

		$scope.$watch('jsonData', function (newValue, oldValue) {
			$scope.jsonString = JSON.stringify(newValue);
			if ( !isUndo && !isRedo && newValue !== oldValue ) {
				historyIndex = historyIndex - historyUndo;
				historyUndo = 0;

				// prevent the future
				storage.revisions.slice(0, historyIndex + 1);
				storage.revisions.push(JSON.stringify(newValue));

				historyIndex++;
			}
			isUndo = false;
			isRedo = false;
		}, true);

		$scope.$watch('jsonString', function (json) {
			try {
				$scope.jsonData = JSON.parse(json);
				$scope.wellFormed = true;
			} catch (e) {
				$scope.wellFormed = false;
			}
		}, true);

		var cleanupJSON = function(jsonData) {
			var cleanJson = $filter('json')(jsonData);
			var jsonObj = angular.fromJson(cleanJson);
			var removeSchemaNodes = function(obj) {
				traverse(obj).forEach(function (element, index, array) {
					if (typeof this.key !== "undefined") {
						var schemaPath = this.path.slice(0, -1);
						var attrPath = this.path.slice(0, -1);
						var attrChildPath = this.path.slice(0); // clone an array
						schemaPath.push('$@'+this.key);
						attrPath.push('@'+this.key);
						attrChildPath.push('@');
						var schema = traverse(obj).get(schemaPath);
						var attr = traverse(obj).get(attrPath);
						var attrChild = traverse(obj).get(attrChildPath);
						//if (this.key == 'groups') {
						//	console.log(attrChildPath);
						//	console.log(attrChild);
						//}
						if ((!angular.isUndefined(attr) || !angular.isUndefined(attrChild)) || (!angular.isUndefined(schema) && schema['iskey'] == true)) {
							// leave key elements

						} else if (this.key.indexOf('$@') !== -1 || this.key.indexOf('@') !== -1) {
							// leave attributes

						} else if (this.notRoot && !angular.isUndefined(this.parent.key) && this.path.toString().indexOf('@') === -1 && this.isLeaf) {
							//this.remove();
						}
					}
				});

				// remove schema nodes
				traverse(obj).forEach(function (element, index, array) {
					if (typeof this.key !== "undefined") {
						if (this.key.indexOf('$@') !== -1 || this.key.indexOf('netopeergui:status') !== -1) {
							this.remove();
						}
					}
				});

				// remove empty atribute nodes
				traverse(obj).forEach(function (element, index, array) {
					if (typeof this.key !== "undefined") {
						if ((this.key.indexOf('@') !== -1 && this.isLeaf) || (Object.prototype.toString.call(this.node) == '[object Array]' && !this.node.length)){
							this.delete(true);
						}
					}
				});
			};
			removeSchemaNodes(jsonObj);
			cleanJson = $filter('json')(jsonObj);
			return cleanJson;
		};

		$scope.download = function (jsonData) {
			var cleanJson = cleanupJSON(jsonData);
			$window.open("data:application/json;charset=utf-8," + encodeURIComponent(cleanJson));
		};

		$scope.undo = function() {
			var json = storage.revisions[historyIndex - historyUndo - 2];
			isUndo = true;
			$scope.jsonString = '{}';

			$timeout(function() {
				isUndo = true;
				$scope.jsonString = json;
				//$scope.jsonData = JSON.parse(json);
				historyUndo++;
			}, 1);
		};

		$scope.redo = function() {
			var json = storage.revisions[historyIndex - historyUndo];
			isRedo = true;
			$scope.jsonString = '{}';

			$timeout(function() {
				isRedo = true;
				$scope.jsonString = json;
				//$scope.jsonData = JSON.parse(json);
				historyUndo--;
			}, 1);
		};

		$scope.submitConfiguration = function(jsonData) {
			$.netopeergui.createSpinner();
			$.netopeergui.showSpinner();
			var cleanJson = cleanupJSON(jsonData);
			cleanJson = JSON.parse(cleanJson);

			AjaxService.submitConfiguration(cleanJson, window.location.href)
				.then(function successCallback(data) {
					$.netopeergui.processResponseData(data.data, function() {
						//$scope.reload();
						$.netopeergui.hideSpinner();
					});
				}, function errorCallback(data) {
					alert('error');
					console.log(data);
					$.netopeergui.hideSpinner();
				});
		};
	}
);<commit_msg>netopeerangular: increase digest limit<commit_after>var storage = Rhaboo.perishable(window.location.href);
var historyIndex = 0,
		historyUndo = 0;

var app = angular.module('NetopeerGUIApp', ['JSONedit', 'ngTraverse', 'NetopeerGUIServices'])

	.controller('ConfigurationController', function ($scope, $filter, $http, $window, $timeout, traverse, AjaxService) {

		storage.write('revisions', []);
		storage.erase('revisions');
		storage.write('revisions', []);

		$scope.hasUndo = function() {
			return (historyIndex - historyUndo - 1) <= 0;
		};
		$scope.hasRedo = function() {
			return (historyIndex - historyUndo) >= storage.revisions.length;
		};
		var isUndo = false,
				isRedo = false;

		$scope.reload = function() {
			AjaxService.reloadData()
				.then(function successCallback(data) {
					$scope.jsonData = data.data;
				}, function errorCallback(data) {
					alert('error');
					console.log('data');
				});
		};

		$scope.$watch('jsonData', function (newValue, oldValue) {
			$scope.jsonString = JSON.stringify(newValue);
			if ( !isUndo && !isRedo && newValue !== oldValue ) {
				historyIndex = historyIndex - historyUndo;
				historyUndo = 0;

				// prevent the future
				storage.revisions.slice(0, historyIndex + 1);
				storage.revisions.push(JSON.stringify(newValue));

				historyIndex++;
			}
			isUndo = false;
			isRedo = false;
		}, true);

		$scope.$watch('jsonString', function (json) {
			try {
				$scope.jsonData = JSON.parse(json);
				$scope.wellFormed = true;
			} catch (e) {
				$scope.wellFormed = false;
			}
		}, true);

		var cleanupJSON = function(jsonData) {
			var cleanJson = $filter('json')(jsonData);
			var jsonObj = angular.fromJson(cleanJson);
			var removeSchemaNodes = function(obj) {
				traverse(obj).forEach(function (element, index, array) {
					if (typeof this.key !== "undefined") {
						var schemaPath = this.path.slice(0, -1);
						var attrPath = this.path.slice(0, -1);
						var attrChildPath = this.path.slice(0); // clone an array
						schemaPath.push('$@'+this.key);
						attrPath.push('@'+this.key);
						attrChildPath.push('@');
						var schema = traverse(obj).get(schemaPath);
						var attr = traverse(obj).get(attrPath);
						var attrChild = traverse(obj).get(attrChildPath);
						//if (this.key == 'groups') {
						//	console.log(attrChildPath);
						//	console.log(attrChild);
						//}
						if ((!angular.isUndefined(attr) || !angular.isUndefined(attrChild)) || (!angular.isUndefined(schema) && schema['iskey'] == true)) {
							// leave key elements

						} else if (this.key.indexOf('$@') !== -1 || this.key.indexOf('@') !== -1) {
							// leave attributes

						} else if (this.notRoot && !angular.isUndefined(this.parent.key) && this.path.toString().indexOf('@') === -1 && this.isLeaf) {
							//this.remove();
						}
					}
				});

				// remove schema nodes
				traverse(obj).forEach(function (element, index, array) {
					if (typeof this.key !== "undefined") {
						if (this.key.indexOf('$@') !== -1 || this.key.indexOf('netopeergui:status') !== -1) {
							this.remove();
						}
					}
				});

				// remove empty atribute nodes
				traverse(obj).forEach(function (element, index, array) {
					if (typeof this.key !== "undefined") {
						if ((this.key.indexOf('@') !== -1 && this.isLeaf) || (Object.prototype.toString.call(this.node) == '[object Array]' && !this.node.length)){
							this.delete(true);
						}
					}
				});
			};
			removeSchemaNodes(jsonObj);
			cleanJson = $filter('json')(jsonObj);
			return cleanJson;
		};

		$scope.download = function (jsonData) {
			var cleanJson = cleanupJSON(jsonData);
			$window.open("data:application/json;charset=utf-8," + encodeURIComponent(cleanJson));
		};

		$scope.undo = function() {
			var json = storage.revisions[historyIndex - historyUndo - 2];
			isUndo = true;
			$scope.jsonString = '{}';

			$timeout(function() {
				isUndo = true;
				$scope.jsonString = json;
				//$scope.jsonData = JSON.parse(json);
				historyUndo++;
			}, 1);
		};

		$scope.redo = function() {
			var json = storage.revisions[historyIndex - historyUndo];
			isRedo = true;
			$scope.jsonString = '{}';

			$timeout(function() {
				isRedo = true;
				$scope.jsonString = json;
				//$scope.jsonData = JSON.parse(json);
				historyUndo--;
			}, 1);
		};

		$scope.submitConfiguration = function(jsonData) {
			$.netopeergui.createSpinner();
			$.netopeergui.showSpinner();
			var cleanJson = cleanupJSON(jsonData);
			cleanJson = JSON.parse(cleanJson);

			AjaxService.submitConfiguration(cleanJson, window.location.href)
				.then(function successCallback(data) {
					$.netopeergui.processResponseData(data.data, function() {
						//$scope.reload();
						$.netopeergui.hideSpinner();
					});
				}, function errorCallback(data) {
					alert('error');
					console.log(data);
					$.netopeergui.hideSpinner();
				});
		};
	})

	.config(['$rootScopeProvider', function ($rootScopeProvider) {
		$rootScopeProvider.digestTtl(20);
	}])
;<|endoftext|>


<commit_before>'use strict';

var indexOf = require('./e-index-of')

  , every = Array.prototype.every
  , isFirst;

isFirst = function (value, index) {
	return indexOf.call(this, value) === index;
};

module.exports = function () {
	return every.call(this, isFirst, this);
};
<commit_msg>-- whitespace<commit_after>'use strict';

var indexOf = require('./e-index-of')

  , every = Array.prototype.every
  , isFirst;

isFirst = function (value, index) {
	return indexOf.call(this, value) === index;
};

module.exports = function () { return every.call(this, isFirst, this); };
<|endoftext|>


<commit_before>import Check from "../Core/Check.js";
import clone from "../Core/clone.js";
import defined from "../Core/defined.js";
import Resource from "../Core/Resource.js";
import RuntimeError from "../Core/RuntimeError.js";
import has3DTilesExtension from "./has3DTilesExtension.js";
import ImplicitSubdivisionScheme from "./ImplicitSubdivisionScheme.js";

/**
 * An ImplicitTileset is a simple struct that stores information about the
 * structure of a single implicit tileset. This includes template URIs for
 * locating resources, details from the implicit root tile (bounding volume,
 * geometricError, etc.), and details about the subtrees (e.g. subtreeLevels,
 * subdivisionScheme).
 *
 * @alias ImplicitTileset
 * @constructor
 *
 * @param {Resource} baseResource The base resource for the tileset
 * @param {Object} tileJson The JSON header of the tile with the 3DTILES_implicit_tiling extension.
 * @private
 */
export default function ImplicitTileset(baseResource, tileJson) {
  var extension = tileJson.extensions["3DTILES_implicit_tiling"];
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.object(
    'tileJson.extensions["3DTILES_implicit_tiling"]',
    extension
  );
  //>>includeEnd('debug');

  /**
   * The base resource for the tileset. This is stored here as it is needed
   * later when expanding Implicit3DTileContents so tile URLs are relative
   * to the tileset, not the subtree file.
   *
   * @type {Resource}
   * @readonly
   * @private
   */
  this.baseResource = baseResource;

  /**
   * The geometric error of the root tile
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.geometricError = tileJson.geometricError;

  if (
    !defined(tileJson.boundingVolume.box) &&
    !defined(tileJson.boundingVolume.region)
  ) {
    throw new RuntimeError(
      "Only box and region are supported for implicit tiling"
    );
  }

  /**
   * The JSON representation of a bounding volume. This is either a box or a
   * region.
   *
   * @type {Object}
   * @readonly
   * @private
   */
  this.boundingVolume = tileJson.boundingVolume;

  /**
   * The refine strategy as a string, either 'ADD' or 'REPLACE'
   *
   * @type {String}
   * @readonly
   * @private
   */
  this.refine = tileJson.refine;

  /**
   * Template URI for the subtree resources, e.g.
   * https://example.com/{level}/{x}/{y}.subtree
   *
   * @type {Resource}
   * @readonly
   * @private
   */
  this.subtreeUriTemplate = new Resource({ url: extension.subtrees.uri });

  /**
   * Template URIs for locating content resources, e.g.
   * https://example.com/{level}/{x}/{y}.b3dm.
   *

   * This is an array to support 3DTILES_multiple_contents
   *

   *
   * @type {Resource[]}
   * @readonly
   * @private
   */
  this.contentUriTemplates = [];

  /**
   * Store a copy of the content headers, so properties such as
   * extras or extensions are preserved when
   * {@link Cesium3DTiles} are created for each tile.
   *

   * This is an array to support 3DTILES_multiple_contents
   *

   *
   * @type {Object[]}
   * @readonly
   * @private
   */
  this.contentHeaders = [];

  var contentHeaders = gatherContentHeaders(tileJson);
  for (var i = 0; i < contentHeaders.length; i++) {
    var contentHeader = contentHeaders[i];
    this.contentHeaders.push(clone(contentHeader, true));
    var contentResource = new Resource({ url: contentHeader.uri });
    this.contentUriTemplates.push(contentResource);
  }

  /**
   * The maximum number of contents as well as content availability bitstreams.
   * This is used for loop bounds when checking content availability.
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.contentCount = this.contentHeaders.length;

  /**
   * Stores a copy of the root implicit tile's JSON header. This is used
   * as a template for creating {@link Cesium3DTile}s. The following properties
   * are removed:
   *
   *

   *
tile.extensions["3DTILES_implicit_tiling"] to prevent infinite loops of implicit tiling

   *
tile.content since this is handled separately

   *
tile.extensions["3DTILES_multiple_contents"], again
   *  because contents are handled separately

   *

   *
   * @type {Object}
   * @readonly
   * @private
   */
  this.tileHeader = makeTileHeaderTemplate(tileJson);

  /**
   * The subdivision scheme for this implicit tileset; either OCTREE or QUADTREE
   *
   * @type {ImplicitSubdivisionScheme}
   * @readonly
   * @private
   */
  this.subdivisionScheme =
    ImplicitSubdivisionScheme[extension.subdivisionScheme];

  /**
   * The branching factor for this tileset. Either 4 for quadtrees or 8 for
   * octrees.
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.branchingFactor = ImplicitSubdivisionScheme.getBranchingFactor(
    this.subdivisionScheme
  );

  /**
   * How many distinct levels within each subtree. For example, a quadtree
   * with subtreeLevels = 2 will have 5 nodes per quadtree (1 root + 4 children)
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.subtreeLevels = extension.subtreeLevels;

  /**
   * The deepest level of any available tile in the entire tileset.
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.maximumLevel = extension.maximumLevel;
}

/**
 * Gather JSON headers for all contents in the tile.
 * This handles both regular tiles and tiles with the
 * `3DTILES_multiple_contents` extension
 *
 * @param {Object} tileJson The JSON header of the tile with the 3DTILES_implicit_tiling extension.
 * @return {Object[]} An array of JSON headers for the contents of each tile
 */
function gatherContentHeaders(tileJson) {
  if (has3DTilesExtension(tileJson, "3DTILES_multiple_contents")) {
    return tileJson.extensions["3DTILES_multiple_contents"].content;
  }

  if (defined(tileJson.content)) {
    return [tileJson.content];
  }

  return [];
}

function makeTileHeaderTemplate(tileJson) {
  var template = clone(tileJson, true);

  // remove the implicit tiling extension to prevent infinite loops
  delete template.extensions["3DTILES_implicit_tiling"];

  // content is handled separately, so remove content-related properties
  delete template.content;
  delete template.extensions["3DTILES_multiple_contents"];

  // if there are no other extensions, remove the extensions property to
  // keep each tile simple
  var removeExtensions = true;
  for (var key in template.extensions) {
    if (template.extensions.hasOwnProperty(key)) {
      removeExtensions = false;
    }
  }
  if (removeExtensions) {
    delete template.extensions;
  }

  return template;
}
<commit_msg>Fix ts build error<commit_after>import Check from "../Core/Check.js";
import clone from "../Core/clone.js";
import defined from "../Core/defined.js";
import Resource from "../Core/Resource.js";
import RuntimeError from "../Core/RuntimeError.js";
import has3DTilesExtension from "./has3DTilesExtension.js";
import ImplicitSubdivisionScheme from "./ImplicitSubdivisionScheme.js";

/**
 * An ImplicitTileset is a simple struct that stores information about the
 * structure of a single implicit tileset. This includes template URIs for
 * locating resources, details from the implicit root tile (bounding volume,
 * geometricError, etc.), and details about the subtrees (e.g. subtreeLevels,
 * subdivisionScheme).
 *
 * @alias ImplicitTileset
 * @constructor
 *
 * @param {Resource} baseResource The base resource for the tileset
 * @param {Object} tileJson The JSON header of the tile with the 3DTILES_implicit_tiling extension.
 * @private
 */
export default function ImplicitTileset(baseResource, tileJson) {
  var extension = tileJson.extensions["3DTILES_implicit_tiling"];
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.object(
    'tileJson.extensions["3DTILES_implicit_tiling"]',
    extension
  );
  //>>includeEnd('debug');

  /**
   * The base resource for the tileset. This is stored here as it is needed
   * later when expanding Implicit3DTileContents so tile URLs are relative
   * to the tileset, not the subtree file.
   *
   * @type {Resource}
   * @readonly
   * @private
   */
  this.baseResource = baseResource;

  /**
   * The geometric error of the root tile
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.geometricError = tileJson.geometricError;

  if (
    !defined(tileJson.boundingVolume.box) &&
    !defined(tileJson.boundingVolume.region)
  ) {
    throw new RuntimeError(
      "Only box and region are supported for implicit tiling"
    );
  }

  /**
   * The JSON representation of a bounding volume. This is either a box or a
   * region.
   *
   * @type {Object}
   * @readonly
   * @private
   */
  this.boundingVolume = tileJson.boundingVolume;

  /**
   * The refine strategy as a string, either 'ADD' or 'REPLACE'
   *
   * @type {String}
   * @readonly
   * @private
   */
  this.refine = tileJson.refine;

  /**
   * Template URI for the subtree resources, e.g.
   * https://example.com/{level}/{x}/{y}.subtree
   *
   * @type {Resource}
   * @readonly
   * @private
   */
  this.subtreeUriTemplate = new Resource({ url: extension.subtrees.uri });

  /**
   * Template URIs for locating content resources, e.g.
   * https://example.com/{level}/{x}/{y}.b3dm.
   *

   * This is an array to support 3DTILES_multiple_contents
   *

   *
   * @type {Resource[]}
   * @readonly
   * @private
   */
  this.contentUriTemplates = [];

  /**
   * Store a copy of the content headers, so properties such as
   * extras or extensions are preserved when
   * {@link Cesium3DTiles} are created for each tile.
   *

   * This is an array to support 3DTILES_multiple_contents
   *

   *
   * @type {Object[]}
   * @readonly
   * @private
   */
  this.contentHeaders = [];

  var contentHeaders = gatherContentHeaders(tileJson);
  for (var i = 0; i < contentHeaders.length; i++) {
    var contentHeader = contentHeaders[i];
    this.contentHeaders.push(clone(contentHeader, true));
    var contentResource = new Resource({ url: contentHeader.uri });
    this.contentUriTemplates.push(contentResource);
  }

  /**
   * The maximum number of contents as well as content availability bitstreams.
   * This is used for loop bounds when checking content availability.
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.contentCount = this.contentHeaders.length;

  /**
   * Stores a copy of the root implicit tile's JSON header. This is used
   * as a template for creating {@link Cesium3DTile}s. The following properties
   * are removed:
   *
   *

   *
tile.extensions["3DTILES_implicit_tiling"] to prevent infinite loops of implicit tiling

   *
tile.content since this is handled separately

   *
tile.extensions["3DTILES_multiple_contents"], again
   *  because contents are handled separately

   *

   *
   * @type {Object}
   * @readonly
   * @private
   */
  this.tileHeader = makeTileHeaderTemplate(tileJson);

  /**
   * The subdivision scheme for this implicit tileset; either OCTREE or QUADTREE
   *
   * @type {ImplicitSubdivisionScheme}
   * @readonly
   * @private
   */
  this.subdivisionScheme =
    ImplicitSubdivisionScheme[extension.subdivisionScheme];

  /**
   * The branching factor for this tileset. Either 4 for quadtrees or 8 for
   * octrees.
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.branchingFactor = ImplicitSubdivisionScheme.getBranchingFactor(
    this.subdivisionScheme
  );

  /**
   * How many distinct levels within each subtree. For example, a quadtree
   * with subtreeLevels = 2 will have 5 nodes per quadtree (1 root + 4 children)
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.subtreeLevels = extension.subtreeLevels;

  /**
   * The deepest level of any available tile in the entire tileset.
   *
   * @type {Number}
   * @readonly
   * @private
   */
  this.maximumLevel = extension.maximumLevel;
}

/**
 * Gather JSON headers for all contents in the tile.
 * This handles both regular tiles and tiles with the
 * `3DTILES_multiple_contents` extension
 *
 * @param {Object} tileJson The JSON header of the tile with the 3DTILES_implicit_tiling extension.
 * @return {Object[]} An array of JSON headers for the contents of each tile
 * @private
 */
function gatherContentHeaders(tileJson) {
  if (has3DTilesExtension(tileJson, "3DTILES_multiple_contents")) {
    return tileJson.extensions["3DTILES_multiple_contents"].content;
  }

  if (defined(tileJson.content)) {
    return [tileJson.content];
  }

  return [];
}

function makeTileHeaderTemplate(tileJson) {
  var template = clone(tileJson, true);

  // remove the implicit tiling extension to prevent infinite loops
  delete template.extensions["3DTILES_implicit_tiling"];

  // content is handled separately, so remove content-related properties
  delete template.content;
  delete template.extensions["3DTILES_multiple_contents"];

  // if there are no other extensions, remove the extensions property to
  // keep each tile simple
  var removeExtensions = true;
  for (var key in template.extensions) {
    if (template.extensions.hasOwnProperty(key)) {
      removeExtensions = false;
    }
  }
  if (removeExtensions) {
    delete template.extensions;
  }

  return template;
}
<|endoftext|>


<commit_before>'use strict';

const Promise = require('bluebird');
const model = require('../../mongo/model');
const common = require('./common');

// In a similar fashion to how remove works, finds all the ids
// that are present in the source but missing in the target
// and copies those to the target

module.exports = function (options) {
    common.checkOptions(['connectString', 'idQuery', 'copyQuery'], options);
    return doSync(options);
};

const doSync = Promise.coroutine(function* (options) {
    const collection = options.collection;
    const Model = model.getSource(collection);

    // connect to Oracle
    const oracleConn = yield common.connect(options);

    let idQuery = options.query;
    idQuery = 'SELECT id FROM (\n' + idQuery + '\n) inner_table';
    let copyQuery = options.copyQuery;
    copyQuery = 'SELECT * FROM (\n' + copyQuery + '\n) inner_table';

    // Get all ids from original source
    const sourceIds = yield common.getIDs(oracleConn, idQuery);

    // Get all ids from copied source
    const targetIds = new Set(
        (yield Model.find({data: {$ne: null}}, {_id: 1}).lean().exec())
            .map(t => t._id)
    );
    const idsToCopy = new Set();

    for (let id of sourceIds) {
        // add to list if exists in original source but not in copied source
        if (!targetIds.has(id)) {
            idsToCopy.add(id);
        }
    }

    copyQuery = `${copyQuery}\nWHERE ID in ('${[...idsToCopy].join("','")}')`;
    yield common.copyEntries(oracleConn, copyQuery, collection, {
        resetDate: true
    });
    yield oracleConn.release();
});
<commit_msg>fix query in copy missing ids<commit_after>'use strict';

const Promise = require('bluebird');
const model = require('../../mongo/model');
const common = require('./common');

// In a similar fashion to how remove works, finds all the ids
// that are present in the source but missing in the target
// and copies those to the target

module.exports = function (options) {
    common.checkOptions(['connectString', 'query'], options);
    return doSync(options);
};

const doSync = Promise.coroutine(function* (options) {
    const collection = options.collection;
    const Model = model.getSource(collection);

    // connect to Oracle
    const oracleConn = yield common.connect(options);

    const query = options.query;
    const idQuery = 'SELECT id FROM (\n' + query + '\n) inner_table';

    // Get all ids from original source
    const sourceIds = yield common.getIDs(oracleConn, idQuery);

    // Get all ids from copied source
    const targetIds = new Set(
        (yield Model.find({data: {$ne: null}}, {_id: 1}).lean().exec())
            .map(t => t._id)
    );
    const idsToCopy = new Set();

    for (let id of sourceIds) {
        // add to list if exists in original source but not in copied source
        if (!targetIds.has(id)) {
            idsToCopy.add(id);
        }
    }

    let copyQuery = `
        SELECT * FROM (
            ${query}
        ) inner_table
        WHERE ID IN ('${[...idsToCopy].join("','")}')
    `;

    yield common.copyEntries(oracleConn, copyQuery, collection, {
        resetDate: true
    });
    yield oracleConn.release();
});
<|endoftext|>


<commit_before>(function (module) {
    module.controller('CreateProcessController', CreateProcessController);
    CreateProcessController.$inject = ["projectsService", "$stateParams", "selectItems",
        "template", "$modal", "processEdit", "$previousState", "$state"];

    function CreateProcessController(projectsService, $stateParams, selectItems, template,
                                     $modal, processEdit, $previousState, $state) {
        var ctrl = this;
        ctrl.process = template;
        ctrl.chooseSamples = chooseSamples;
        ctrl.chooseInputFiles = chooseInputFiles;
        ctrl.chooseOutputFiles = chooseOutputFiles;
        ctrl.linkFilesToSample = linkFilesToSample;
        ctrl.cancel = gotoPreviousState;
        ctrl.submit = submit;
        ctrl.submitAndAnother = submitAndAnother;
        ctrl.remove = removeById;
        ctrl.submitSample = submitSample;
        ctrl.doc = {value: []};
        ctrl.sample = {
            name: '',
            description: '',
            old_properties: [],
            new_properties: [],
            files: []
        };

        setPreviousStateMemo();

        /////////////////////////

        function chooseSamples() {
            selectItems.open('samples').then(function (item) {
                var uniqueSamples = differenceById(item.samples, ctrl.process.input_samples);
                uniqueSamples.forEach(function (sample) {
                    ctrl.process.input_samples.push({
                        id: sample.id,
                        name: sample.name,
                        old_properties: [],
                        new_properties: [],
                        property_set_id: sample.property_set_id,
                        files: []
                    });
                });
            });
        }

        function chooseInputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.input_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.input_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function chooseOutputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.output_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.output_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function gotoPreviousState() {
            $previousState.go('processes_previous');
            $previousState.forget('processes_previous');
        }

        function submitAndAnother() {
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(function () {
                $state.go('projects.project.processes.create', {process: p.process_name, process_id: p.id});
            });
        }

        function submit() {
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(
                function success() {
                    gotoPreviousState();
                },

                function failure() {
                    console.log('failed to save process', e);
                }
            );
        }

        function submitSample() {
            if (ctrl.doc.value.length) {
                var composition = ctrl.doc.value.map(function(c) {
                    return {
                        element: c.element,
                        value: _.parseInt(c.value)
                    };
                });
                var measurement = {
                    name: 'Composition',
                    attribute: 'composition',
                    measurements: [
                        {
                            is_best_measure: true,
                            value: composition,
                            unit: ctrl.doc.unit,
                            _type: 'composition'
                        }
                    ]
                };
                ctrl.sample.new_properties.push(measurement);
            }
            ctrl.process.output_samples.push(ctrl.sample);
            submit();
        }

        // setPreviousStateMemo sets the process_previous memo to the previous state. It
        // only sets the memo if the previous state doesn't exist. If it does exist that
        // means that create has been entered multiple times.
        function setPreviousStateMemo() {
            var previousMemo = $previousState.get('processes_previous');
            var previousState = $previousState.get();
            if (!previousMemo) {
                $previousState.memo('processes_previous');
            } else {
                // previousMemo is not null, but the user may not have cancelled to clear
                // the previousMemo. That is they may have gone to the tabs rather than
                // the cancel button to get out of a create.
                if (previousState.state.name !== 'projects.project.processes.create') {
                    // User did not cancel, so we have an old state. Save new previous state
                    // so user will go where they expect if they press the cancel button.
                    $previousState.memo('processes_previous');
                }
            }
        }

        function linkFilesToSample(sample, input_files, output_files) {
            var modal = $modal.open({
                templateUrl: 'application/core/projects/project/processes/link-files-to-sample.html',
                controller: 'LinkFilesToSampleController',
                controllerAs: 'sample',
                resolve: {
                    files: function () {
                        var files = input_files.concat(output_files);
                        var linkedFilesById = _.indexBy(sample.files, 'id');
                        var setLinked = function (f) {
                            f.linked = (f.id in linkedFilesById);
                            return f;
                        };

                        return files.map(setLinked);
                    },

                    sample: function () {
                        return sample;
                    },

                    project: function () {
                        return {};
                    }
                }
            });
            modal.result.then(function (linkedFiles) {
                sample = processEdit.refreshSample(linkedFiles, sample);
            });
        }
    }
}(angular.module('materialscommons')));<commit_msg>Remove _.parseInt since the periodic-table is saving measurements as numbers and not strings so they don't need to be converted.<commit_after>(function (module) {
    module.controller('CreateProcessController', CreateProcessController);
    CreateProcessController.$inject = ["projectsService", "$stateParams", "selectItems",
        "template", "$modal", "processEdit", "$previousState", "$state"];

    function CreateProcessController(projectsService, $stateParams, selectItems, template,
                                     $modal, processEdit, $previousState, $state) {
        var ctrl = this;
        ctrl.process = template;
        ctrl.chooseSamples = chooseSamples;
        ctrl.chooseInputFiles = chooseInputFiles;
        ctrl.chooseOutputFiles = chooseOutputFiles;
        ctrl.linkFilesToSample = linkFilesToSample;
        ctrl.cancel = gotoPreviousState;
        ctrl.submit = submit;
        ctrl.submitAndAnother = submitAndAnother;
        ctrl.remove = removeById;
        ctrl.submitSample = submitSample;
        ctrl.doc = {value: []};
        ctrl.sample = {
            name: '',
            description: '',
            old_properties: [],
            new_properties: [],
            files: []
        };

        setPreviousStateMemo();

        /////////////////////////

        function chooseSamples() {
            selectItems.open('samples').then(function (item) {
                var uniqueSamples = differenceById(item.samples, ctrl.process.input_samples);
                uniqueSamples.forEach(function (sample) {
                    ctrl.process.input_samples.push({
                        id: sample.id,
                        name: sample.name,
                        old_properties: [],
                        new_properties: [],
                        property_set_id: sample.property_set_id,
                        files: []
                    });
                });
            });
        }

        function chooseInputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.input_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.input_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function chooseOutputFiles() {
            selectItems.open('files').then(function (item) {
                var uniqueFiles = differenceById(item.files, ctrl.process.output_files);
                uniqueFiles.forEach(function (file) {
                    ctrl.process.output_files.push({
                        id: file.id,
                        name: file.name,
                        mediatype: file.mediatype
                    });
                });
            });
        }

        function gotoPreviousState() {
            $previousState.go('processes_previous');
            $previousState.forget('processes_previous');
        }

        function submitAndAnother() {
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(function () {
                $state.go('projects.project.processes.create', {process: p.process_name, process_id: p.id});
            });
        }

        function submit() {
            projectsService.createProjectProcess($stateParams.id, ctrl.process).then(
                function success() {
                    gotoPreviousState();
                },

                function failure() {
                    console.log('failed to save process', e);
                }
            );
        }

        function submitSample() {
            if (ctrl.doc.value.length) {
                var composition = ctrl.doc.value.map(function(c) {
                    return {
                        element: c.element,
                        value: c.value
                    };
                });
                var measurement = {
                    name: 'Composition',
                    attribute: 'composition',
                    measurements: [
                        {
                            is_best_measure: true,
                            value: composition,
                            unit: ctrl.doc.unit,
                            _type: 'composition'
                        }
                    ]
                };
                ctrl.sample.new_properties.push(measurement);
            }
            ctrl.process.output_samples.push(ctrl.sample);
            submit();
        }

        // setPreviousStateMemo sets the process_previous memo to the previous state. It
        // only sets the memo if the previous state doesn't exist. If it does exist that
        // means that create has been entered multiple times.
        function setPreviousStateMemo() {
            var previousMemo = $previousState.get('processes_previous');
            var previousState = $previousState.get();
            if (!previousMemo) {
                $previousState.memo('processes_previous');
            } else {
                // previousMemo is not null, but the user may not have cancelled to clear
                // the previousMemo. That is they may have gone to the tabs rather than
                // the cancel button to get out of a create.
                if (previousState.state.name !== 'projects.project.processes.create') {
                    // User did not cancel, so we have an old state. Save new previous state
                    // so user will go where they expect if they press the cancel button.
                    $previousState.memo('processes_previous');
                }
            }
        }

        function linkFilesToSample(sample, input_files, output_files) {
            var modal = $modal.open({
                templateUrl: 'application/core/projects/project/processes/link-files-to-sample.html',
                controller: 'LinkFilesToSampleController',
                controllerAs: 'sample',
                resolve: {
                    files: function () {
                        var files = input_files.concat(output_files);
                        var linkedFilesById = _.indexBy(sample.files, 'id');
                        var setLinked = function (f) {
                            f.linked = (f.id in linkedFilesById);
                            return f;
                        };

                        return files.map(setLinked);
                    },

                    sample: function () {
                        return sample;
                    },

                    project: function () {
                        return {};
                    }
                }
            });
            modal.result.then(function (linkedFiles) {
                sample = processEdit.refreshSample(linkedFiles, sample);
            });
        }
    }
}(angular.module('materialscommons')));<|endoftext|>


<commit_before>/* eslint-disable no-bitwise */

/*
   The MIT License (MIT)

   Copyright (c) 2014 Jameson Little

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

// ----------------------------------------------------------------------------
// Decoding infrastructure
// ----------------------------------------------------------------------------

const REVERSE_LOOKUP = [];
REVERSE_LOOKUP['-'.charCodeAt(0)] = 62;
REVERSE_LOOKUP['_'.charCodeAt(0)] = 63;

const BASE64_CODE =
  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
for (let i = 0; i < BASE64_CODE.length; i++) {
  REVERSE_LOOKUP[BASE64_CODE.charCodeAt(i)] = i;
}

// ----------------------------------------------------------------------------
// Base64 analysis
// ----------------------------------------------------------------------------

function isValidChar(c) {
  return REVERSE_LOOKUP[c.charCodeAt(0)] !== undefined;
}

function extractChunks(b64Str) {
  const strSize = b64Str.length;
  const chunks = [];

  let currentChunk = null;
  for (let i = 0; i < strSize; i++) {
    if (isValidChar(b64Str[i])) {
      if (!currentChunk) {
        currentChunk = { start: i, count: 0 };
      }
      currentChunk.count++;
      currentChunk.end = i;
    } else if (b64Str[i] === '=' && currentChunk) {
      // End of chunk
      chunks.push(currentChunk);
      currentChunk = null;
    } else {
      // Skip padding / formatting
      // => do nothing, just move along
    }
  }
  return chunks;
}

function writeChunk(b64Str, chunk, dstOffset, unit8) {
  const { start, count } = chunk;
  const remain = count % 4;
  const fourCharProcessCount = Math.floor(count / 4);
  let charIdx = start;
  let tmp = null;
  let offset = dstOffset;

  // Handle 4=>3
  for (let i = 0; i < fourCharProcessCount; i++) {
    while (!isValidChar(charIdx)) {
      charIdx++;
    }
    tmp = REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 18;
    while (!isValidChar(charIdx)) {
      charIdx++;
    }
    tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 12;
    while (!isValidChar(charIdx)) {
      charIdx++;
    }
    tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 6;
    while (!isValidChar(charIdx)) {
      charIdx++;
    }
    tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)];

    unit8[offset++] = (tmp >> 16) & 0xff;
    unit8[offset++] = (tmp >> 8) & 0xff;
    unit8[offset++] = tmp & 0xff;
  }

  // Handle remain
  switch (remain) {
    case 3:
      while (!isValidChar(charIdx)) {
        charIdx++;
      }
      tmp = REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 10;
      while (!isValidChar(charIdx)) {
        charIdx++;
      }
      tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 4;
      while (!isValidChar(charIdx)) {
        charIdx++;
      }
      tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] >> 2;
      unit8[offset++] = (tmp >> 8) & 0xff;
      unit8[offset++] = tmp & 0xff;
      break;
    case 2:
      while (!isValidChar(charIdx)) {
        charIdx++;
      }
      tmp = REVERSE_LOOKUP[b64Str.charCodeAt(charIdx)] << 2;
      while (!isValidChar(charIdx)) {
        charIdx++;
      }
      tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx)] >> 4;
      unit8[offset++] = tmp & 0xff;
      break;
    case 1:
      console.error('BASE64: remain 1 should not happen');
      break;
    case 0:
      break;
    default:
      break;
  }

  return offset;
}

function toArrayBuffer(b64Str) {
  const chunks = extractChunks(b64Str);
  let totalSize = 0;
  for (let i = 0; i < chunks.length; i++) {
    const { count } = chunks[i];
    const remain = count % 4;
    totalSize += (count - remain) * 3 + remain;
  }

  const arrayBuffer = new ArrayBuffer(totalSize);
  const view = new Uint8Array(arrayBuffer);
  let dstOffset = 0;
  for (let i = 0; i < chunks.length; i++) {
    dstOffset += writeChunk(b64Str, chunks[i], dstOffset, view);
  }

  return arrayBuffer;
}

export default {
  toArrayBuffer,
};
<commit_msg>fix(Base64): Incorrect handling of case where remain is 1<commit_after>/* eslint-disable no-bitwise */

// ----------------------------------------------------------------------------
// Decoding infrastructure
// ----------------------------------------------------------------------------

const REVERSE_LOOKUP = [];
REVERSE_LOOKUP['-'.charCodeAt(0)] = 62;
REVERSE_LOOKUP['_'.charCodeAt(0)] = 63;

const BASE64_CODE =
  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
for (let i = 0; i < BASE64_CODE.length; i++) {
  REVERSE_LOOKUP[BASE64_CODE.charCodeAt(i)] = i;
}

// ----------------------------------------------------------------------------
// Base64 analysis
// ----------------------------------------------------------------------------

function isValidChar(c) {
  return REVERSE_LOOKUP[c.charCodeAt(0)] !== undefined;
}

function extractChunks(b64Str) {
  const strSize = b64Str.length;
  const chunks = [];

  let currentChunk = null;
  for (let i = 0; i < strSize; i++) {
    if (isValidChar(b64Str[i])) {
      if (!currentChunk) {
        currentChunk = { start: i, count: 0 };
      }
      currentChunk.count++;
      currentChunk.end = i;
    } else if (b64Str[i] === '=' && currentChunk) {
      // End of chunk (found padding char)
      chunks.push(currentChunk);
      currentChunk = null;
    }
  }

  if (currentChunk) {
    chunks.push(currentChunk);
  }
  return chunks;
}

function writeChunk(b64Str, chunk, dstOffset, uint8) {
  const { start, count } = chunk;
  const remain = count % 4;
  const fourCharProcessCount = Math.floor(count / 4);
  let charIdx = start;
  let tmp = null;
  let offset = dstOffset;

  // Handle 4=>3
  for (let i = 0; i < fourCharProcessCount; i++) {
    while (!isValidChar(b64Str[charIdx])) {
      charIdx++;
    }
    tmp = REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 18;
    while (!isValidChar(b64Str[charIdx])) {
      charIdx++;
    }
    tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 12;
    while (!isValidChar(b64Str[charIdx])) {
      charIdx++;
    }
    tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 6;
    while (!isValidChar(b64Str[charIdx])) {
      charIdx++;
    }
    tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)];

    uint8[offset++] = (tmp >> 16) & 0xff;
    uint8[offset++] = (tmp >> 8) & 0xff;
    uint8[offset++] = tmp & 0xff;
  }

  // Handle remain
  switch (remain) {
    case 3:
      while (!isValidChar(b64Str[charIdx])) {
        charIdx++;
      }
      tmp = REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 10;
      while (!isValidChar(b64Str[charIdx])) {
        charIdx++;
      }
      tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 4;
      while (!isValidChar(b64Str[charIdx])) {
        charIdx++;
      }
      tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] >> 2;
      uint8[offset++] = (tmp >> 8) & 0xff;
      uint8[offset++] = tmp & 0xff;
      break;
    case 2:
      while (!isValidChar(b64Str[charIdx])) {
        charIdx++;
      }
      tmp = REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] << 2;
      while (!isValidChar(b64Str[charIdx])) {
        charIdx++;
      }
      tmp |= REVERSE_LOOKUP[b64Str.charCodeAt(charIdx++)] >> 4;
      uint8[offset++] = tmp & 0xff;
      break;
    case 1:
      throw new Error('BASE64: remain 1 should not happen');
    case 0:
      break;
    default:
      break;
  }

  return offset;
}

function toArrayBuffer(b64Str) {
  const chunks = extractChunks(b64Str);
  const totalEncodedLength = chunks[chunks.length - 1].end + 1;
  const padding = (4 - (totalEncodedLength % 4)) % 4; // -length mod 4
  // Any padding chars in the middle of b64Str is to be interpreted as \x00,
  // whereas the terminating padding chars are to be interpreted as literal padding.
  const totalSize = ((totalEncodedLength + padding) * 3) / 4 - padding;

  const arrayBuffer = new ArrayBuffer(totalSize);
  const view = new Uint8Array(arrayBuffer);
  let dstOffset = 0;
  for (let i = 0; i < chunks.length; i++) {
    dstOffset += writeChunk(b64Str, chunks[i], dstOffset, view);
    dstOffset += (4 - (chunks[i].count % 4)) % 4;
  }

  return arrayBuffer;
}

export default {
  toArrayBuffer,
};
<|endoftext|>


<commit_before>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2013 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

PageSystemInformation.prototype = {
    _init: function() {
        this.id = "system_information";
    },

    getTitle: function() {
        return C_("page-title", "System Information");
    },

    setup: function() {
        var self = this;

        $("#realms-join").click (function (e) {
            if (!cockpit.check_role('cockpit-realm-admin', self.client))
                return;

            if(self.realms.Joined[0] === undefined) {
                cockpit.realms_op_set_parameters(self.realm_manager, 'join', '', { });
                $('#realms-op').modal('show');
            }
        });

        $('#system_information_change_hostname_button').on('click', function () {
            if (!cockpit.check_role('wheel', self.client))
                return;
            PageSystemInformationChangeHostname.client = self.client;
            $('#system_information_change_hostname').modal('show');
        });
    },

    update: function() {
        var self = this;
        var joined = self.realm_manager.Joined;

        $("#realms-list").empty();

        if (joined === undefined) {
            $("#realms-empty-text").hide();
            return;
        }

        if (joined.length === 0) {
            $("#realms-empty-text").show();
            return;
        } else
            $("#realms-empty-text").hide();

            (function () {
                var name = joined[0][0];
                var details = joined[0][1];
                $("#realms-list").append(('
' +
                                          cockpit_esc(name) +
                                          '<button class="btn btn-default realms-leave-button" id="realms-leave" style="float:right">' +
                                          _("Leave") + '</button>' +
                                          '
' +
                                          '
'));
                $("#realms-leave").off("click");
                $("#realms-leave").on("click", function (e) {
                    if (!cockpit.check_role('cockpit-realm-admin', self.client))
                        return;
                    $("#realms-leave-spinner" ).show();
                    self.leave_realm(name, details);
                });
            })();
    },

    update_busy: function () {
        var self = this;

        var busy = self.realm_manager.Busy;

        if (busy && busy[0])
            $(".realms-leave-button").prop('disabled', true);
        else {
            $(".realms-leave-button").prop('disabled', false);
            $(".realms-leave-spinner").hide();
        }
    },

    leave_realm: function (name, details) {
        var self = this;

        $("#realms-leave-error").text("");
        var options = { 'server-software': details['server-software'],
                        'client-software': details['client-software']
                      };
        self.realm_manager.call("Leave", name, [ 'none', '', '' ], options, function (error, result) {
            $(".realms-leave-spinner").hide();
            if (error) {
                if (error.name == 'com.redhat.Cockpit.Error.AuthenticationFailed') {
                    cockpit.realms_op_set_parameters(self.realm_manager, 'leave', name, details);
                    $("#realms-op").modal('show');
                } else
                    $("#realms-leave-error").text(error.message);
            }
        });
    },

    enter: function() {
        var self = this;

        self.address = cockpit.get_page_param('machine', 'server') || "localhost";
        /* TODO: This code needs to be migrated away from dbus-json1 */
        self.client = cockpit.dbus(self.address, { payload: 'dbus-json1' });
        cockpit.set_watched_client(self.client);

        self.address = cockpit.get_page_param('machine', 'server') || "localhost";
        /* TODO: This code needs to be migrated away from dbus-json1 */
        self.client = cockpit.dbus(self.address, { payload: 'dbus-json1' });
        cockpit.set_watched_client(self.client);
        self.realm_manager = self.client.get("/com/redhat/Cockpit/Realms",
                                             "com.redhat.Cockpit.Realms");
        $(self.realm_manager).on("notify:Joined.realms", $.proxy(self, "update"));
        $(self.realm_manager).on("notify:Busy.realms", $.proxy(self, "update_busy"));

        $("#realms-leave-error").text("");
        self.update();
        self.update_busy();
        self.manager = self.client.get("/com/redhat/Cockpit/Manager",
                                       "com.redhat.Cockpit.Manager");

        function bindf(sel, object, prop, func) {
            function update() {
                $(sel).text(func(object[prop]));
            }
            $(object).on('notify:' + prop + '.system-information', update);
            update();
        }

        function bind(sel, object, prop) {
            bindf(sel, object, prop, function (s) { return s; });
        }

        bind("#system_information_hardware_text", self.manager, "System");
        bind("#system_information_asset_tag_text", self.manager, "SystemSerial");
        bind("#system_information_bios_text", self.manager, "BIOS");
        bind("#system_information_os_text", self.manager, "OperatingSystem");

        function hostname_text() {
            var pretty_hostname = self.manager.PrettyHostname;
            var hostname = self.manager.Hostname;
            var str;
            if (!pretty_hostname || pretty_hostname == hostname)
                str = hostname;
            else
                str = pretty_hostname + " (" + hostname + ")";
	    return str;
        }

        bindf("#system_information_hostname_text", self.manager, "Hostname", hostname_text);
        bindf("#system_information_hostname_text", self.manager, "PrettyHostname", hostname_text);

        function realms_text(val) {
            if (!val)
                return "?";

            var res = [ ];
            for (var i = 0; i < val.length; i++)
                res.push(val[i][0]);
            return res.join (", ");
        }

        function hide_buttons(val) {
            if (!val)
                return;

            if(val[0] === undefined){
                $(".realms-leave-spinner").hide();
                $("#realms-leave").hide();
                $("#realms-join").show();
            }
            else {
                $("#realms-join").hide();
                $("#realms-leave").show();
                $(".realms-leave-button").prop('disabled', false);
                $("#realms-op").modal('hide');
            }

        }

        self.realms = self.client.get("/com/redhat/Cockpit/Realms", "com.redhat.Cockpit.Realms");
        bindf("#system_information_realms", self.realms, "Joined", realms_text);

        $(self.realms).on('notify:Joined.system-information', function() {
            hide_buttons(self.realms['Joined']);
        });

        hide_buttons(self.realms['Joined']);
    },

    show: function() {
    },

    leave: function() {
        var self = this;

        function unbind(object) {
            $(object).off('.system-information');
        }

        unbind(self.manager);
        unbind(self.realms);

        cockpit.set_watched_client(null);
        self.client.release();
        self.client = null;
        self.manager = null;
        self.realms = null;
        $(self.realm_manager).off('.realms');
        self.realm_manager = null;
    }
};

function PageSystemInformation() {
    this._init();
}

cockpit.pages.push(new PageSystemInformation());

PageSystemInformationChangeHostname.prototype = {
    _init: function() {
        this.id = "system_information_change_hostname";
    },

    getTitle: function() {
        return C_("page-title", "Change Host Name");
    },

    setup: function() {
        $("#sich-pretty-hostname").on("keyup", $.proxy(this._on_full_name_changed, this));
        $("#sich-hostname").on("keyup", $.proxy(this._on_name_changed, this));
        $("#sich-apply-button").on("click", $.proxy(this._on_apply_button, this));
    },

    enter: function() {
        var self = this;

        self.manager = PageSystemInformationChangeHostname.client.get("/com/redhat/Cockpit/Manager",
                                                                      "com.redhat.Cockpit.Manager");
        self._initial_hostname = self.manager.Hostname || "";
        self._initial_pretty_hostname = self.manager.PrettyHostname || self._initial_hostname;
        $("#sich-pretty-hostname").val(self._initial_pretty_hostname);
        $("#sich-hostname").val(self._initial_hostname);

        this._always_update_from_pretty = false;
        this._update();
    },

    show: function() {
        $("#sich-pretty-hostname").focus();
    },

    leave: function() {
    },

    _on_apply_button: function(event) {
        var self = this;

        var new_full_name = $("#sich-pretty-hostname").val();
        var new_name = $("#sich-hostname").val();
        self.manager.call("SetHostname",
                          new_full_name, new_name, {},
                          function(error, reply) {
                              $("#system_information_change_hostname").modal('hide');
                              if(error) {
                                  cockpit.show_unexpected_error(error);
                              }
                          });
    },

    _on_full_name_changed: function(event) {
        /* Whenever the pretty host name has changed (e.g. the user has edited it), we compute a new
         * simple host name (e.g. 7bit ASCII, no special chars/spaces, lower case) from it...
         */
        var pretty_hostname = $("#sich-pretty-hostname").val();
        if (this._always_update_from_pretty || this._initial_pretty_hostname != pretty_hostname) {
            var new_hostname = pretty_hostname.toLowerCase().replace(/['"]+/g, "").replace(/[^a-zA-Z0-9]+/g, "-");
            $("#sich-hostname").val(new_hostname);
            this._always_update_from_pretty = true; // make sure we always update it from now-on
        }
        this._update();
    },

    _on_name_changed: function(event) {
        this._update();
    },

    _update: function() {
        var apply_button = $("#sich-apply-button");
        var note = $("#sich-note");
        var changed = false;
        var valid = false;
        var can_apply = false;

        var hostname = $("#sich-hostname").val();
        var pretty_hostname = $("#sich-pretty-hostname").val();

        if (hostname != this._initial_hostname ||
            pretty_hostname != this._initial_pretty_hostname)
            changed = true;

        if (hostname.match(/[a-z0-9-]*/) == hostname)
            valid = true;

        if (changed && valid)
            can_apply = true;

        if (valid)
            note.hide();
        else
            note.show();

        apply_button.prop('disabled', !can_apply);
    }
};

function PageSystemInformationChangeHostname() {
    this._init();
}

cockpit.pages.push(new PageSystemInformationChangeHostname());
<commit_msg>shell: Move cockpit-system-information.js into private JS scope<commit_after>/*
 * This file is part of Cockpit.
 *
 * Copyright (C) 2013 Red Hat, Inc.
 *
 * Cockpit is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

(function(cockpit, $) {

PageSystemInformation.prototype = {
    _init: function() {
        this.id = "system_information";
    },

    getTitle: function() {
        return C_("page-title", "System Information");
    },

    setup: function() {
        var self = this;

        $("#realms-join").click (function (e) {
            if (!cockpit.check_role('cockpit-realm-admin', self.client))
                return;

            if(self.realms.Joined[0] === undefined) {
                cockpit.realms_op_set_parameters(self.realm_manager, 'join', '', { });
                $('#realms-op').modal('show');
            }
        });

        $('#system_information_change_hostname_button').on('click', function () {
            if (!cockpit.check_role('wheel', self.client))
                return;
            PageSystemInformationChangeHostname.client = self.client;
            $('#system_information_change_hostname').modal('show');
        });
    },

    update: function() {
        var self = this;
        var joined = self.realm_manager.Joined;

        $("#realms-list").empty();

        if (joined === undefined) {
            $("#realms-empty-text").hide();
            return;
        }

        if (joined.length === 0) {
            $("#realms-empty-text").show();
            return;
        } else
            $("#realms-empty-text").hide();

            (function () {
                var name = joined[0][0];
                var details = joined[0][1];
                $("#realms-list").append(('
' +
                                          cockpit_esc(name) +
                                          '<button class="btn btn-default realms-leave-button" id="realms-leave" style="float:right">' +
                                          _("Leave") + '</button>' +
                                          '
' +
                                          '
'));
                $("#realms-leave").off("click");
                $("#realms-leave").on("click", function (e) {
                    if (!cockpit.check_role('cockpit-realm-admin', self.client))
                        return;
                    $("#realms-leave-spinner" ).show();
                    self.leave_realm(name, details);
                });
            })();
    },

    update_busy: function () {
        var self = this;

        var busy = self.realm_manager.Busy;

        if (busy && busy[0])
            $(".realms-leave-button").prop('disabled', true);
        else {
            $(".realms-leave-button").prop('disabled', false);
            $(".realms-leave-spinner").hide();
        }
    },

    leave_realm: function (name, details) {
        var self = this;

        $("#realms-leave-error").text("");
        var options = { 'server-software': details['server-software'],
                        'client-software': details['client-software']
                      };
        self.realm_manager.call("Leave", name, [ 'none', '', '' ], options, function (error, result) {
            $(".realms-leave-spinner").hide();
            if (error) {
                if (error.name == 'com.redhat.Cockpit.Error.AuthenticationFailed') {
                    cockpit.realms_op_set_parameters(self.realm_manager, 'leave', name, details);
                    $("#realms-op").modal('show');
                } else
                    $("#realms-leave-error").text(error.message);
            }
        });
    },

    enter: function() {
        var self = this;

        self.address = cockpit.get_page_param('machine', 'server') || "localhost";
        /* TODO: This code needs to be migrated away from dbus-json1 */
        self.client = cockpit.dbus(self.address, { payload: 'dbus-json1' });
        cockpit.set_watched_client(self.client);

        self.address = cockpit.get_page_param('machine', 'server') || "localhost";
        /* TODO: This code needs to be migrated away from dbus-json1 */
        self.client = cockpit.dbus(self.address, { payload: 'dbus-json1' });
        cockpit.set_watched_client(self.client);
        self.realm_manager = self.client.get("/com/redhat/Cockpit/Realms",
                                             "com.redhat.Cockpit.Realms");
        $(self.realm_manager).on("notify:Joined.realms", $.proxy(self, "update"));
        $(self.realm_manager).on("notify:Busy.realms", $.proxy(self, "update_busy"));

        $("#realms-leave-error").text("");
        self.update();
        self.update_busy();
        self.manager = self.client.get("/com/redhat/Cockpit/Manager",
                                       "com.redhat.Cockpit.Manager");

        function bindf(sel, object, prop, func) {
            function update() {
                $(sel).text(func(object[prop]));
            }
            $(object).on('notify:' + prop + '.system-information', update);
            update();
        }

        function bind(sel, object, prop) {
            bindf(sel, object, prop, function (s) { return s; });
        }

        bind("#system_information_hardware_text", self.manager, "System");
        bind("#system_information_asset_tag_text", self.manager, "SystemSerial");
        bind("#system_information_bios_text", self.manager, "BIOS");
        bind("#system_information_os_text", self.manager, "OperatingSystem");

        function hostname_text() {
            var pretty_hostname = self.manager.PrettyHostname;
            var hostname = self.manager.Hostname;
            var str;
            if (!pretty_hostname || pretty_hostname == hostname)
                str = hostname;
            else
                str = pretty_hostname + " (" + hostname + ")";
	    return str;
        }

        bindf("#system_information_hostname_text", self.manager, "Hostname", hostname_text);
        bindf("#system_information_hostname_text", self.manager, "PrettyHostname", hostname_text);

        function realms_text(val) {
            if (!val)
                return "?";

            var res = [ ];
            for (var i = 0; i < val.length; i++)
                res.push(val[i][0]);
            return res.join (", ");
        }

        function hide_buttons(val) {
            if (!val)
                return;

            if(val[0] === undefined){
                $(".realms-leave-spinner").hide();
                $("#realms-leave").hide();
                $("#realms-join").show();
            }
            else {
                $("#realms-join").hide();
                $("#realms-leave").show();
                $(".realms-leave-button").prop('disabled', false);
                $("#realms-op").modal('hide');
            }

        }

        self.realms = self.client.get("/com/redhat/Cockpit/Realms", "com.redhat.Cockpit.Realms");
        bindf("#system_information_realms", self.realms, "Joined", realms_text);

        $(self.realms).on('notify:Joined.system-information', function() {
            hide_buttons(self.realms['Joined']);
        });

        hide_buttons(self.realms['Joined']);
    },

    show: function() {
    },

    leave: function() {
        var self = this;

        function unbind(object) {
            $(object).off('.system-information');
        }

        unbind(self.manager);
        unbind(self.realms);

        cockpit.set_watched_client(null);
        self.client.release();
        self.client = null;
        self.manager = null;
        self.realms = null;
        $(self.realm_manager).off('.realms');
        self.realm_manager = null;
    }
};

function PageSystemInformation() {
    this._init();
}

cockpit.pages.push(new PageSystemInformation());

PageSystemInformationChangeHostname.prototype = {
    _init: function() {
        this.id = "system_information_change_hostname";
    },

    getTitle: function() {
        return C_("page-title", "Change Host Name");
    },

    setup: function() {
        $("#sich-pretty-hostname").on("keyup", $.proxy(this._on_full_name_changed, this));
        $("#sich-hostname").on("keyup", $.proxy(this._on_name_changed, this));
        $("#sich-apply-button").on("click", $.proxy(this._on_apply_button, this));
    },

    enter: function() {
        var self = this;

        self.manager = PageSystemInformationChangeHostname.client.get("/com/redhat/Cockpit/Manager",
                                                                      "com.redhat.Cockpit.Manager");
        self._initial_hostname = self.manager.Hostname || "";
        self._initial_pretty_hostname = self.manager.PrettyHostname || self._initial_hostname;
        $("#sich-pretty-hostname").val(self._initial_pretty_hostname);
        $("#sich-hostname").val(self._initial_hostname);

        this._always_update_from_pretty = false;
        this._update();
    },

    show: function() {
        $("#sich-pretty-hostname").focus();
    },

    leave: function() {
    },

    _on_apply_button: function(event) {
        var self = this;

        var new_full_name = $("#sich-pretty-hostname").val();
        var new_name = $("#sich-hostname").val();
        self.manager.call("SetHostname",
                          new_full_name, new_name, {},
                          function(error, reply) {
                              $("#system_information_change_hostname").modal('hide');
                              if(error) {
                                  cockpit.show_unexpected_error(error);
                              }
                          });
    },

    _on_full_name_changed: function(event) {
        /* Whenever the pretty host name has changed (e.g. the user has edited it), we compute a new
         * simple host name (e.g. 7bit ASCII, no special chars/spaces, lower case) from it...
         */
        var pretty_hostname = $("#sich-pretty-hostname").val();
        if (this._always_update_from_pretty || this._initial_pretty_hostname != pretty_hostname) {
            var new_hostname = pretty_hostname.toLowerCase().replace(/['"]+/g, "").replace(/[^a-zA-Z0-9]+/g, "-");
            $("#sich-hostname").val(new_hostname);
            this._always_update_from_pretty = true; // make sure we always update it from now-on
        }
        this._update();
    },

    _on_name_changed: function(event) {
        this._update();
    },

    _update: function() {
        var apply_button = $("#sich-apply-button");
        var note = $("#sich-note");
        var changed = false;
        var valid = false;
        var can_apply = false;

        var hostname = $("#sich-hostname").val();
        var pretty_hostname = $("#sich-pretty-hostname").val();

        if (hostname != this._initial_hostname ||
            pretty_hostname != this._initial_pretty_hostname)
            changed = true;

        if (hostname.match(/[a-z0-9-]*/) == hostname)
            valid = true;

        if (changed && valid)
            can_apply = true;

        if (valid)
            note.hide();
        else
            note.show();

        apply_button.prop('disabled', !can_apply);
    }
};

function PageSystemInformationChangeHostname() {
    this._init();
}

cockpit.pages.push(new PageSystemInformationChangeHostname());

}(cockpit, jQuery));
<|endoftext|>


<commit_before>/**
 * Experience Sampling consent page.
 */

var setupSurvey = {};  // Namespace variable
setupSurvey.CLOSE_TIME = 3600;  // One minute.
setupSurvey.status = constants.SETUP_PENDING;

/**
 * A helper method for updating the value in local storage.
 * @param {string} newState The desired new state for the setup pref.
 */
function setSetupStorageValue(newState) {
  var items = {};
  items[constants.SETUP_KEY] = newState;
  chrome.storage.local.set(items);
}

/**
 * Sets up the survey form based on the saved survey value.
 * @param {object} savedState Object possibly containing the setup status.
 */
function setupSurveyForm(savedState) {
  // Get the value from storage; save an initial value if empty.
  if (!savedState || savedState[constants.SETUP_KEY] == null) {
    setSetupStorageValue(constants.SETUP_PENDING);
  } else {
    setupSurvey.status = savedState[constants.SETUP_KEY];
  }
  console.log('Setup survey status: ' + setupSurvey.status);

  if (setupSurvey.status == constants.SETUP_PENDING) {
    // Show the survey.
    $('explanation').classList.remove('hidden');
    $('survey-container').classList.remove('hidden');
    document.forms['survey-form'].addEventListener(
        'submit', setupFormSubmitted);
  } else if (setupSurvey.status == constants.SETUP_COMPLETED) {
    // Show a notice that the survey was already completed.
    $('already-completed').classList.remove('hidden');
    setTimeout(window.close, setupSurvey.CLOSE_TIME);
  }
}

/**
 * Handles the submission of the setup survey.
 * @param {object} The submission button click event.
 */
function setupFormSubmitted(event) {
  event.preventDefault();
  setSetupStorageValue(constants.SETUP_COMPLETED);
  $('explanation').classList.add('hidden');
  $('survey-container').classList.add('hidden');
  $('thank-you').classList.remove('hidden');
  setTimeout(window.close, setupSurvey.CLOSE_TIME);
}

/**
 * Looks up values from local storage to set up the initial state. This should
 * be the first method called when the page is loaded.
 */
function getInitialState() {
  console.log('Setup survey loading');
  chrome.storage.local.get(constants.SETUP_KEY, setupSurveyForm);
}

document.addEventListener('DOMContentLoaded', getInitialState);
<commit_msg>Fixed time<commit_after>/**
 * Experience Sampling consent page.
 */

var setupSurvey = {};  // Namespace variable
setupSurvey.CLOSE_TIME = 3000;  // Half a minute, in milliseconds
setupSurvey.status = constants.SETUP_PENDING;

/**
 * A helper method for updating the value in local storage.
 * @param {string} newState The desired new state for the setup pref.
 */
function setSetupStorageValue(newState) {
  var items = {};
  items[constants.SETUP_KEY] = newState;
  chrome.storage.local.set(items);
}

/**
 * Sets up the survey form based on the saved survey value.
 * @param {object} savedState Object possibly containing the setup status.
 */
function setupSurveyForm(savedState) {
  // Get the value from storage; save an initial value if empty.
  if (!savedState || savedState[constants.SETUP_KEY] == null) {
    setSetupStorageValue(constants.SETUP_PENDING);
  } else {
    setupSurvey.status = savedState[constants.SETUP_KEY];
  }
  console.log('Setup survey status: ' + setupSurvey.status);

  if (setupSurvey.status == constants.SETUP_PENDING) {
    // Show the survey.
    $('explanation').classList.remove('hidden');
    $('survey-container').classList.remove('hidden');
    document.forms['survey-form'].addEventListener(
        'submit', setupFormSubmitted);
  } else if (setupSurvey.status == constants.SETUP_COMPLETED) {
    // Show a notice that the survey was already completed.
    $('already-completed').classList.remove('hidden');
    setTimeout(window.close, setupSurvey.CLOSE_TIME);
  }
}

/**
 * Handles the submission of the setup survey.
 * @param {object} The submission button click event.
 */
function setupFormSubmitted(event) {
  event.preventDefault();
  setSetupStorageValue(constants.SETUP_COMPLETED);
  $('explanation').classList.add('hidden');
  $('survey-container').classList.add('hidden');
  $('thank-you').classList.remove('hidden');
  setTimeout(window.close, setupSurvey.CLOSE_TIME);
}

/**
 * Looks up values from local storage to set up the initial state. This should
 * be the first method called when the page is loaded.
 */
function getInitialState() {
  console.log('Setup survey loading');
  chrome.storage.local.get(constants.SETUP_KEY, setupSurveyForm);
}

document.addEventListener('DOMContentLoaded', getInitialState);
<|endoftext|>


<commit_before>import Ember from 'ember';

import Base from 'ember-simple-auth/authenticators/base';
import config from 'ember-get-config';

import { authenticatedAJAX } from 'ember-osf/utils/ajax-helpers';

/**
 * @module ember-osf
 * @submodule authenticators
 */

/**
 * Ember-simple-auth compatible authenticator based on session cookie.
 *
 * Intended to be used with the authorizer of the same name.
 *
 * @class OsfCookieAuthenticator
 * @extends ember-simple-auth/BaseAuthenticator
 */
export default Base.extend({
    // HACK: Lets us clear session manually, rather than after .invalidate method resolves
    store: Ember.inject.service(),
    session: Ember.inject.service(),

    _test() {
        return authenticatedAJAX({
            method: 'GET',
            url: `${config.OSF.apiUrl}/${config.OSF.apiNamespace}/`,
            dataType: 'json',
            contentType: 'application/json',
            xhrFields: {
                withCredentials: true
            }
        }).then(res => {
            // Push the result into the store for later use by the current-user service
            // Note: we have to deepcopy res because pushPayload mutates our data
            // and causes an infinite loop because reasons
            if (res['meta']['current_user'] !== null ){
                this.get('store').pushPayload(Ember.copy(res['meta']['current_user'], true));
            } else {
                return Ember.RSVP.reject();
            }
            return res.data;
        });
    },
    restore(/* data */) {
        return this._test().fail(this.invalidate);
    },

    /**
     * Send a request to the flask application to trigger invalidation of session remotely
     * @method invalidate
     */
    invalidate(data) {
        if (!data || data.id && data.status !== 401) {
            // If invalidate is called when loading the page to check if a cookie has permissions, don't redirect the user
            // But if invalidate is called without arguments, or for any other reason, interpret this as a straight logout request
            //   (and let the session get invalidated next time at the start of first page load)
            // Can't do this via AJAX request because it redirects to CAS, and AJAX + redirect = CORS issue

            // Manually clear session before user leaves the page, since we aren't sticking around for ESA to do so later
            return this.get('session.session')._clear(true);
        } else {
            // This branch is expected to be called when a test request reveals the user to lack permissions... so session should be wiped
            return Ember.RSVP.resolve();
        }
    },
    /**
     * For now, simply verify that a token is present and can be used
     * @method authenticate
     * @param code
     * @return {Promise}
     */
    authenticate(code) {
        // NOTE: Must be wrapped in an RSVP promise
        // _test returns a Jquery Promise but authenticate expects an RSVP Promise
        return new Ember.RSVP.Promise((resolve, reject) =>
            this._test(code).then(resolve).fail(reject)
        );
    }
});
<commit_msg>return the correct data from _test<commit_after>import Ember from 'ember';

import Base from 'ember-simple-auth/authenticators/base';
import config from 'ember-get-config';

import { authenticatedAJAX } from 'ember-osf/utils/ajax-helpers';

/**
 * @module ember-osf
 * @submodule authenticators
 */

/**
 * Ember-simple-auth compatible authenticator based on session cookie.
 *
 * Intended to be used with the authorizer of the same name.
 *
 * @class OsfCookieAuthenticator
 * @extends ember-simple-auth/BaseAuthenticator
 */
export default Base.extend({
    // HACK: Lets us clear session manually, rather than after .invalidate method resolves
    store: Ember.inject.service(),
    session: Ember.inject.service(),

    _test() {
        return authenticatedAJAX({
            method: 'GET',
            url: `${config.OSF.apiUrl}/${config.OSF.apiNamespace}/`,
            dataType: 'json',
            contentType: 'application/json',
            xhrFields: {
                withCredentials: true
            }
        }).then(res => {
            // Push the result into the store for later use by the current-user service
            // Note: we have to deepcopy res because pushPayload mutates our data
            // and causes an infinite loop because reasons
            if (res['meta']['current_user'] !== null ){
                this.get('store').pushPayload(Ember.copy(res['meta']['current_user'], true));
            } else {
                return Ember.RSVP.reject();
            }
            return res['meta']['current_user']['data'];
        });
    },
    restore(/* data */) {
        return this._test().fail(this.invalidate);
    },

    /**
     * Send a request to the flask application to trigger invalidation of session remotely
     * @method invalidate
     */
    invalidate(data) {
        if (!data || data.id && data.status !== 401) {
            // If invalidate is called when loading the page to check if a cookie has permissions, don't redirect the user
            // But if invalidate is called without arguments, or for any other reason, interpret this as a straight logout request
            //   (and let the session get invalidated next time at the start of first page load)
            // Can't do this via AJAX request because it redirects to CAS, and AJAX + redirect = CORS issue

            // Manually clear session before user leaves the page, since we aren't sticking around for ESA to do so later
            return this.get('session.session')._clear(true);
        } else {
            // This branch is expected to be called when a test request reveals the user to lack permissions... so session should be wiped
            return Ember.RSVP.resolve();
        }
    },
    /**
     * For now, simply verify that a token is present and can be used
     * @method authenticate
     * @param code
     * @return {Promise}
     */
    authenticate(code) {
        // NOTE: Must be wrapped in an RSVP promise
        // _test returns a Jquery Promise but authenticate expects an RSVP Promise
        return new Ember.RSVP.Promise((resolve, reject) =>
            this._test(code).then(resolve).fail(reject)
        );
    }
});
<|endoftext|>


<commit_before>'use strict';
'require view';
'require dom';
'require fs';
'require ui';
'require uci';
'require network';

return view.extend({
	handleCommand: function(exec, args) {
		var buttons = document.querySelectorAll('.diag-action > .cbi-button');

		for (var i = 0; i < buttons.length; i++)
			buttons[i].setAttribute('disabled', 'true');

		return fs.exec(exec, args).then(function(res) {
			var out = document.querySelector('.command-output');
			    out.style.display = '';

			dom.content(out, [ res.stdout || '', res.stderr || '' ]);
		}).catch(function(err) {
			ui.addNotification(null, E('p', [ err ]))
		}).finally(function() {
			for (var i = 0; i < buttons.length; i++)
				buttons[i].removeAttribute('disabled');
		});
	},

	handlePing: function(ev, cmd) {
		var exec = cmd || 'ping',
		    addr = ev.currentTarget.parentNode.previousSibling.value,
		    args = (exec == 'ping') ? [ '-4', '-c', '5', '-W', '1', addr ] : [ '-6', '-c', '5', addr ];

		return this.handleCommand(exec, args);
	},

	handleTraceroute: function(ev, cmd) {
		var exec = cmd || 'traceroute',
		    addr = ev.currentTarget.parentNode.previousSibling.value,
		    args = (exec == 'traceroute') ? [ '-4', '-q', '1', '-w', '1', '-n', '-m', String(L.env.rpctimeout || 20), addr ] : [ '-q', '1', '-w', '2', '-n', addr ];

		return this.handleCommand(exec, args);
	},

	handleNslookup: function(ev, cmd) {
		var addr = ev.currentTarget.parentNode.previousSibling.value;

		return this.handleCommand('nslookup', [ addr ]);
	},

	handleArpScan: function(ev, cmd) {
		var addr = ev.currentTarget.parentNode.previousSibling.value;

		return this.handleCommand('arp-scan', [ '-l', '-I', addr ]);
	},

	load: function() {
		return Promise.all([
			L.resolveDefault(fs.stat('/bin/ping6'), {}),
			L.resolveDefault(fs.stat('/usr/bin/ping6'), {}),
			L.resolveDefault(fs.stat('/bin/traceroute6'), {}),
			L.resolveDefault(fs.stat('/usr/bin/traceroute6'), {}),
			L.resolveDefault(fs.stat('/usr/bin/arp-scan'), {}),
			network.getDevices(),
			uci.load('luci')
		]);
	},

	render: function(res) {
		var has_ping6 = res[0].path || res[1].path,
		    has_traceroute6 = res[2].path || res[3].path,
		    has_arpscan = res[4].path,
		    devices = res[5],
			dns_host = uci.get('luci', 'diag', 'dns') || 'openwrt.org',
			ping_host = uci.get('luci', 'diag', 'ping') || 'openwrt.org',
			route_host = uci.get('luci', 'diag', 'route') || 'openwrt.org';

		return E([], [
			E('h2', {}, [ _('Network Utilities') ]),
			E('table', { 'class': 'table' }, [
				E('tr', { 'class': 'tr' }, [
					E('td', { 'class': 'td left' }, [
						E('input', {
							'style': 'margin:5px 0',
							'type': 'text',
							'value': ping_host
						}),
						E('span', { 'class': 'diag-action' }, [
							has_ping6 ? new ui.ComboButton('ping', {
								'ping': '%s %s'.format(_('IPv4'), _('Ping')),
								'ping6': '%s %s'.format(_('IPv6'), _('Ping')),
							}, {
								'click': ui.createHandlerFn(this, 'handlePing'),
								'classes': {
									'ping': 'btn cbi-button cbi-button-action',
									'ping6': 'btn cbi-button cbi-button-action'
								}
							}).render() : E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handlePing')
							}, [ _('Ping') ])
						])
					]),

					E('td', { 'class': 'td left' }, [
						E('input', {
							'style': 'margin:5px 0',
							'type': 'text',
							'value': route_host
						}),
						E('span', { 'class': 'diag-action' }, [
							has_traceroute6 ? new ui.ComboButton('traceroute', {
								'traceroute': '%s %s'.format(_('IPv4'), _('Traceroute')),
								'traceroute6': '%s %s'.format(_('IPv6'), _('Traceroute')),
							}, {
								'click': ui.createHandlerFn(this, 'handleTraceroute'),
								'classes': {
									'traceroute': 'btn cbi-button cbi-button-action',
									'traceroute6': 'btn cbi-button cbi-button-action'
								}
							}).render() : E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handleTraceroute')
							}, [ _('Traceroute') ])
						])
					]),

					E('td', { 'class': 'td left' }, [
						E('input', {
							'style': 'margin:5px 0',
							'type': 'text',
							'value': dns_host
						}),
						E('span', { 'class': 'diag-action' }, [
							E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handleNslookup')
							}, [ _('Nslookup') ])
						])
					]),

					has_arpscan ? E('td', { 'class': 'td left' }, [
						E('select', {
							'style': 'margin:5px 0'
						}, devices.map(function(device) {
							if (!device.isUp())
								return E([]);

							return E('option', { 'value': device.getName() }, [ device.getI18n() ]);
						})),
						E('span', { 'class': 'diag-action' }, [
							E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handleArpScan')
							}, [ _('Arp-scan') ])
						])
					]) : E([]),
				])
			]),
			E('pre', { 'class': 'command-output', 'style': 'display:none' })
		]);
	},

	handleSaveApply: null,
	handleSave: null,
	handleReset: null
});
<commit_msg>luci-mod-network: convert diagnostic page to LuCI look and feel<commit_after>'use strict';
'require view';
'require dom';
'require fs';
'require ui';
'require uci';
'require network';

return view.extend({
	handleCommand: function(exec, args) {
		var buttons = document.querySelectorAll('.diag-action > .cbi-button');

		for (var i = 0; i < buttons.length; i++)
			buttons[i].setAttribute('disabled', 'true');

		return fs.exec(exec, args).then(function(res) {
			var out = document.querySelector('textarea');

			dom.content(out, [ res.stdout || '', res.stderr || '' ]);
		}).catch(function(err) {
			ui.addNotification(null, E('p', [ err ]))
		}).finally(function() {
			for (var i = 0; i < buttons.length; i++)
				buttons[i].removeAttribute('disabled');
		});
	},

	handlePing: function(ev, cmd) {
		var exec = cmd || 'ping',
		    addr = ev.currentTarget.parentNode.previousSibling.value,
		    args = (exec == 'ping') ? [ '-4', '-c', '5', '-W', '1', addr ] : [ '-6', '-c', '5', addr ];

		return this.handleCommand(exec, args);
	},

	handleTraceroute: function(ev, cmd) {
		var exec = cmd || 'traceroute',
		    addr = ev.currentTarget.parentNode.previousSibling.value,
		    args = (exec == 'traceroute') ? [ '-4', '-q', '1', '-w', '1', '-n', '-m', String(L.env.rpctimeout || 20), addr ] : [ '-q', '1', '-w', '2', '-n', addr ];

		return this.handleCommand(exec, args);
	},

	handleNslookup: function(ev, cmd) {
		var addr = ev.currentTarget.parentNode.previousSibling.value;

		return this.handleCommand('nslookup', [ addr ]);
	},

	handleArpScan: function(ev, cmd) {
		var addr = ev.currentTarget.parentNode.previousSibling.value;

		return this.handleCommand('arp-scan', [ '-l', '-I', addr ]);
	},

	load: function() {
		return Promise.all([
			L.resolveDefault(fs.stat('/bin/ping6'), {}),
			L.resolveDefault(fs.stat('/usr/bin/ping6'), {}),
			L.resolveDefault(fs.stat('/bin/traceroute6'), {}),
			L.resolveDefault(fs.stat('/usr/bin/traceroute6'), {}),
			L.resolveDefault(fs.stat('/usr/bin/arp-scan'), {}),
			network.getDevices(),
			uci.load('luci')
		]);
	},

	render: function(res) {
		var has_ping6 = res[0].path || res[1].path,
		    has_traceroute6 = res[2].path || res[3].path,
		    has_arpscan = res[4].path,
		    devices = res[5],
			dns_host = uci.get('luci', 'diag', 'dns') || 'openwrt.org',
			ping_host = uci.get('luci', 'diag', 'ping') || 'openwrt.org',
			route_host = uci.get('luci', 'diag', 'route') || 'openwrt.org';

		var table = E('table', { 'class': 'table' }, [
				E('tr', { 'class': 'tr' }, [
					E('td', { 'class': 'td left' }, [
						E('input', {
							'style': 'margin:5px 0',
							'type': 'text',
							'value': ping_host
						}),
						E('span', { 'class': 'diag-action' }, [
							has_ping6 ? new ui.ComboButton('ping', {
								'ping': '%s %s'.format(_('IPv4'), _('Ping')),
								'ping6': '%s %s'.format(_('IPv6'), _('Ping')),
							}, {
								'click': ui.createHandlerFn(this, 'handlePing'),
								'classes': {
									'ping': 'btn cbi-button cbi-button-action',
									'ping6': 'btn cbi-button cbi-button-action'
								}
							}).render() : E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handlePing')
							}, [ _('Ping') ])
						])
					]),

					E('td', { 'class': 'td left' }, [
						E('input', {
							'style': 'margin:5px 0',
							'type': 'text',
							'value': route_host
						}),
						E('span', { 'class': 'diag-action' }, [
							has_traceroute6 ? new ui.ComboButton('traceroute', {
								'traceroute': '%s %s'.format(_('IPv4'), _('Traceroute')),
								'traceroute6': '%s %s'.format(_('IPv6'), _('Traceroute')),
							}, {
								'click': ui.createHandlerFn(this, 'handleTraceroute'),
								'classes': {
									'traceroute': 'btn cbi-button cbi-button-action',
									'traceroute6': 'btn cbi-button cbi-button-action'
								}
							}).render() : E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handleTraceroute')
							}, [ _('Traceroute') ])
						])
					]),

					E('td', { 'class': 'td left' }, [
						E('input', {
							'style': 'margin:5px 0',
							'type': 'text',
							'value': dns_host
						}),
						E('span', { 'class': 'diag-action' }, [
							E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handleNslookup')
							}, [ _('Nslookup') ])
						])
					]),

					has_arpscan ? E('td', { 'class': 'td left' }, [
						E('select', {
							'style': 'margin:5px 0'
						}, devices.map(function(device) {
							if (!device.isUp())
								return E([]);

							return E('option', { 'value': device.getName() }, [ device.getI18n() ]);
						})),
						E('span', { 'class': 'diag-action' }, [
							E('button', {
								'class': 'cbi-button cbi-button-action',
								'click': ui.createHandlerFn(this, 'handleArpScan')
							}, [ _('Arp-scan') ])
						])
					]) : E([]),
				])
			]);

		var view = E('div', { 'class': 'cbi-map'}, [
			E('h2', {}, [ _('Diagnostics') ]),
			E('div', { 'class': 'cbi-map-descr'}, _('Execution of various network commands to check the connection and name resolution to other systems.')),
			table,
			E('div', {'class': 'cbi-section'}, [
				E('div', { 'id' : 'command-output'},
					E('textarea', {
						'id': 'widget.command-output',
						'style': 'width: 100%',
						'readonly': true,
						'wrap': 'off',
						'rows': '20'
					})
				)
			])
		]);

		return view;
	},

	handleSaveApply: null,
	handleSave: null,
	handleReset: null
});
<|endoftext|>