def createWmsSource(self, params): name = params['name'] baseURL = params['baseURL'] parsedUrl = getUrlParts(baseURL) hostName = parsedUrl.netloc username = params['username'] if 'username' in params else None password = params['password'] if 'password' in params else None wms = WebMapService(baseURL, version='1.1.1', username=username, password=password ) layersType = list(wms.contents) layers = [] for layerType in layersType: layer = { 'layer_title': wms[layerType].title, 'layer_type': layerType } layers.append(layer) minerva_metadata = { 'source_type': 'wms', 'layers': layers, 'wms_params': { 'base_url': baseURL, 'host_name': hostName } } if username and password: credentials = encryptCredentials("{}:{}".format( username, password)) minerva_metadata['wms_params']['credentials'] = credentials desc = 'wms source for %s' % name return self.createSource(name, minerva_metadata, desc)
def initializeOtp(self, user): """ Initialize the use of one-time passwords with this user. This does not save the modified user model. :param user: The user to modify. :return: The new OTP keys, each in KeyUriFormat. :rtype: dict """ totp = self._TotpFactory.new() user['otp'] = {'enabled': False, 'totp': totp.to_dict()} # Use the brand name as the OTP issuer if it's non-default (since that's prettier and more # meaningful for users), but fallback to the site hostname if the brand name isn't set # (to disambiguate otherwise identical "Girder" issuers) # Prevent circular import from girder.api.rest import getUrlParts brandName = Setting().get(SettingKey.BRAND_NAME) defaultBrandName = Setting().getDefault(SettingKey.BRAND_NAME) # OTP URIs ( https://github.com/google/google-authenticator/wiki/Key-Uri-Format ) do not # allow colons, so use only the hostname component serverHostname = getUrlParts().netloc.partition(':')[0] # Normally, the issuer would be set when "self._TotpFactory" is instantiated, but that # happens during model initialization, when there's no current request, so the server # hostname is not known then otpIssuer = brandName if brandName != defaultBrandName else serverHostname return {'totpUri': totp.to_uri(label=user['login'], issuer=otpIssuer)}
def initializeOtp(self, user): """ Initialize the use of one-time passwords with this user. This does not save the modified user model. :param user: The user to modify. :return: The new OTP keys, each in KeyUriFormat. :rtype: dict """ totp = self._TotpFactory.new() user['otp'] = { 'enabled': False, 'totp': totp.to_dict() } # Use the brand name as the OTP issuer if it's non-default (since that's prettier and more # meaningful for users), but fallback to the site hostname if the brand name isn't set # (to disambiguate otherwise identical "Girder" issuers) # Prevent circular import from girder.api.rest import getUrlParts brandName = Setting().get(SettingKey.BRAND_NAME) defaultBrandName = Setting().getDefault(SettingKey.BRAND_NAME) # OTP URIs ( https://github.com/google/google-authenticator/wiki/Key-Uri-Format ) do not # allow colons, so use only the hostname component serverHostname = getUrlParts().netloc.partition(':')[0] # Normally, the issuer would be set when "self._TotpFactory" is instantiated, but that # happens during model initialization, when there's no current request, so the server # hostname is not known then otpIssuer = brandName if brandName != defaultBrandName else serverHostname return { 'totpUri': totp.to_uri(label=user['login'], issuer=otpIssuer) }
def createWmsSource(self, params): name = params['name'] baseURL = params['baseURL'] parsedUrl = getUrlParts(baseURL) hostName = parsedUrl.netloc username = params['username'] if 'username' in params else None password = params['password'] if 'password' in params else None wms = WebMapService(baseURL, version='1.1.1', username=username, password=password) layersType = list(wms.contents) layers = [] source = self._sourceMetadata(username, password, baseURL, hostName) source['layer_source'] = name for layerType in layersType: dataset = self.createWmsDataset(source, params={ 'typeName': layerType, 'name': wms[layerType].title, 'abstract': wms[layerType].abstract}) layers.append(dataset) return layers
def createWmsDataset(self, wmsSource, params): # Get layer legend (TODO// Include authentication in the future) # Legend to be included in the metadata? baseURL = wmsSource['meta']['minerva']['wms_params']['base_url'] parsedUrl = getUrlParts(baseURL) hostName = parsedUrl.netloc typeName = params['typeName'] conn = httplib.HTTPConnection(hostName) conn.request("GET", "/geoserver/ows?service=WMS&request=" + "GetLegendGraphic&format=image" + "%2Fpng&width=20&height=20&layer=" + typeName ) response = conn.getresponse() legend = binascii.b2a_base64(response.read()) self.requireParams(('name'), params) name = params['name'] minerva_metadata = { 'dataset_type': 'wms', 'legend': legend, 'source_id': wmsSource['_id'], 'type_name': typeName, 'base_url': baseURL } dataset = self.constructDataset(name, minerva_metadata) return dataset
def createWmsSource(self, params): name = params['name'] baseURL = params['baseURL'] parsedUrl = getUrlParts(baseURL) hostName = parsedUrl.netloc username = params['username'] if 'username' in params else None password = params['password'] if 'password' in params else None wms = WebMapService(baseURL, version='1.1.1', username=username, password=password) layersType = list(wms.contents) layers = [] source = self._sourceMetadata(username, password, baseURL, hostName) source['layer_source'] = name for layerType in layersType: dataset = self.createWmsDataset(source, params={ 'typeName': layerType, 'name': wms[layerType].title, 'abstract': wms[layerType].abstract, 'category': self._get_category(wms[layerType]), 'metadata': self._get_metadata(wms[layerType])}) layers.append(dataset) return layers
def createWmsDataset(self, wmsSource, params): baseURL = wmsSource['wms_params']['base_url'] parsedUrl = getUrlParts(baseURL) typeName = params['typeName'] try: if params['metadata']: layer_info = params['metadata'] else: layer_info = WmsStyle(typeName, baseURL).get_layer_info() except TypeError: layer_info = "" if 'credentials' in wmsSource['wms_params']: credentials = (wmsSource['wms_params']['credentials']) basic_auth = 'Basic ' + b64encode(decryptCredentials(credentials)) headers = {'Authorization': basic_auth} else: headers = {} credentials = None request_url = parsedUrl.scheme + '://' + parsedUrl.netloc + \ parsedUrl.path r = requests.get(request_url, params={ 'service': 'WMS', 'request': 'GetLegendGraphic', 'format': 'image/png', 'width': 20, 'height': 20, 'layer': params['typeName'] }, headers=headers) legend = b64encode(r.content) self.requireParams(('name'), params) name = params['name'] minerva_metadata = { 'dataset_type': 'wms', 'legend': legend, 'source': wmsSource, 'type_name': typeName, 'base_url': baseURL, 'layer_info': layer_info, 'abstract': params['abstract'], 'category': params['category'] } if credentials: minerva_metadata['credentials'] = credentials dataset = self.constructDataset(name, minerva_metadata) return dataset
def createWmsDataset(self, wmsSource, params): baseURL = wmsSource['wms_params']['base_url'] parsedUrl = getUrlParts(baseURL) typeName = params['typeName'] try: if params['metadata']: layer_info = params['metadata'] else: layer_info = WmsStyle(typeName, baseURL).get_layer_info() except TypeError: layer_info = "" if 'credentials' in wmsSource['wms_params']: credentials = ( wmsSource['wms_params']['credentials'] ) basic_auth = 'Basic ' + b64encode(decryptCredentials(credentials)) headers = {'Authorization': basic_auth} else: headers = {} credentials = None request_url = parsedUrl.scheme + '://' + parsedUrl.netloc + \ parsedUrl.path r = requests.get(request_url, params={ 'service': 'WMS', 'request': 'GetLegendGraphic', 'format': 'image/png', 'width': 20, 'height': 20, 'layer': params['typeName']}, headers=headers) legend = b64encode(r.content) self.requireParams(('name'), params) name = params['name'] minerva_metadata = { 'dataset_type': 'wms', 'legend': legend, 'source': wmsSource, 'type_name': typeName, 'base_url': baseURL, 'layer_info': layer_info, 'abstract': params['abstract'], 'category': params['category'] } if credentials: minerva_metadata['credentials'] = credentials dataset = self.constructDataset(name, minerva_metadata) return dataset
def testGetApiUrl(self): url = 'https://localhost/thing/api/v1/hello/world?foo=bar#test' self.assertEqual(rest.getApiUrl(url), 'https://localhost/thing/api/v1') parts = rest.getUrlParts(url) self.assertEqual(parts.path, '/thing/api/v1/hello/world') self.assertEqual(rest.getApiUrl(parts.path), '/thing/api/v1') self.assertEqual(parts.port, None) self.assertEqual(parts.hostname, 'localhost') self.assertEqual(parts.query, 'foo=bar') self.assertEqual(parts.fragment, 'test') url = 'https://localhost/girder#users' self.assertRaises(Exception, rest.getApiUrl, url=url)
def testGetApiUrl(): url = 'https://localhost/thing/api/v1/hello/world?foo=bar#test' assert rest.getApiUrl(url) == 'https://localhost/thing/api/v1' parts = rest.getUrlParts(url) assert parts.path == '/thing/api/v1/hello/world' assert rest.getApiUrl(parts.path) == '/thing/api/v1' assert parts.port is None assert parts.hostname == 'localhost' assert parts.query == 'foo=bar' assert parts.fragment == 'test' url = 'https://localhost/girder#users' with pytest.raises(GirderException, match='Could not determine API root in %s.$' % url): rest.getApiUrl(url)
def createWmsSource(self, params): name = params["name"] baseURL = params["baseURL"] parsedUrl = getUrlParts(baseURL) hostName = parsedUrl.netloc username = params["username"] if "username" in params else None password = params["password"] if "password" in params else None wms = WebMapService(baseURL, version="1.1.1", username=username, password=password) layersType = list(wms.contents) layers = [] for layerType in layersType: layer = {"layer_title": wms[layerType].title, "layer_type": layerType} layers.append(layer) minerva_metadata = { "source_type": "wms", "layers": layers, "wms_params": {"base_url": baseURL, "host_name": hostName}, } desc = "wms source for %s" % name return self.createSource(name, minerva_metadata, desc)
def tileServerURL(self, image, width=None): image_file = self.multiresolutionFile(image) assetstore = self.model('assetstore').load(image_file['assetstoreId']) file_path = os.path.join(assetstore['root'], image_file['path']) # the ordering of query string parameters to IIP critically matters query_params = collections.OrderedDict() query_params['FIF'] = file_path if width: query_params['WID'] = width query_params['CVT'] = 'jpeg' # TODO: this won't work if the server's DNS doesn't know its own canonical hostname current_location = getUrlParts() url = Url( scheme=current_location.scheme, host=current_location.netloc, port=None, path='/fcgi-bin/iipsrv.fcgi', query='&'.join('%s=%s' % item for item in query_params.viewitems()) ) return url.url
def createElasticsearchSource(self, params): name = params['name'] baseURL = params['baseURL'] parsedUrl = getUrlParts(baseURL) hostName = parsedUrl.netloc index = params['index'] username = params['username'] if 'username' in params else None password = params['password'] if 'password' in params else None minerva_metadata = { 'source_type': 'elasticsearch', 'elasticsearch_params': { 'index': index, 'base_url': baseURL, 'host_name': hostName } } if username and password: enc_creds = encryptCredentials("{}:{}".format( username, password)) minerva_metadata['elasticsearch_params']['credentials'] = enc_creds desc = 'elasticsearch source for %s' % name return self.createSource(name, minerva_metadata, desc)
def createWmsDataset(self, wmsSource, params): baseURL = wmsSource['meta']['minerva']['wms_params']['base_url'] parsedUrl = getUrlParts(baseURL) typeName = params['typeName'] if 'credentials' in wmsSource['meta']['minerva']['wms_params']: credentials = ( wmsSource['meta']['minerva']['wms_params']['credentials'] ) basic_auth = 'Basic ' + b64encode(decryptCredentials(credentials)) headers = {'Authorization': basic_auth} else: headers = {} credentials = None conn = httplib.HTTPConnection(parsedUrl.netloc) conn.request("GET", parsedUrl.path + "?service=WMS&request=" + "GetLegendGraphic&format=image" + "%2Fpng&width=20&height=20&layer=" + typeName, headers=headers ) response = conn.getresponse() legend = binascii.b2a_base64(response.read()) self.requireParams(('name'), params) name = params['name'] minerva_metadata = { 'dataset_type': 'wms', 'legend': legend, 'source_id': wmsSource['_id'], 'type_name': typeName, 'base_url': baseURL } if credentials: minerva_metadata['credentials'] = credentials dataset = self.constructDataset(name, minerva_metadata) return dataset
def createPostgresSource(self, params): name = params['name'] baseURL = params['baseURL'] parsedUrl = getUrlParts(baseURL) hostName = parsedUrl.netloc dbname = params['dbname'] username = params['username'] if 'username' in params else None password = params['password'] if 'password' in params else None minerva_metadata = { 'source_type': 'postgres', 'postgres_params': { 'dbname': dbname, 'base_url': baseURL, 'host_name': hostName } } if username and password: enc_creds = encryptCredentials("{}:{}".format( username, password)) minerva_metadata['postgres_params']['credentials'] = enc_creds desc = 'postgres source for %s' % name return self.createSource(name, minerva_metadata, desc)
def runClimos(self, inFolder, outFolder, params): self.requireParams(('seasons', 'vars', 'outputFilename'), params) user = self.getCurrentUser() urlParts = rest.getUrlParts() apiUrl = rest.getApiUrl() jobModel = self.model('job', 'jobs') job = jobModel.createJob(title='Climos: ' + inFolder['name'], type='climos', handler='romanesco_handler', user=user) token = self.model('token').createToken(user=user, days=3) task = { 'mode': 'python', 'script': _climos_script, 'inputs': [{ 'id': 'in_dir', 'type': 'string', 'format': 'text' }, { 'id': 'out_filename', 'type': 'string', 'format': 'text' }, { 'id': 'variables', 'type': 'python', 'format': 'object' }, { 'id': 'seasons', 'type': 'python', 'format': 'object' }], 'outputs': [{ 'id': 'outfile', 'type': 'string', 'format': 'text' }] } girderIoParams = { 'mode': 'girder', 'host': urlParts.hostname, 'port': urlParts.port, 'api_root': rest.getApiUrl(urlParts.path), 'scheme': urlParts.scheme, 'token': token['_id'] } inputs = { 'in_dir': dict( girderIoParams, **{ 'method': 'GET', 'id': str(inFolder['_id']), 'resource_type': 'folder', 'type': 'string', 'format': 'text', 'name': inFolder['name'] }), 'seasons': { 'mode': 'inline', 'type': 'python', 'format': 'object', 'data': json.loads(params['seasons']) }, 'variables': { 'mode': 'inline', 'type': 'python', 'format': 'object', 'data': json.loads(params['vars']) }, 'out_filename': { 'mode': 'inline', 'type': 'string', 'format': 'text', 'data': params['outputFilename'].strip() } } outputs = { 'outfile': dict( girderIoParams, **{ 'parent_type': 'folder', 'parent_id': str(outFolder['_id']), 'format': 'text', 'type': 'string' }) } job['kwargs'] = { 'task': task, 'inputs': inputs, 'outputs': outputs, 'jobInfo': { 'method': 'PUT', 'url': '/'.join((apiUrl, 'job', str(job['_id']))), 'headers': { 'Girder-Token': token['_id'] }, 'logPrint': True }, 'validate': False, 'auto_convert': True, 'cleanup': True } job = jobModel.save(job) jobModel.scheduleJob(job) return jobModel.filter(job, user)
def runClimos(self, inFolder, outFolder, params): self.requireParams(('seasons', 'vars', 'outputFilename'), params) user = self.getCurrentUser() urlParts = rest.getUrlParts() apiUrl = rest.getApiUrl() jobModel = self.model('job', 'jobs') job = jobModel.createJob( title='Climos: ' + inFolder['name'], type='climos', handler='romanesco_handler', user=user) token = self.model('token').createToken(user=user, days=3) task = { 'mode': 'python', 'script': _climos_script, 'inputs': [{ 'id': 'in_dir', 'type': 'string', 'format': 'text' }, { 'id': 'out_filename', 'type': 'string', 'format': 'text' }, { 'id': 'variables', 'type': 'python', 'format': 'object' }, { 'id': 'seasons', 'type': 'python', 'format': 'object' }], 'outputs': [{ 'id': 'outfile', 'type': 'string', 'format': 'text' }] } girderIoParams = { 'mode': 'girder', 'host': urlParts.hostname, 'port': urlParts.port, 'api_root': rest.getApiUrl(urlParts.path), 'scheme': urlParts.scheme, 'token': token['_id'] } inputs = { 'in_dir': dict(girderIoParams, **{ 'method': 'GET', 'id': str(inFolder['_id']), 'resource_type': 'folder', 'type': 'string', 'format': 'text', 'name': inFolder['name'] }), 'seasons': { 'mode': 'inline', 'type': 'python', 'format': 'object', 'data': json.loads(params['seasons']) }, 'variables': { 'mode': 'inline', 'type': 'python', 'format': 'object', 'data': json.loads(params['vars']) }, 'out_filename': { 'mode': 'inline', 'type': 'string', 'format': 'text', 'data': params['outputFilename'].strip() } } outputs = { 'outfile': dict(girderIoParams, **{ 'parent_type': 'folder', 'parent_id': str(outFolder['_id']), 'format': 'text', 'type': 'string' }) } job['kwargs'] = { 'task': task, 'inputs': inputs, 'outputs': outputs, 'jobInfo': { 'method': 'PUT', 'url': '/'.join((apiUrl, 'job', str(job['_id']))), 'headers': {'Girder-Token': token['_id']}, 'logPrint': True }, 'validate': False, 'auto_convert': True, 'cleanup': True } job = jobModel.save(job) jobModel.scheduleJob(job) return jobModel.filter(job, user)