1# Copyright (c) 2012 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import json 6import logging 7import urlparse 8from sdk_update_common import Error 9 10SOURCE_WHITELIST = [ 11 'http://localhost/', # For testing. 12 'https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk', 13] 14 15def IsSourceValid(url): 16 # E1101: Instance of 'ParseResult' has no 'scheme' member 17 # pylint: disable=E1101 18 19 given = urlparse.urlparse(url) 20 for allowed_url in SOURCE_WHITELIST: 21 allowed = urlparse.urlparse(allowed_url) 22 if (given.scheme == allowed.scheme and 23 given.hostname == allowed.hostname and 24 given.path.startswith(allowed.path)): 25 return True 26 return False 27 28 29class Config(dict): 30 def __init__(self, data=None): 31 dict.__init__(self) 32 if data: 33 self.update(data) 34 else: 35 self.sources = [] 36 37 def LoadJson(self, json_data): 38 try: 39 self.update(json.loads(json_data)) 40 except Exception as e: 41 raise Error('Error reading json config:\n%s' % str(e)) 42 43 def ToJson(self): 44 try: 45 return json.dumps(self, sort_keys=False, indent=2) 46 except Exception as e: 47 raise Error('Json encoding error writing config:\n%s' % e) 48 49 def __getattr__(self, name): 50 if name in self: 51 return self[name] 52 else: 53 raise AttributeError('Config does not contain: %s' % name) 54 55 def __setattr__(self, name, value): 56 self[name] = value 57 58 def AddSource(self, source): 59 if not IsSourceValid(source): 60 logging.warn('Only whitelisted sources are allowed. Ignoring \"%s\".' % ( 61 source,)) 62 return 63 64 if source in self.sources: 65 logging.info('Source \"%s\" already in Config.' % (source,)) 66 return 67 self.sources.append(source) 68 69 def RemoveSource(self, source): 70 if source not in self.sources: 71 logging.warn('Source \"%s\" not in Config.' % (source,)) 72 return 73 self.sources.remove(source) 74 75 def RemoveAllSources(self): 76 if not self.sources: 77 logging.info('No sources to remove.') 78 return 79 self.sources = [] 80