def __init__(self,tid=False,ip=False): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid,'ip': ip}) self.couch = couchdb.Server(COUCHDB_SERVER) self.couch.resource.credentials = (COUCHDB_USER,COUCHDB_PASS) self.user_database = 'myring_users' self.roles = {} self.roles['handle_owner'] = ['get_a_home','get_a_x','post_a_x','post_a_x_y','put_a_x_y','delete_a_x_y','get_a','get_a_b','get_a_b_c','post_a','post_a_b','put_a','put_a_b','put_a_b_c','delete_a','delete_a_b','delete_a_b_c'] self.roles['org_owner'] = ['get_a_home','get_a_p','post_a_p','delete_a_p_q','get_a_m','post_a_m','get_a_m_n','put_a_m_n','delete_a_m_n','put_a_m_n_settings','put_a_m_n_invite','get_a_x','post_a_x','post_a_x_y','put_a_x_y','delete_a_x_y','get_a','get_a_b','get_a_b_c','post_a','post_a_b','put_a','put_a_b','put_a_b_c','delete_a','delete_a_b','delete_a_b_c'] self.roles['team_generic'] = ['get_a_home','get_a_m','get_a_x'] self.roles['team_reader'] = ['get_a_home','get_a_m','get_a_m_n','get_a','get_a_b','get_a_b_c'] self.roles['team_writer'] = ['get_a_home','get_a_m','get_a_m_n','get_a','get_a_b','get_a_b_c','post_a_b','put_a_b_c','delete_a_b_c'] self.roles['team_admin'] = ['get_a_home','get_a_m','get_a_m_n','get_a','get_a_b','get_a_b_c','post_a','post_a_b','put_a','put_a_b','put_a_b_c','delete_a','delete_a_b','delete_a_b_c','put_a_m_n_invite'] self.roles['anonymous'] = ['get_a_home'] self.roles['api_anonymous'] = ['get_a','get_a_b','get_a_b_c'] self.roles['handle_member'] = ['get_a','get_a_b','get_a_b_c'] self.roles['ring_owner'] = ['get_a_b','get_a_b_c','post_a','post_a_b','put_a_b','put_a_b_c','delete_a_b','delete_a_b_c'] self.roles['item_owner'] = ['get_a_b_c','put_a_b_c','delete_a_b_c'] self.roles['api_user'] = ['get_a_b','get_a_b_c'] self.roles['moderator'] = ['get_a_b','get_a_b_c','put_a_b_c','delete_a_b_c'] self.roles['capturist'] = ['get_a_b','get_a_b_c','post_a_b','put_a_b_c','delete_a_b_c'] self.roles['fact_checker'] = ['get_a_b_c','put_a_b_c']
def __init__(self): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, { 'tid': g.get('tid', None), 'ip': g.get('ip', None) }) self.couch = couchdb.Server(COUCHDB_SERVER) self.couch.resource.credentials = (COUCHDB_USER, COUCHDB_PASS) #self.lggr.info('self.couch :ATM') #self.lggr.info(self.couch) #self.lggr.info('self.couch.resource.credentials :ATM') #self.lggr.info(self.couch.resource.credentials) self.user_database = 'myring_users' self.MAM = MainModel() self.officialsizes = { 'r100': 100, 'r240': 240, 'r320': 320, 'r500': 500, 'r640': 640, 'r800': 800, 'r1024': 1024 } self.thumbnailsizes = {'t75': 75, 't150': 150}
def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.RIM = RingsModel(tid=tid, ip=ip) self.COM = CollectionsModel(tid=tid, ip=ip) self.CB = CollectionBuilder(tid=tid, ip=ip)
def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.MAM = MainModel(tid=tid, ip=ip) self.TEM = TeamsModel(tid=tid, ip=ip) self.PEM = PeopleModel(tid=tid, ip=ip)
class PeopleModel: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.MAM = MainModel(tid=tid, ip=ip) #PEOPLEMODEL def get_a_p(self, handle, person): pass # Returns list of people #Not being used. Using self.MAM.is_org(handle) instead. #FUTURE: Maybe we will have to use this in the future to optimize #PEOPLEMODEL def post_a_p(self, handle, person): '''Creates new person in the organization''' doc = self.MAM.select_user(handle) self.lggr.debug('user_doc[people]:%s' % doc['people']) newperson = { 'handle': person, 'addedby': current_user.id, 'added': str(datetime.now()) } doc['people'].append(newperson) return self.MAM.post_user_doc(doc) #PEOPLEMODEL def delete_a_p_q(self, handle, person): '''Deletes person from organization''' doc = self.MAM.select_user(handle) #Delete user from _people pool m = 0 for people in doc['people']: if people['handle'] == person: del doc['people'][m] m += 1 #Delete user from all the teams it belongs too in this org (if any) n = 0 for team in doc['teams']: p = 0 for m in team['members']: if m['handle'] == person: del doc['teams'][n]['members'][p] p += 1 n += 1 return self.MAM.post_user_doc(doc)
def __init__(self,tid=None,ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid,'ip': ip}) self.collectionprotocols = {} self.collectionprotocols['collectionprotocol'] = ['CollectioNname','CollectionDescription','CollectionVersion'] self.collectionprotocols['mandatory'] = ['CollectionName'] self.collectionprotocols['defaults'] = {'CollectionVersion':'0.1.0'} self.COM = CollectionsModel()
def __init__(self, handle, ring, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.handle = handle self.ring = ring client = algoliasearch.Client(ALGOLIA_APPLICATION_ID, ALGOLIA_ADMIN_API_KEY) indexname = '%s-%s' % (handle, ring) self.index = client.init_index(indexname)
def __init__(self, username=None, email=None, passhash=None, owner=None, location=None, url=None, profilepic=None, name=None, isOrg=False, active=True, id=None, onlogin=False, about=None, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.lggr.debug('__init__()') self.username = username self.email = email self.location = location self.passhash = passhash self.about = about self.url = url self.profilepic = profilepic self.name = name self.isOrg = isOrg self.active = active self.isAdmin = False self.id = None self.onlogin = onlogin if owner: self.owner = owner else: self.owner = username if isinstance(self.location, basestring): self.location = self.location.lower() if isinstance(self.email, basestring): self.email = self.email.lower() if isinstance(self.username, basestring): self.usernme = self.username.lower() self.ATM = AuthModel()
class AlgoliaSearchModel: def __init__(self, handle, ring, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.handle = handle self.ring = ring client = algoliasearch.Client(ALGOLIA_APPLICATION_ID, ALGOLIA_ADMIN_API_KEY) indexname = '%s-%s' % (handle, ring) self.index = client.init_index(indexname) def indexer(self, content, idx): print content item = self.clean_content(content) self.lggr.info('Algolia Indexing %s/%s/%s' % (self.handle, self.ring, idx)) self.lggr.info('Item to index: %s' % (item)) r = self.index.add_object(item, object_id=idx) print(r) return r def unindexer(self, idx): r = self.index.delete_object(self, idx) return check_response_status(r.status_code) def clean_content(self, content): item = content['item'] clean = {} for k in item: if k[0] != '_': if k[-5:] != '_flag': if k[-5:] != '_rich': clean[k] = item[k] return clean
def __init__(self, handle): self.handle = handle self.rs_status = '' self.officialsizes = { 'r100': 100, 'r240': 240, 'r320': 320, 'r500': 500, 'r640': 640, 'r800': 800, 'r1024': 1024 } self.thumbnailsizes = {'t75': 75, 't150': 150} self.allowed_formats = set( ['txt', 'pdf', 'png', 'jpg', 'JPG', 'jpeg', 'gif']) logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, { 'tid': g.get('tid', None), 'ip': g.get('ip', None) })
# Define the WSGI application object app = Flask(__name__) # Configurations app.config.from_object('default_config') if 'DEBUG' in app.config: app_debug = app.config['DEBUG'] else: app_debug = True #setup_logging() LS = LoggingSetUp() LS.setup(logfile_path=app.config['LOGFILE_PATH'], app_debug=app_debug) logger = logging.getLogger('Avispa') lggr = AvispaLoggerAdapter(logger, {'tid': '0', 'ip': '0'}) # Log something lggr.info('Flask App defined!') lggr.debug('Debug log is ON') lggr.info('Klaun was here') if app.config['DEBUG']: from flask_debugtoolbar import DebugToolbarExtension toolbar = DebugToolbarExtension(app) # Flask BCrypt will be used to salt the user password flask_bcrypt = Bcrypt(app) # Associate Flask-Login manager with current app login_manager = LoginManager() lggr.info('Login Manager defined!')
class CollectionsModel: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.MAM = MainModel(tid=tid, ip=ip) #COLLECTIONSMODEL def get_a_x(self, handle): # Returns list of collections try: doc = self.MAM.select_user(handle) collections = doc['collections'] rings = doc['rings'] # 1. Here we need to call the DB again but now to get which validring = {} ringorigins = {} ringcounts = {} for ring in rings: if not 'deleted' in ring: ringname = str(ring['ringname']) if 'origin' in ring: ringorigin = str(ring['origin']) else: ringorigin = str(handle) ringorigins[ringname] = ringorigin ringcounts[ringname] = ring['count'] #raise Exception('debug') self.lggr.info(ringcounts) for coll in collections: for ring in coll['rings']: if ring['ringname'] in ringcounts: ring['count'] = ringcounts[ring['ringname']] if ring['ringname'] in ringorigins: ring['ringorigin'] = ringorigins[ring['ringname']] return collections except (ResourceNotFound, TypeError) as e: self.lggr.error("Notice: Expected error:%s,%s" % (sys.exc_info()[0], sys.exc_info()[1])) return False #COLLECTIONSMODEL def post_a_x(self, handle, collectiond): '''Creates new collection''' doc = self.MAM.select_user(handle) if 'description' not in collectiond: collectiond['description'] = '' newcollection = { 'collectionname': str(collectiond['name']), 'collectiondescription': str(collectiond['description']), 'version': str(collectiond['version']), 'rings': collectiond['ringlist'], 'added': str(datetime.now()) } doc['collections'].append(newcollection) self.MAM.post_user_doc(doc) return True #COLLECTIONSMODEL def get_a_x_y(self, handle, collection): #Not used directly, but used by put_rq_a_x_y to return collection details #Returns just one collection try: doc = self.MAM.select_user(handle) collections = doc['collections'] rings = doc['rings'] validring = {} for ring in rings: if not 'deleted' in ring: ringname = str(ring['ringname']) validring[ringname] = ring['count'] for coll in collections: #coll['valid'] = True if coll['collectionname'] == collection: #coll['valid'] = True for ring in coll['rings']: if ring['ringname'] in validring: ring['count'] = validring[ring['ringname']] else: pass #InValid Collection, at least one of its rings is marked as deleted #coll['valid'] = False return coll return False except (ResourceNotFound, TypeError) as e: self.lggr.error("Notice: Expected error:%s,%s" % (sys.exc_info()[0], sys.exc_info()[1])) #COLLECTIONSMODEL def put_a_x_y(self, handle, collectiond): doc = self.MAM.select_user(handle) newcollection = { 'collectionname': str(collectiond['name']), 'collectiondescription': str(collectiond['description']), 'version': str(collectiond['version']), 'rings': collectiond['ringlist'], 'added': str(datetime.now()) } i = 0 for coll in doc['collections']: if coll['collectionname'] == newcollection['collectionname']: #This is a match. This is what we need to replace with incoming document doc['collections'][i] = newcollection i = i + 1 self.MAM.post_user_doc(doc) return True #COLLECTIONSMODEL def patch_a_x_y(self, handle, collection, collectiond): doc = self.MAM.select_user(handle) path = {} if 'name' in collectiond: patch['collectionname'] = str(collectiond['name']) if 'description' in collectiond: patch['collectiondescription'] = str(collectiond['description']) if 'version' in collectiond: patch['version'] = str(collectiond['version']) if 'rings' in collectiond: patch['rings'] = collectiond['ringlist'] i = 0 for coll in doc['collections']: if coll['collectionname'] == collection: for p in patch: doc['collections'][i][p] = patch[p] i = i + 1 self.MAM.post_user_doc(doc) return True def add_ring_to_collection(self, handle, collection, ringd): doc = self.MAM.select_user(handle) for coll in doc['collections']: if coll['collectionname'] == collection: coll['rings'].append(ringd) self.lggr.info('Ring added to collection:', doc) self.MAM.post_user_doc(doc) return True #COLLECTIONSMODEL def delete_a_x_y(self, handle, collection): doc = self.MAM.select_user(handle) i = 0 for coll in doc['collections']: if coll['collectionname'] == collection: del doc['collections'][i] i = i + 1 self.MAM.post_user_doc(doc) return True
class MainModel: def __init__(self,tid=False,ip=False): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid,'ip': ip}) self.couch = couchdb.Server(COUCHDB_SERVER) self.couch.resource.credentials = (COUCHDB_USER,COUCHDB_PASS) self.user_database = 'myring_users' self.roles = {} self.roles['handle_owner'] = ['get_a_home','get_a_x','post_a_x','post_a_x_y','put_a_x_y','delete_a_x_y','get_a','get_a_b','get_a_b_c','post_a','post_a_b','put_a','put_a_b','put_a_b_c','delete_a','delete_a_b','delete_a_b_c'] self.roles['org_owner'] = ['get_a_home','get_a_p','post_a_p','delete_a_p_q','get_a_m','post_a_m','get_a_m_n','put_a_m_n','delete_a_m_n','put_a_m_n_settings','put_a_m_n_invite','get_a_x','post_a_x','post_a_x_y','put_a_x_y','delete_a_x_y','get_a','get_a_b','get_a_b_c','post_a','post_a_b','put_a','put_a_b','put_a_b_c','delete_a','delete_a_b','delete_a_b_c'] self.roles['team_generic'] = ['get_a_home','get_a_m','get_a_x'] self.roles['team_reader'] = ['get_a_home','get_a_m','get_a_m_n','get_a','get_a_b','get_a_b_c'] self.roles['team_writer'] = ['get_a_home','get_a_m','get_a_m_n','get_a','get_a_b','get_a_b_c','post_a_b','put_a_b_c','delete_a_b_c'] self.roles['team_admin'] = ['get_a_home','get_a_m','get_a_m_n','get_a','get_a_b','get_a_b_c','post_a','post_a_b','put_a','put_a_b','put_a_b_c','delete_a','delete_a_b','delete_a_b_c','put_a_m_n_invite'] self.roles['anonymous'] = ['get_a_home'] self.roles['api_anonymous'] = ['get_a','get_a_b','get_a_b_c'] self.roles['handle_member'] = ['get_a','get_a_b','get_a_b_c'] self.roles['ring_owner'] = ['get_a_b','get_a_b_c','post_a','post_a_b','put_a_b','put_a_b_c','delete_a_b','delete_a_b_c'] self.roles['item_owner'] = ['get_a_b_c','put_a_b_c','delete_a_b_c'] self.roles['api_user'] = ['get_a_b','get_a_b_c'] self.roles['moderator'] = ['get_a_b','get_a_b_c','put_a_b_c','delete_a_b_c'] self.roles['capturist'] = ['get_a_b','get_a_b_c','post_a_b','put_a_b_c','delete_a_b_c'] self.roles['fact_checker'] = ['get_a_b_c','put_a_b_c'] #MAINMODEL def create_db(self,dbname): return self.couch.create(dbname) def stack_parser(self,stack): out = [] for frame,filename,lineno,functionname,context,index in stack: parts = filename.split('/') skip = False for p in parts: if p in ['env','venv','system','lib','library']: skip = True break if not skip: s = filename+':'+str(lineno)+' '+functionname+' '+str(context) print(s) #s = filename+':'+str(lineno)+' '+functionname+' -> '+str(inspect.getargvalues(frame)) #out.append(s) return out #MAINMODEL def select_db(self,dbname): result = self.couch[dbname] return result #MAINMODEL def delete_db(self,dbname): del self.couch[dbname] return True #MAINMODEL def create_doc(self,dbname,id,doc): db=self.select_db(dbname) doc['_id']= id db.save(doc) #doc.store(db) return True #MAINMODEL def create_user(self,userd,dbname=None): if not dbname: dbname=self.user_database #self.lggr.debug('flag1') self.db = self.select_db(dbname) #self.lggr.debug('flag2') if 'onLogin' not in userd: userd['onlogin'] = '' #self.lggr.debug('Notice: Creating User ->'+userd['username']) auser = MyRingUser( email= userd['email'], billingemail = userd['email'], isorg = False, passhash= userd['passhash'], onlogin= userd['onlogin']) auser._id = userd['username'] storeresult = auser.store(self.db) self.lggr.info(str(storeresult)) return True #MAINMODEL def create_orguser(self,data,dbname=None): if not dbname: dbname=self.user_database #self.lggr.debug('flag1') self.db = self.select_db(dbname) #self.lggr.debug('flag2') people = {} people[data['username']] = {} people[data['username']]['addedby'] = data['username'] people[data['username']]['added'] = str(datetime.now()) teams = {} teams['owner'] = {} teams['owner']['members'] = [] teams['owner']['members'].append(data['username']) teams['owner']['addedby'] = data['username'] teams['owner']['added'] = str(datetime.now()) #dict(data['username']:dict("addedby":data['username'],"added":datetime.now())) #dict(data['username']=dict("addedby"=data['username'],"added"=datetime.now())) people2 = {} people2['addedby'] = 'moco' people2['added'] = datetime.now() self.lggr.debug('Notice: Creating User ->%s'%data['username']) auser = MyRingUser( email= data['username']+'@id.myring.io', billingemail = data['email'], is_org = True, passhash= data['passhash'], location = data['location'], url = data['url'], profilepic = data['profilepic'], name = data['name']) #auser.people[data['username']] = {} auser.people.append(handle=data['owner'],addedby=data['owner'],added=datetime.now()) auser.teams.append(teamname='owner',addedby=data['owner'],added=datetime.now()) auser.teams.append(teamname='staff',addedby=data['owner'],added=datetime.now()) for team in auser.teams: self.lggr.debug("Teamowner:%s"%team) self.lggr.debug("team.teamname:%s"%team.teamname) self.lggr.debug("team.members:%s - %s"%(team.members, type(team.members))) self.lggr.debug("team.added:%s"%team.added) if team.teamname == 'owner': team.members.append(handle=data['owner'],addedby=data['owner'],added=datetime.now()) elif team.teamname == 'staff': team.members.append(handle=data['owner'],addedby=data['owner'],added=datetime.now()) team.roles.append(role='team_admin',addedby=data['owner'],added=datetime.now()) auser._id = data['username'] storeresult = auser.store(self.db) return True def repair_user_doc(self,element,username,dbname=None): if not dbname: dbname=self.user_database db = self.select_db(dbname) user_doc = MyRingUser.load(db, username) self.lggr.debug('user_doc: %s (%s)'%(user_doc,type(user_doc))) self.lggr.debug('element: %s (%s)'%(element,type(element))) #if not hasattr(user_doc,str(element)): try: user_doc[element] except(KeyError): self.lggr.debug('repairflag') user_doc[element] = '' if user_doc.store(db): return True return False def add_team(self,handle,team,author,user_database=None): if not user_database: user_database=self.user_database db = self.select_db(user_database) user_doc = MyRingUser.load(db,handle) user_doc.teams.append(teamname=team,addedby=author,added=datetime.now()) for teamd in user_doc.teams: if teamd['teamname'] == team: self.lggr.debug('flag at1') teamd.members.append(handle=author,addedby=author,added=datetime.now()) teamd.roles.append(role='team_writer',addedby=author,added=datetime.now()) storeresult = user_doc.store(db) return True return False def delete_team(self,handle,team,user_database=None): if not user_database: user_database=self.user_database db = self.select_db(user_database) user_doc = MyRingUser.load(db,handle) count = 0 for teamd in user_doc.teams: if teamd['teamname'] == team: del user_doc.teams[count] if user_doc.store(db): return True count += 1 return False #MAINMODEL def is_org(self,username,user_database=None): result = self.select_user_doc_view('orgs/peopleteams',username) return result def user_exists(self,username,user_database=None): result = self.select_user_doc_view('auth/userbyhandle',username) return result #MAINMODEL def user_orgs(self,username,user_database=None): result = self.select_user_doc_view('orgs/user2orgs',username,10) return result #MAINMODEL #TODO: Rename this method to get_user_doc() def select_user(self,username): db = self.select_db(USER_DB) return MyRingUser.load(db, username) def post_user_doc(self,doc): db = self.select_db(USER_DB) return doc.store(db) def select_user_doc_view(self,dbview,key,batch=None,user_database=None): if not user_database : user_database = self.user_database if not batch : batch = 1 db = self.select_db(self.user_database) options = {} options['key']=str(key) result = db.iterview(dbview,batch,**options) # This is a generator. If it comes empty, the username didn't exist. # The only way to figure that out is trying to iterate in it. #self.lggr.debug('iterview result for '+dbview+' with key '+key+':',result) #options: key, startkey, endkey if batch == 1: for r in result: return r['value'] else: out = [] for r in result: out.append(r['value']) return out return False def select_multiple_users_doc_view(self,dbview,batch,user_database=None): #BUG I tried factorizing this with select_user_doc_view but it is showing users as organizations. # By just changing key for startkey if not user_database : user_database = self.user_database if not batch : batch = 500 db = self.select_db(self.user_database) options = {} result = db.iterview(dbview,batch,**options) return result def select_ring_doc_view(self,ringdb,dbview,key=None,batch=None,showall=False): print('select_ring_doc_view::'+ringdb+','+dbview+','+str(key)+','+str(batch)) if not batch : batch = 1 db = self.select_db(ringdb) options = {} if key: options['key']=str(key) result = db.iterview(dbview,batch,**options) # This is a generator. If it comes empty, the username didn't exist. # The only way to figure that out is trying to iterate in it. #self.lggr.debug('iterview result for '+dbview+' with key '+key+':',result) #print('gen len:',sum(1 for _ in result)) if batch == 1: for r in result: if showall: rr = {'key':r['key'],'id':r['id'],'value':r['value']} return rr else: return r['value'] else: out = [] for r in result: if showall: rr = {'key':r['key'],'id':r['id'],'value':r['value']} out.append(rr) else: out.append(r['value']) return out return False def general_daily_activity(self,handle,user_database=None): #0. Create the general count dictionary (with 365 slots) #1. Retrieve all rings for this handle. Use view myringusers:ring/count #2. Rerieve all the rings of all organizations where this user has something to do #3. For each of the rings found: #3a: Load its database #3b: Call its dailyactivity view with key=handle #3c: If something is found iterate through each one of the rows looking for the last 365 days #3d: add "New" and "Update "counts to the general count for that specific day pass #MAINMODEL def delete_user(self,dbname,user): self.db = self.select_db(dbname) #self.lggr.debug('Notice: Deleting User ->'+user) #del self.db[user] return True def append_to_user_field(self,handle,field,data,sublist=None,wherefield=None,wherefieldvalue=None,user_database=None): #This only to be used by fields that hold lists if not user_database : user_database = self.user_database self.db = self.couch[self.user_database] user = MyRingUser.load(self.db,handle) if user: #Preparing user[field] if field not in user: user[field] = [] else: if type(user[field]) is not list: self.lggr.debug('Cant append things to something that is not a list') return False #Preparing user[field][x][sublist] if sublist: s = 0 for u in user[field]: if u[wherefield] == wherefieldvalue: #This is assuming that user[field][s][sublist] exists and it is a list if sublist not in u: user[field][s][sublist] = [] elif type(user[field][s][sublist]) is not list: self.lggr.debug('Cant append things to something that is not a list..') return False user[field][s][sublist].append(data) break s += 1 else: user[field].append(data) if user.store(self.db): self.lggr.debug('Data updated succesfully') return True else: self.lggr.debug('Could not update user') return False else: self.lggr.debug('No user:%s'%handle) return False #MAINMODEL def update_user(self,data,user_database=None): if not user_database : user_database = self.user_database self.db = self.couch[self.user_database] #self.lggr.debug("update_user 3:") user = MyRingUser.load(self.db, data['id']) #self.lggr.debug("update_user 4:") #self.lggr.debug(user) if user: #self.lggr.debug("update_user 5:") for field in data: if field!='id': self.lggr.debug("Old Value:%s"%str(user[field])) self.lggr.debug("New Value:%s"%str(data[field])) user[field]=data[field] if user.store(self.db): self.lggr.debug('Data updated succesfully') return True else: self.lggr.debug('Could not update user') return False else: self.lggr.debug('No user %s'%data['_id']) #ROLEMODEL def user_is_authorized(self,current_user,method,route,handle,ring=None,idx=None,collection=None,team=None,api=False): # @method : is what is going to be checked against the user_authorization list # @route : how deep to dig in the user_authorizations self.lggr.info('START AUTHORIZATION') user_authorizations = [] rolelist = [] self.lggr.debug('Method:%s'%method) self.lggr.debug('route:%s'%route) if api: user_authorizations = self.sum_role_auth(user_authorizations,'api_user') if route == '_a' or route == '_a_b' or route == '_a_b_c': if current_user == handle: #This user is a Handle Owner self.lggr.debug('This user is a Handle Owner') user_authorizations = self.sum_role_auth(user_authorizations,'handle_owner') else: if route != '_a_b' or route != '_a_b_c': #This is only important if you are not going to go deeper than _a rolelist = self.user_belongs_org_team(current_user,handle,ring='*') #rolelist = self.user_belongs_org_team(current_user,handle) if rolelist: self.lggr.debug('rolelist1:%s'%str(rolelist)) self.lggr.debug('This user is a member of a team') for role in rolelist: user_authorizations = self.sum_role_auth(user_authorizations,role) else: if current_user == '_api_anonymous': self.lggr.info('This user is API Anonymous') user_authorizations += self.roles['api_anonymous'] else: self.lggr.info('This user is Anonymous 1') user_authorizations += self.roles['anonymous'] if route == '_a_b' or route == '_a_b_c': rolelist = self.user_belongs_org_team(current_user,handle,ring=ring) if rolelist: self.lggr.debug('rolelist2:%s'%str(rolelist)) self.lggr.debug('This user can act on this ring:%s'%ring) for role in rolelist: user_authorizations = self.sum_role_auth(user_authorizations,role) if route == '_a_b_c': db_ringname=str(handle)+'_'+str(ring) #self.lggr.debug('db_ringname:%s'%db_ringname) db = self.select_db(db_ringname) #self.lggr.debug('db:%s'%db) options = {} options['key']=str(idx) #Retrieving from ring/items view result = db.iterview('item/roles',1,**options) self.lggr.debug('item/roles:%s'%str(result)) try: for roles in result: self.lggr.debug('roles for item:%s'%roles['value']) #{u'fact_checker': [u'blalab', u'camaradediputados'], u'_public': False} for role in roles['value']: self.lggr.debug(roles['value'][role]) self.lggr.debug(type(roles['value'][role])) if type(roles['value'][role]) is list and current_user in roles['value'][role]: self.lggr.debug('This user is an Item %s:%s'%(role,ring)) if role in self.roles: self.lggr.debug('Adding:%s.'%role) user_authorizations = self.sum_role_auth(user_authorizations,role) except(ResourceNotFound): #AUTOREPAIR self.lggr.debug('item/roles db view does not exist. Will regenerate') from avispa_rest.RingsModel import RingsModel #Loading here because I don't want to load for all MainModel.py #TO_REFACTOR RIM = RingsModel() RIM.ring_set_db_views(db_ringname,'item/roles') #Now issue the same request before the exception was thrown for roles in result: self.lggr.debug('roles for item:%s'%roles['value']) #{u'fact_checker': [u'blalab', u'camaradediputados'], u'_public': False} for role in roles['value']: self.lggr.debug(roles['value'][role]) self.lggr.debug(type(roles['value'][role])) if type(roles['value'][role]) is list and current_user in roles['value'][role]: self.lggr.debug('This user is an Item %s:%s '%(role,ring)) user_authorizations = self.sum_role_auth(user_authorizations,role) elif route == '_a_p' or route == '_a_p_q': self.lggr.debug('Testing authorizations for /_people section') team = 'owner' rolelist = self.user_belongs_org_team(current_user,handle,team) if rolelist: self.lggr.debug('rolelist3:%s'%rolelist) self.lggr.debug('This user is a member of team:%s'%team) for role in rolelist: user_authorizations = self.sum_role_auth(user_authorizations,role) else: self.lggr.debug('This user is Anonymous 2') user_authorizations = self.sum_role_auth(user_authorizations,'anonymous') rolelist.append('anonymous') elif route == '_a_m' or route == '_a_m_n' or route == '_a_m_n_settings' or route == '_a_m_n_invite': if not team: self.lggr.debug('Testing authorizations for /_teams section') rolelist = self.user_belongs_org_team(current_user,handle) else: self.lggr.debug('Testing authorizations for /_teams/%s'%team) rolelist = self.user_belongs_org_team(current_user,handle,team) if rolelist: self.lggr.debug('rolelist4:%s'%rolelist) for role in rolelist: user_authorizations = self.sum_role_auth(user_authorizations,role) else: self.lggr.debug('This user is Anonymous 3') user_authorizations = self.sum_role_auth(user_authorizations,'anonymous') rolelist.append('anonymous') elif route == '_a_x' or route == '_a_x_y': if current_user == handle: #This user is a Handle Owner rolelist.append('handle_owner') self.lggr.debug('This user is a Handle Owner') user_authorizations = self.sum_role_auth(user_authorizations,'handle_owner') else: rolelist = self.user_belongs_org_team(current_user,handle) if rolelist: self.lggr.debug('rolelist5:%s'%rolelist) self.lggr.debug('This user is a member of a team accesing a collection') for role in rolelist: user_authorizations = self.sum_role_auth(user_authorizations,role) ''' if role != 'org_owner': user_authorizations = self.sum_role_auth(user_authorizations,'team_generic') ''' #Here, add the retrieve of authorizations in deeper levels (just if required by route) self.lggr.debug('Final user_authorizations:%s'%str(user_authorizations)) method_parts = method.split('_') separator = '_' if 'rq' in method_parts: position = method_parts.index('rq') del method_parts[position] method = separator.join(method_parts) if 'rs' in method_parts: position = method_parts.index('rs') del method_parts[position] method = separator.join(method_parts) out={} out['user_authorizations'] = user_authorizations self.lggr.debug('Method for this screen:%s'%method) if method.lower() in user_authorizations: out['authorized'] = True else: out['authorized'] = False self.lggr.info('END AUTHORIZATION') return out def sum_role_auth(self,user_authorizations,role): if type(role) is dict: if role['role'] in self.roles: if role['ring']: self.lggr.debug('Adding ring role:%s_%s'%(role['ring'],role['role'])) self.lggr.debug(self.roles[role['role']]) for r in self.roles[role['role']]: user_authorizations.append(role['ring']+'_'+r) else: self.lggr.debug('%s was not found'%role) else: if role in self.roles: self.lggr.debug('Adding role:%s:%s'%(role,str(self.roles[role]))) user_authorizations += self.roles[role] else: self.lggr.debug(role+' was not found') return user_authorizations def is_org_owner(self,handle,org): return True def user_belongs_org_team(self,username,org,team=None,ring=None): self.lggr.debug('Will check if '+username+' belongs to a team ') rolelist = [] result = self.select_user_doc_view('orgs/peopleteams',org) if result: if team: #Check if this usernname belongs to a team. Assign roles of that team only for teamd in result['teams']: for member in teamd['members']: if member['handle'] == username: self.lggr.debug(teamd['teamname']+' team has as member: '+member['handle']) #Will add only those roles of a team the user belongs to if teamd['teamname'] == 'owner': rolelist.append('org_owner') else: for role in teamd['roles']: rolelist.append(role['role']) elif ring: #Check if this username can act on this ring for teamd in result['teams']: self.lggr.debug('flagx1') if teamd['teamname'] == 'owner': self.lggr.debug('Checking is this user is in owner team:'+str(teamd['members'])) for member in teamd['members']: if member['handle'] == username: rolelist.append('org_owner') elif teamd['teamname'] == 'staff': for member in teamd['members']: if member['handle'] == username: for role in teamd['roles']: rolelist.append(role['role']) else: for ringd in teamd['rings']: self.lggr.debug('flagx2'+ringd['ringname']+str(ring)) if ring == '*': for member in teamd['members']: if member['handle'] == username: #Ring specific permissions for role in teamd['roles']: rolelist.append({"ring":ringd['ringname'],"role":role['role']}) #It will show a lot of ring specific permissions but you still need to have the team_generic # to be able to see your team rolelist.append('team_generic') elif ringd['ringname'] == ring: self.lggr.debug('flagx3') #This team acts on this ring! for member in teamd['members']: if member['handle'] == username: #This user belongs to this team that can act on this ring! for role in teamd['roles']: rolelist.append(role['role']) else: #This is only used in /_home and /_teams to prove membership in ANY team for teamd in result['teams']: for member in teamd['members']: if member['handle'] == username: if teamd['teamname'] == 'owner': rolelist.append('org_owner') else: rolelist.append('team_generic') return rolelist return False #MAINMODEL def random_hash_generator(self,bits=36): if bits % 8 != 0: bits = bits - (bits % 8) if bits < 8: bits = 8 required_length = bits / 8 * 2 s = hex(random.getrandbits(bits)).lstrip('0x').rstrip('L') if len(s) < required_length: return self.random_hash_generator(bits) else: return s
class CollectionBuilder: def __init__(self,tid=None,ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid,'ip': ip}) self.collectionprotocols = {} self.collectionprotocols['collectionprotocol'] = ['CollectioNname','CollectionDescription','CollectionVersion'] self.collectionprotocols['mandatory'] = ['CollectionName'] self.collectionprotocols['defaults'] = {'CollectionVersion':'0.1.0'} self.COM = CollectionsModel() def post_a_x(self,rqform,handle): if 'CollectionName' in rqform: collectiond = {} collectiond['name'] = rqform.get('CollectionName').lower() # I dont like this here collectiond['handle'] = handle.lower() if 'CollectionDescription' in rqform: collectiond['description'] = rqform.get('CollectionDescription').lower() else: collectiond['description'] = '' if rqform.get('CollectionVersion'): collectiond['version'] = rqform.get('CollectionVersion').replace('.','-') # I dont like this here else: collectiond['version'] = self.collectionprotocols['defaults']['CollectionVersion'].replace('.','-') ringlist = [] for p in rqform: pparts = p.split('_') ring = {} if pparts[0] == 'ring' and pparts[1]: value = rqform.get(p) vparts = value.split('_') ring['handle'] = vparts[0] ring['ringname'] = '_'.join(vparts[1:]) # Will implement this later. Layer is to separate from primary and secondary rings ring['layer'] = 1 ringlist.append(ring) collectiond['ringlist'] = ringlist #Here you write to the user.collection document if self.COM.post_a_x(handle,collectiond): self.lggr.debug('New Collection created: '+collectiond['name']) return True else: self.lggr.debug('The Collection '+ collectiond['name'] +' database already exists') return False def put_a_x_y(self,rqform,handle,collection): #Same as collectiongenerator if rqform.get('CollectionName'): collectiond = {} collectiond['name'] = rqform.get('CollectionName').lower() # I dont like this here collectiond['description'] = rqform.get('CollectionDescription').lower() collectiond['handle'] = handle.lower() if rqform.get('CollectionVersion'): collectiond['version'] = rqform.get('CollectionVersion').replace('.','-') # I dont like this here ringlist = [] for p in rqform: pparts = p.split('_') ring = {} if pparts[0] == 'ring' and pparts[1]: value = rqform.get(p) vparts = value.split('_') ring['handle'] = vparts[0] ring['ringname'] = '_'.join(vparts[1:]) # Will implement layer later. This is to separate from primary and secondary rings ring['layer'] = 1 ringlist.append(ring) collectiond['ringlist'] = ringlist if self.COM.put_a_x_y(handle,collectiond): self.lggr.debug('Collection updated: '+collectiond['name']) return True else: self.lggr.debug('The Collection '+ collectiond['name'] +' database already exists') return False
class TeamsController: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.MAM = MainModel(tid=tid, ip=ip) self.TEM = TeamsModel(tid=tid, ip=ip) self.PEM = PeopleModel(tid=tid, ip=ip) # GET/a def get_a_m(self, handle, team, *args, **kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: #This is an organization d['teamlistlen'] = len(peopleteams['teams']) d['teammembership'] = {} allteams = {} for teamd in peopleteams['teams']: #get the profilepic for this person self.lggr.debug('teamname:%s' % teamd['teamname']) for member in teamd['members']: self.lggr.debug('member:%s' % member['handle']) person_user_doc = self.MAM.select_user_doc_view( 'auth/userbasic', member['handle']) if person_user_doc: member['thumbnail'] = person_user_doc['profilepic'] if current_user.id == member['handle']: self.lggr.debug('%s is member' % member['handle']) if teamd['teamname'] == 'owner': d['teammembership'][ teamd['teamname']] = 'org_owner' else: if len(teamd['roles']) >= 1: d['teammembership'][teamd['teamname']] = teamd[ 'roles'][-1]['role'] allteams[teamd['teamname']] = 'org_owner' if 'owner' in d['teammembership']: d['teammembership'] = allteams d['teamlist'] = peopleteams['teams'] d['template'] = 'avispa_rest/get_a_m.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d # POST/a def post_a_m(self, handle, team, rqform=None, *args, **kargs): ''' Creates a new team ''' #We need to recover from request as it doesn't come via URL team = rqform.get('newteam') #Check if the team exists or not d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: redirect = url_for('avispa_rest.teams_a_m', handle=handle, _external=True, _scheme=URL_SCHEME) #This is an organization for teamd in peopleteams['teams']: if teamd['teamname'] == team: #This team exists in this handle! flash('This team exists already. Use a different name', 'ER') #redirect = '/'+handle+'/_teams' d = {'redirect': redirect, 'status': 200} return d if self.MAM.add_team(handle, team, current_user.id): self.lggr.debug('Awesome , you just created team %s ' % team) #msg = 'Item put with id: '+idx flash('Awesome , you just created team %s ' % team, 'UI') else: flash('There was an error adding team %s ' % team, 'UI') else: #This is not an organization #redirect = '/'+current_user.id redirect = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def get_a_m_n(self, handle, team, *args, **kargs): d = {} rings = self.MAM.select_user_doc_view('rings/count', handle) d['rings'] = rings peopleteams = self.MAM.is_org(handle) if peopleteams: d['people'] = peopleteams['people'] for teamd in peopleteams['teams']: #get the profilepic for this person if teamd['teamname'] == team: if teamd['roles']: if teamd['roles'][-1]['role'] == 'team_admin': teamauth = 'RWX' elif teamd['roles'][-1]['role'] == 'team_writer': teamauth = 'RW' elif teamd['roles'][-1]['role'] == 'team_reader': teamauth = 'R' else: teamauth = '' teamd['teamauth'] = teamauth for member in teamd['members']: person_user_doc = self.MAM.select_user_doc_view( 'auth/userbasic', member['handle']) if person_user_doc: member['thumbnail'] = person_user_doc['profilepic'] d['team'] = teamd break d['template'] = 'avispa_rest/get_a_m_n.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d #DEPRECATED def put_a_m_n(self, handle, team, rqform=None, rqargs=None, *args, **kargs): #This function should be refactored into multiple functions that obey RESTFUL: # post_a_m_n_members , delete_a_m_n_members , post_a_m_n_rings, delete_a_m_n_rings d = {} if 'newmember' in rqform: member = rqform.get('newmember') if self.TEM.post_a_m_n_members(handle, team, member): self.lggr.debug('%s has been added to the team.' % member) flash('%s has been added to the team.' % member, 'UI') else: self.lggr.debug('%s is already part of this team.' % member) flash('%s is already part of this team.' % member, 'UI') if 'delmember' in rqargs: member = rqargs.get('delmember') if self.TEM.delete_a_m_n_members(handle, team, member): self.lggr.debug('%s has been deleted from the team.' % member) flash('%s has been deleted from the team.' % member, 'UI') else: self.lggr.error('There was an issue deleting: %s' % member) flash('There was an issue deleting: %s' % member, 'UI') if 'newring' in rqform: ring = rqform.get('newring') if self.TEM.post_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been added to the team.' % ring) flash('%s has been added to the team.' % ring, 'UI') else: self.lggr.error('%s already exists in this team.' % ring) flash('%s already exists in this team.' % ring, 'UI') if 'delring' in rqargs: ring = rqargs.get('delring') if self.TEM.delete_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been deleted from the team.' % ring) flash('%s has been deleted from the team.' % ring, 'UI') else: self.lggr.error('There was an issue deleting: %s' % ring) flash('There was an issue deleting: %s' % ring, 'UI') #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d def post_a_m_n_p(self, handle, team, rqform): d = {} member = rqform.get('newmember') if self.TEM.post_a_m_n_members(handle, team, member): self.lggr.debug('%s has been added to the team.' % member) flash('%s has been added to the team.' % member, 'UI') else: self.lggr.debug('%s is already part of this team.' % member) flash('%s is already part of this team.' % member, 'UI') return d def delete_a_m_n_p_q(self, handle, team, member): '''Deletes a member from a team''' d = {} if self.TEM.delete_a_m_n_members(handle, team, member): self.lggr.debug('%s has been deleted from the team.' % member) flash('%s has been deleted from the team.' % member, 'UI') else: self.lggr.error('There was an issue deleting: %s' % member) flash('There was an issue deleting: %s' % member, 'UI') '''User Garbage collection''' # If a user no longer belongs to any team, it should be also released from the org # 1. Call TeamModel to check if this <member> exists in any other <team> in this <handle> memberships = self.TEM.get_a_m_all_p_q(handle, member) raise Exception # 2. If it doesn't, call the PeopleModel to delete this user if len(memberships) == 0: self.PEM.delete_a_p_q(handle, member) return d def post_a_m_n_r(self, handle, team, rqform): d = {} ring = rqform.get('newring') if self.TEM.post_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been added to the team.' % ring) flash('%s has been added to the team.' % ring, 'UI') else: self.lggr.error('%s already exists in this team.' % ring) flash('%s already exists in this team.' % ring, 'UI') return d def delete_a_m_n_r_b(self, handle, team, ring): d = {} if self.TEM.delete_a_m_n_rings(handle, team, ring): self.lggr.debug('%s has been deleted from the team.' % ring) flash('%s has been deleted from the team.' % ring, 'UI') else: self.lggr.error('There was an issue deleting: %s' % ring) flash('There was an issue deleting: %s' % ring, 'UI') return d #DELETE /a/b def delete_a_m_n(self, handle, team, *args, **kargs): #Will delete an existing team self.lggr.debug('Trying to delete the following team: %s' % team) d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: #This is an organization for teamd in peopleteams['teams']: if teamd['teamname'] == team: if self.MAM.delete_team(handle, team): self.lggr.debug('You just deleted team %s' % team) flash('You just deleted team %s' % team, 'UI') else: self.lggr.error( 'There was an error deleting team: %s' % team) flash('There was an error deleting team: %s' % team, 'ER') redirect = url_for('avispa_rest.teams_a_m', handle=handle, _external=True, _scheme=URL_SCHEME) else: #This is not an organization #redirect = '/'+current_user.id redirect = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def get_a_m_n_settings(self, handle, team, *args, **kargs): #redirect = '/'+handle+'/_teams/'+team redirect = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def put_rq_a_m_n_settings(self, handle, team, *args, **kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: d['people'] = peopleteams['people'] for teamd in peopleteams['teams']: #get the profilepic for this person if teamd['teamname'] == team: if teamd['roles']: if teamd['roles'][-1]['role'] == 'team_admin': teamauth = 'RWX' elif teamd['roles'][-1]['role'] == 'team_writer': teamauth = 'RW' elif teamd['roles'][-1]['role'] == 'team_reader': teamauth = 'R' else: teamauth = '' teamd['teamauth'] = teamauth d['team'] = teamd break d['template'] = 'avispa_rest/put_rq_a_m_n_settings.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d def put_a_m_n_settings(self, handle, team, rqform=None, *args, **kargs): d = {} p = {} if ('description' in rqform) or ('teamauth' in rqform): p['description'] = rqform.get('description') p['teamauth'] = rqform.get('teamauth') if self.TEM.put_a_m_n_settings(handle, team, p): self.lggr.debug('%s has been updated.' % team) flash('%s has been updated.' % team, 'UI') else: self.lggr.error('There was a problem updating team %s' % team) flash('There was a problem updating team %s' % team, 'ER') #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d def get_a_m_n_invite(self, handle, team, *args, **kargs): #redirect = '/'+handle+'/_teams/'+team redirect = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} return d def put_rq_a_m_n_invite(self, handle, team, *args, **kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: d['people'] = peopleteams['people'] for teamd in peopleteams['teams']: #get the profilepic for this person if teamd['teamname'] == team: d['team'] = teamd break d['template'] = 'avispa_rest/put_rq_a_m_n_invite.html' return d def put_a_m_n_invite(self, handle, team, rqurl=None, rqform=None, *args, **kargs): d = {} self.EMM = EmailModel() collabraw = rqform.get('emails') valid_emails, invalid_emails = address.validate_list(collabraw, as_tuple=True) self.lggr.debug('valid_emails:%s' % valid_emails) self.lggr.debug('invalid_emails:%s' % invalid_emails) #2. If it is an email, send ring subscription url/token o = urlparse.urlparse(rqurl) host_url = urlparse.urlunparse((o.scheme, o.netloc, '', '', '', '')) #2a PENDING # Subtract team object from org document peopleteams = self.MAM.is_org(handle) if peopleteams: for teamd in peopleteams['teams']: teamfound = False if teamd['teamname'] == team: # This team actually exists in this org. You can continue with the invitations teamfound = True break if not teamfound: # This team doesnt exist. No invitation can be sent #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d # teamd carries the team object #Try to convert invalid_emails (myringIDs) into valid_emails for invite_handle in invalid_emails: user_doc = self.MAM.select_user_doc_view('auth/userbyhandle', invite_handle) if user_doc: if user_doc['email'] not in valid_emails: valid_emails.append(user_doc['email']) for email in valid_emails: email = str(email) invite = {} invite['email'] = email invite['count'] = 1 invite['team'] = team invite['token'] = flask_bcrypt.generate_password_hash( email + str(random.randint(0, 9999))) invite['lasttime'] = str(datetime.now()) invite['author'] = current_user.id user_doc = self.MAM.select_user_doc_view('auth/userbyemail', email) if user_doc: #You are inviting an existing myRing user existinguser = True else: #You are inviting a soon to be myRing user existinguser = False token = invite['token'] to = email subject = handle + " has invited you to collaborate in the following team : " + team # https://avispa.myring.io/_register?h=cdmit&t=staff&k=11111&[email protected] content = "Click here to start working with this team: " + host_url + "/_register?h=" + handle + "&t=" + team + "&k=" + token + "&e=" + email self.lggr.debug('%s,%s,%s' % (to, subject, content)) if self.EMM.send_one_email(to, subject, content): flash("Invitation email sent.", 'UI') self.MAM.append_to_user_field(handle, 'invitations', invite) else: flash("Invitation email failed.", 'UI') #d['redirect'] = '/'+handle+'/_teams/'+team d['redirect'] = url_for('avispa_rest.teams_a_m_n', handle=handle, team=team, _external=True, _scheme=URL_SCHEME) return d
import logging from AvispaLogging import AvispaLoggerAdapter from flask import render_template, request, make_response, url_for from RingsController import RingsController from CollectionsController import CollectionsController from PeopleController import PeopleController from TeamsController import TeamsController from Tool import Tool from Patch import Patch from ElasticSearchModel import ElasticSearchModel from flask.ext.login import current_user from env_config import IMAGE_CDN_ROOT, TEMP_ACCESS_TOKEN, URL_SCHEME from MainModel import MainModel logger = logging.getLogger('Avispa') lggr = AvispaLoggerAdapter(logger, {'tid': '0', 'ip': '0'}) lggr.debug('Controller start') def setup_log_vars(): MAM = MainModel() if 'X-Forwarded-For' in request.headers: ip = request.headers.get('X-Forwarded-For') else: ip = request.remote_addr tid = MAM.random_hash_generator(36) return tid, ip
def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip})
class User(UserMixin): def __init__(self, username=None, email=None, passhash=None, owner=None, location=None, url=None, profilepic=None, name=None, isOrg=False, active=True, id=None, onlogin=False, about=None, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.lggr.debug('__init__()') self.username = username self.email = email self.location = location self.passhash = passhash self.about = about self.url = url self.profilepic = profilepic self.name = name self.isOrg = isOrg self.active = active self.isAdmin = False self.id = None self.onlogin = onlogin if owner: self.owner = owner else: self.owner = username if isinstance(self.location, basestring): self.location = self.location.lower() if isinstance(self.email, basestring): self.email = self.email.lower() if isinstance(self.username, basestring): self.usernme = self.username.lower() self.ATM = AuthModel() def set_user(self): user = {} # Defaults coming via self user['username'] = self.username user['email'] = self.email user['location'] = self.location user['owner'] = self.owner user['location'] = self.location user['url'] = self.url user['profilepic'] = self.profilepic user['name'] = self.name user['passhash'] = self.passhash user['onlogin'] = self.onlogin user['about'] = self.about self.lggr.info(user) if not self.isOrg: self.lggr.info('is an Org') #You are registering a regular User if self.ATM.saas_create_user(user): self.lggr.info("new user id = %s " % user['username']) return user['username'] else: return False else: self.lggr.info('is NOT an Org') #You are registering an Organization if self.ATM.saas_create_orguser(user): self.lggr.info("new organization id = %s " % user['username']) return user['username'] else: return False def set_password_key(self, key): self.lggr.info('set_password_key:') self.lggr.info(self.id) return self.ATM.saas_create_password_key(self.id, key) def set_password(self, passhash): self.lggr.info('set_password:'******'value']['email'] self.location = dbUser['value']['location'] self.active = dbUser['value']['is_active'] self.password = dbUser['value']['passhash'] self.id = dbUser['value']['_id'] return self else: return None except: self.lggr.error("Notice: UnExpected error :", sys.exc_info()[0], sys.exc_info()[1]) self.lggr.error("there was an error") return None def get_user(self): #raise Exception ('stop here') try: if self.email: self.lggr.debug('self.email:' + self.email) dbUser = self.ATM.userdb_get_user_by_email(self.email) elif self.username: self.lggr.info('START AUTHENTICATION:' + self.username) dbUser = self.ATM.userdb_get_user_by_handle(self.username) else: return None if dbUser: self.lggr.info("END AUTHENTICATION:%s" % dbUser['value']['name']) self.name = dbUser['value']['name'] self.email = dbUser['value']['email'] self.url = dbUser['value']['url'] self.profilepic = dbUser['value']['profilepic'] self.location = dbUser['value']['location'] self.about = dbUser['value']['about'] self.onlogin = dbUser['value']['onlogin'] self.active = dbUser['value']['is_active'] self.password = dbUser['value']['passhash'] self.id = dbUser['value']['_id'] return self else: self.lggr.error('User: not found') return None except (KeyError): self.lggr.error("Notice: UnExpected error :", sys.exc_info()[0], sys.exc_info()[1]) self.lggr.error( "there was an error, we need to repair the user_document") preconditions = [ 'name', 'email', 'url', 'profilepic', 'location', 'about', 'onlogin' ] repaired = False for element_to_add in preconditions: MAM = MainModel() if MAM.repair_user_doc(element_to_add, dbUser['value']['_id']): repaired = True self.lggr.info('Repaired ' + element_to_add + '. ') #flash('Repaired '+element_to_add+'. ') #Let's try again if repaired: if self.email: dbUser = self.ATM.userdb_get_user_by_email(self.email) elif self.username: dbUser = self.ATM.userdb_get_user_by_handle(self.username) if dbUser: self.name = dbUser['value']['name'] self.email = dbUser['value']['email'] self.url = dbUser['value']['url'] self.profilepic = dbUser['value']['profilepic'] self.location = dbUser['value']['location'] self.about = dbUser['value']['about'] self.active = dbUser['value']['is_active'] self.password = dbUser['value']['passhash'] self.id = dbUser['value']['_id'] return self else: return False else: return False def update_user_profile(self, request): dbUser = self.ATM.userdb_get_user_by_handle(self.username) changes = {} if dbUser: if request.form.get('profilepic') != dbUser['value']['profilepic']: self.lggr.info('profilepic changed!') changes['profilepic'] = request.form.get('profilepic') if request.form.get('name') != dbUser['value']['name']: self.lggr.info('name changed!') changes['name'] = request.form.get('name') mp_change = True if request.form.get('url') != dbUser['value']['url']: self.lggr.info('url changed!') changes['url'] = request.form.get('url') if request.form.get('location') != dbUser['value']['location']: self.lggr.info('location changed!') changes['location'] = request.form.get('location') if request.form.get('about') != dbUser['value']['about']: self.lggr.info('about changed!') changes['about'] = request.form.get('about') if request.form.get('onlogin') != dbUser['value']['onlogin']: self.lggr.info('onlogin changed!') changes['onlogin'] = request.form.get('onlogin') return self.ATM.saas_update_user_profile(self.username, changes) def is_valid_password_key(self, email, key): try: #self.lggr.info('flag1') dbUser = self.ATM.userdb_get_user_by_email(email) #self.lggr.info('flag2') #self.lggr.info(dbUser) if dbUser['value']['new_password_key'] == key: return True else: return False except: self.lggr.error("Notice: UnExpected error :", sys.exc_info()[0], sys.exc_info()[1]) self.lggr.error("There was an error validating the Key") return False def is_active(self): return self.active def is_authenticated(self): return True def is_anonymous(self): return False
class AuthModel: def __init__(self): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, { 'tid': g.get('tid', None), 'ip': g.get('ip', None) }) self.couch = couchdb.Server(COUCHDB_SERVER) self.couch.resource.credentials = (COUCHDB_USER, COUCHDB_PASS) #self.lggr.info('self.couch :ATM') #self.lggr.info(self.couch) #self.lggr.info('self.couch.resource.credentials :ATM') #self.lggr.info(self.couch.resource.credentials) self.user_database = 'myring_users' self.MAM = MainModel() self.officialsizes = { 'r100': 100, 'r240': 240, 'r320': 320, 'r500': 500, 'r640': 640, 'r800': 800, 'r1024': 1024 } self.thumbnailsizes = {'t75': 75, 't150': 150} #AUTHMODEL def saas_create_user(self, user): #Added validation for SaaS users go here #Check if that username or email exists before trying to create the new user. Reject if TRUE if self.userdb_get_user_by_email(user['email']): self.lggr.info('User with this email already exists') flash('User with this email already exists', 'UI') return False self.lggr.info("self.userdb_get_user_by_handle") if self.userdb_get_user_by_handle(user['username']): self.lggr.info( 'Organization or User with this username already exists') flash('Organization or User with this username already exists', 'UI') return False if self.MAM.create_user(user): self.lggr.info( "User created in DB. Attempting to create image folders...") return True #AUTHMODEL def saas_create_orguser(self, user): #Added validation for SaaS users go here #Check if that username exists before trying to create the new orguser. Reject if TRUE self.lggr.info("self.userdb_get_user_by_handle") if self.userdb_get_user_by_handle(user['username']): self.lggr.info( 'Organization or User with this username already exists') flash('Organization or User with this username already exists', 'UI') return False if self.MAM.create_orguser(user): return True def saas_create_password_key(self, user, key): self.lggr.info("saas_create_password_key") self.lggr.info(user) self.lggr.info(key) data = {} data['id'] = user data['new_password_key'] = key return self.MAM.update_user(data) def saas_set_password(self, user, passhash): self.lggr.info("saas_set_password") self.lggr.info(user) self.lggr.info(passhash) data = {} data['id'] = user data['passhash'] = passhash return self.MAM.update_user(data) def saas_update_user_profile(self, user, changes): changes['id'] = user return self.MAM.update_user(changes) #AUTHMODEL def admin_user_db_create(self, user_database=None, *args): if not user_database: user_database = self.user_database try: #self.db = self.couch[self.user_database] self.lggr.info('Notice: Entering TRY block') self.db = self.MAM.create_db(user_database) self.lggr.info('Notice: ' + user_database + ' database did not exist. Will create') self.userdb_set_db_views(user_database) self.lggr.info('Notice: DB Views Created') return True except (PreconditionFailed): self.lggr.info("Notice: Expected error :", sys.exc_info()[0], sys.exc_info()[1]) #flash(u'Unexpected error:'+ str(sys.exc_info()[0]) + str(sys.exc_info()[1]),'error') self.rs_status = '500' #raise # Will not get here because of 'raise' self.lggr.info( "Notice: Since it already existed, selecting existing one") self.MAM.select_db(user_database) self.lggr.info('Notice: ' + user_database + ' database exists already') return False #AUTHMODEL def admin_user_create(self, data, user_database=None): if not user_database: user_database = self.user_database db = self.couch[user_database] auser = self.MAM.select_user(data['username']) self.lggr.info('Notice: User subtracted from DB ') if auser: self.lggr.info('Notice: ' + data['username'] + ' exists already') return False else: auser = MyRingUser(email=data['email'], firstname=data['firstname'], lastname=data['lastname'], passhash=data['passhash'], guid=data['guid'], salt=data['salt']) auser._id = data['username'] storeresult = auser.store(db) self.lggr.info('Notice: ' + data['username'] + ' created -> ' + str(storeresult)) return True #AUTHMODEL def userdb_set_db_views(self, user_database=None): if not user_database: user_database = self.user_database self.lggr.info('#couchdb_call:' + user_database + '->userdb_set_db_views()') db = self.couch[user_database] view = ViewDefinition( 'auth', 'userbyemail', ''' function(doc) { if(doc.email) { emit(doc.email,doc); } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'auth', 'userbyhandle', ''' function(doc) { if(doc.email) { emit(doc._id,doc); } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'auth', 'userbasic', ''' function(doc) { if(doc.email) { var x = {}; x['name'] = doc.name; x['location'] = doc.location; x['is_org'] = doc.is_org; if(doc.profilepic===''){ x['profilepic'] = ''; }else{ parts = doc.profilepic.split(',') if(parts[0]==''){ x['profilepic'] = parts[1]; }else{ x['profilepic'] = parts[0]; } } emit(doc._id,x); } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'rings', 'count', ''' function(doc) { if(doc.email) { var x = {}; for (var key in doc.rings){ if(!doc.rings[key]['deleted']){ x[doc.rings[key]['ringname']]=doc.rings[key]['count']; } } emit(doc._id,x); } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'rings', 'origin', ''' function(doc) { if(doc.email) { var x = {}; for (var key in doc.rings){ if(!doc.rings[key]['deleted']){ x[doc.rings[key]['origin']] = doc.rings[key]['origin']; } } emit(doc._id,x); } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'rings', 'roles', ''' function(doc) { if(doc.email) { var x = {}; for (var key in doc.rings){ if(!doc.rings[key]['deleted']){ x[doc.rings[key]['ringname']] = new Object(); x[doc.rings[key]['ringname']]['owner']=doc.rings[key]['owner']; x[doc.rings[key]['ringname']]['capturist']=doc.rings[key]['capturist']; x[doc.rings[key]['ringname']]['moderator']=doc.rings[key]['moderator']; } } emit(doc._id,x); } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'orgs', 'peopleteams', ''' function(doc) { if(doc.is_org) { var x = {}; x['people']=doc.people; x['teams']=doc.teams; emit(doc._id,x); } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'orgs', 'user2orgs', ''' function(doc) { if(doc.is_org) { var x = {}; x['handle']=doc._id; x['name']='' if(doc.name){ x['name']=doc.name; } x['location']='' if(doc.location){ x['location']=doc.location; } x['profilepic']=''; if(doc.profilepic){ if(doc.profilepic===''){ x['profilepic'] = ''; }else{ parts = doc.profilepic.split(',') if(parts[0]==''){ x['profilepic'] = parts[1]; }else{ x['profilepic'] = parts[0]; } } } for (var key in doc.people){ emit(doc.people[key]['handle'],x); } } } ''') view.get_doc(db) view.sync(db) view = ViewDefinition( 'orgs', 'invitations', ''' function(doc) { if(doc.is_org) { var x = {}; x['invitations']=doc.invitations; emit(doc._id,x); } } ''') view.get_doc(db) view.sync(db) return True #AUTHMODEL def userdb_get_user_by_email(self, email, user_database=None): #self.lggr.info('flag1.1') if not user_database: user_database = self.user_database #self.lggr.info('flag1.2') db = self.couch[user_database] #self.lggr.info('flag1.3') options = {} options['key'] = email result = db.view('auth/userbyemail', **options) #result = db.iterview('auth/userhash',1,**options) #self.lggr.info(result) #self.lggr.info('flag1.4') item = {} for row in result: item = {} item[u'id'] = row['id'] item[u'key'] = row['key'] item[u'value'] = row['value'] #self.lggr.info('flag1.5') if item: return item else: return False #AUTHMODEL def userdb_get_user_by_handle(self, handle, user_database=None): #self.lggr.info('flag1.1') if not user_database: user_database = self.user_database #self.lggr.info('flag1.2') db = self.couch[user_database] #self.lggr.info('flag1.3') options = {} # options will only accept this: 'key', 'startkey', 'endkey' options['key'] = handle result = db.view('auth/userbyhandle', **options) #result = db.iterview('auth/userhash',1,**options) #self.lggr.info(result) #self.lggr.info('flag1.4') item = {} for row in result: item = {} item[u'id'] = row['id'] item[u'key'] = row['key'] item[u'value'] = row['value'] #self.lggr.info('flag1.5') return item
class ElasticSearchModel: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) def get_a_b(self, handle, ring, q=None): # Connect to Elastic Search Node es_url = ES_NODE connections.create_connection(hosts=[es_url]) field = '_all' s = Search(index=handle,doc_type=ring) \ .query("match", **{field:q}) response = s.execute() print("Searching in %s/%s" % (handle, ring)) print(s.to_dict()) #return response out = [] for hit in response: # hit meta contains: index,score,id,doc_type # i.e: hit.meta.score item = collections.OrderedDict() item['_id'] = hit.meta.id #print #print(hit.meta.score) #print('%s/%s/%s'%(hit.meta.index,hit.meta.doc_type,hit.meta.id)) for m in hit: item[m] = hit[m] item[m + '_flag'] = u'1000' #print (m,hit[m]) out.append(item) return out def unindexer(self, handle, ring=None, idx=None): # Connect to Elastic Search Node es = Elasticsearch([ES_NODE]) out = {} out['unindexed'] = [] if handle and ring and idx: es.delete(index=handle, doc_type=ring, id=idx, ignore=[400, 404]) i = '%s/%s/%s' % (handle, ring, idx) elif handle and ring: #es.delete(index=handle,doc_type=ring, ignore=[400, 404]) This doesnt work # Could not make elasticsearch_py delete a doc_type only requests.delete('%s/%s/%s' % (ES_NODE, handle, ring)) i = '%s/%s' % (handle, ring) elif handle: es.indices.delete(index=handle, ignore=[400, 404]) i = '%s' % (handle) self.lggr.info('UnIndexing:%s' % i) out['unindexed'].append(i) d = {} d['json_out'] = json.dumps(out) d['template'] = 'base_json.html' return d #'index':handle,'type':ringname,'id': idx def handle_indexer(self, url, handle): #1. Get all the active rings for this handle self.RIM = RingsModel() ringlist = self.RIM.user_get_rings(handle) print('RINGLIST:', ringlist) #2. Index one by one out = {} out['indexed'] = [] for ring in ringlist: result = self.indexer(url, handle, ring['ringname']) x = json.loads(result['json_out']) out['indexed'] += x['indexed'] self.lggr.info('Handle Indexed:%s' % handle) d = {} d['json_out'] = json.dumps(out) d['template'] = 'base_json.html' return d def indexer(self, url, handle, ring, idx=None): self.lggr.info('START indexer') # Good to Index (a/b) and (a/b/c) as they use same ring_class. # If you want to index a whole handle (a) use handle_indexer # Connect to Elastic Search Node es_url = ES_NODE self.lggr.info('START @ create_connection') connections.create_connection(hosts=[es_url]) self.lggr.info('END @ create_connection') o = urlparse.urlparse(url) if idx: path = '_api/%s/%s/%s' % (handle, ring, idx) else: path = '_api/%s/%s' % (handle, ring) origin_url = urlparse.urlunparse( (URL_SCHEME, o.netloc, path, '', '', '')) schema, items = self.get_items(origin_url) #Preprare the ES Map (as a class) ring_class, ring_map = self.prepare_class(schema) #Create the index in the ES Cluster (indempotent action) self.create_index(ring_class, origin_url) #Index the item d = {} out = {} out['indexed'] = [] for item in items: #Check that item is valid before attempting to index it if self.valid_item(item, ring_map): #try: if True: handle, ring, idx = self.index_item( ring_class, origin_url, item) i = '%s/%s/%s' % (handle, ring, idx) out['indexed'].append(i) self.lggr.info('Indexed:%s' % i) else: #Here we store possible indexing errors if 'not_indexed' not in out: out['not_indexed'] = [] out['not_indexed'].append(item) self.lggr.error('Document invalid. Not Indexed:%s' % item) d['json_out'] = json.dumps(out) d['template'] = 'base_json.html' self.lggr.info('END indexer') return d def valid_item(self, item, ring_map): self.lggr.info('START valid_item') print("Check item against map:") print(ring_map) v_item = {} for f in ring_map: #print(f) valid = False if f in item: #print(ring_map[f],type(ring_map[f])) #if ring_map[f] is elasticsearch_dsl.field.String: if isinstance(ring_map[f], String): #Check if item[f] is a string if (isinstance(item[f], str) or isinstance(item[f], unicode)): valid = True self.lggr.info('%s -> %s is a string (%s)' % (f, item[f], type(item[f]))) else: self.lggr.error('%s -> %s not a string (%s)' % (f, item[f], type(item[f]))) #elif ring_map[f] is elasticsearch_dsl.field.Object: elif isinstance(ring_map[f], Object): #Check if item[f] is an object if isinstance(item[f], dict): v_item[f] = {} print(ring_map[f].properties) for p in ring_map[f].properties: #Check if the property exists in the item if p in item[f]: #Check if the property is an elasticsearch_dsl.field.String: if isinstance(ring_map[f].properties[p], String): #Check if item[f] is a string if (isinstance(item[f][p], str) or isinstance(item[f][p], unicode)): v_item[f][p] = item[f][p] valid = True else: self.lggr.error('%s not a string (%s)' % (item[f], type(item[f]))) else: self.lggr.error('%s not in item' % p) else: self.lggr.error('%s not a dictionary (%s)' % (item[f], type(item[f]))) # TO-DO: Do we want nested objects? If yes develop. if valid: # Add field to the output v_item[f] = item[f] self.lggr.info('Valid item. Will Index') else: self.lggr.info('Invalid item. Will not index') else: self.lggr.info('%s not in map' % f) self.lggr.info('END valid_item') if len(v_item) > 0: return v_item else: return False def valid_api_url(self, url): o = urlparse.urlparse(url) p = o.path.split('/') if p[1] != '_api': path = '/_api' + o.path else: path = o.path return urlparse.urlunparse( (URL_SCHEME, o.netloc, path, '', 'schema=1&limit=_all', '')) def get_items(self, url): url = self.valid_api_url( url) + '&access_token=%s&fieldid=1' % TEMP_ACCESS_TOKEN self.lggr.info('START get_items ->%s' % url) result = requests.get(url, verify=False) self.lggr.info('result ->%s' % result.text) self.lggr.info('result.text ->%s' % result.text) r = result.json() self.lggr.info('result.json() ->%s' % r) schema = {'rings': r['rings'], 'fields': r['fields']} items = r['items'] self.lggr.info('END get_items') return schema, items def prepare_class(self, schema): self.lggr.info('START prepare_class') d = {} for field in schema['fields']: if field['FieldType'] == 'INTEGER': d[field['FieldId']] = Integer() elif field['FieldType'] == 'OBJECT': if field['FieldMultilingual']: f = {} f['spa'] = String(analyzer='spanish') f['eng'] = String(analyzer='english') f['ita'] = String(analyzer='italian') f['fra'] = String(analyzer='french') d[field['FieldId']] = Object(properties=f) else: #Some other kind of object d[field['FieldId']] = String() elif field['FieldType'] == 'ARRAY': d[field['FieldId']] = String() elif field['FieldType'] == 'BOOLEAN': d[field['FieldId']] = Integer() else: d[field['FieldId']] = String() print(d) raw_map = d.copy() self.lggr.info('END prepare_class') return type(str(schema['rings'][0]['RingName']), (DocType, ), d), raw_map def subtract_h_r_i(self, origin_url): self.lggr.info('START subtract_h_r_i') url = self.valid_api_url(origin_url) print(url) o = urlparse.urlparse(url) p = o.path.split('/') handle = p[2] if len(p) >= 4: ringname = p[3] else: ringname = None if len(p) >= 5: idx = p[4] else: idx = None self.lggr.info('END subtract_h_r_i') return handle, ringname, idx def create_index(self, ring_class, origin_url): self.lggr.info('START create_index') handle, ringname, idx = self.subtract_h_r_i(origin_url) # create the mappings in elasticsearch R = ring_class.init(handle) self.lggr.info('END create_index') return R def index_item(self, ring_class, origin_url, item): self.lggr.info('START index_item') handle, ringname, idx = self.subtract_h_r_i(origin_url) #overwrite the idx with items idx = item['_id'] # create the mappings in elasticsearch #print(R) #print(handle) #print(ringname) #print(idx) #print(item) # create and save an item article = ring_class(meta={ 'index': handle, 'type': ringname, 'id': idx }, **item) print(article) article.save() print('SAVED') self.lggr.info('END index_item') return (handle, ringname, idx)
class TeamsModel: def __init__(self,tid=None,ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid,'ip': ip}) self.MAM = MainModel(tid=tid,ip=ip) #TEAMSMODEL def post_a_m_n_members(self,handle,team,member): #Creates new member in the team doc = self.MAM.select_user(handle) self.lggr.debug(doc['teams']) for teamd in doc['teams']: if teamd['teamname'] == team: self.lggr.debug('Members for team %s: %s'%(team,teamd['members'])) memberlist = [] if 'members' not in teamd: teamd['members'] = [] for memberd in teamd['members']: memberlist.append(memberd['handle']) if member in memberlist: #User is already memberm abort adding a member return False else: newmember = {'handle': member, 'addedby': current_user.id, 'added': str(datetime.now())} teamd['members'].append(newmember) break self.MAM.post_user_doc(doc) return True #TEAMSMODEL def delete_a_m_n_members(self,handle,team,member): #Deletes an existing member from the team doc = self.MAM.select_user(handle) self.lggr.debug('%s'%doc['teams']) count1 = 0 for teamd in doc['teams']: if teamd['teamname'] == team: self.lggr.debug('Members for team %s: %s '%(team,teamd['members'])) memberlist = [] count2 = 0 for memberd in teamd['members']: if member == memberd['handle']: del doc['teams'][count1]['members'][count2] count2 += 1 count1 += 1 if self.MAM.post_user_doc(doc): return True else: return False #TEAMSMODEL def post_a_m_n_rings(self,handle,team,ring): #Creates new member in the team doc = self.MAM.select_user(handle) for teamd in doc['teams']: if teamd['teamname'] == team: ringlist = [] if 'rings' not in teamd: teamd['rings'] = [] for ringd in teamd['rings']: ringlist.append(ringd['ringname']) if ring in ringlist: #Ring is already in the team list return False else: newring = {'handle' : handle, 'ringname': ring, 'addedby': current_user.id, 'added': str(datetime.now())} teamd['rings'].append(newring) break self.MAM.post_user_doc(doc) return True #TEAMSMODEL def delete_a_m_n_rings(self,handle,team,ring): #Deletes an existing member from the team doc = self.MAM.select_user(handle) self.lggr.debug(doc['teams']) count1 = 0 for teamd in doc['teams']: if teamd['teamname'] == team: ringlist = [] count2 = 0 for ringd in teamd['rings']: if ring == ringd['ringname']: del doc['teams'][count1]['rings'][count2] count2 += 1 count1 += 1 if self.MAM.post_user_doc(doc): return True else: return False def put_a_m_n_settings(self,handle,team,parameters): doc = self.MAM.select_user(handle) for teamd in doc['teams']: if teamd['teamname'] == team: if 'description' in parameters: teamd['description'] = parameters['description'] if 'teamauth' in parameters: teamd['roles'] = [] if parameters['teamauth'] == 'RWX': role = 'team_admin' elif parameters['teamauth'] == 'RW': role = 'team_writer' elif parameters['teamauth'] == 'R': role = 'team_reader' else: role = False if role: newrole = {'handle' : handle, 'role': role, 'addedby': current_user.id, 'added': str(datetime.now())} teamd['roles'].append(newrole) break; if self.MAM.post_user_doc(doc): return True else: return False def get_a_m_all_p_q(self,handle,member): '''All the teams that this <member> belongs to in this org <handle>''' memberships = [] doc = self.MAM.select_user(handle) for teamd in doc['teams']: for memberd in teamd['members']: if member == memberd['handle']: memberships.append(teamd['teamname']) return memberships
def setup_local_logger(tid, ip): return AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip})
class PeopleController: def __init__(self,tid=None,ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid,'ip': ip}) self.MAM = MainModel(tid=tid,ip=ip) self.PEM = PeopleModel(tid=tid,ip=ip) self.TEM = TeamsModel(tid=tid,ip=ip) # GET/a def get_a_p(self,handle,person,*args,**kargs): d = {} peopleteams = self.MAM.is_org(handle) if peopleteams: #This is an organization d['peoplelist'] = peopleteams['people'] d['peoplelistlen'] = len(peopleteams['people']) for person in peopleteams['people']: #get the profilepic for this person person_user_doc = self.MAM.select_user_doc_view('auth/userbasic',person['handle']) if person_user_doc: person['thumbnail'] = person_user_doc['profilepic'] person['memberships'] = self.TEM.get_a_m_all_p_q(handle,person['handle']) d['template'] = 'avispa_rest/get_a_p.html' else: #This is a regular user #d['redirect'] = '/'+handle+'/_home' d['redirect'] = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) return d # POST/a def post_a_p(self,handle,person,rqform=None,*args,**kargs): #We need to recover from request as it doesn't come via URL person = rqform.get('newperson') #Check if the user exists or not if self.MAM.user_exists(person): result = self.PEM.post_a_p(handle,person) if result: self.lggr.debug('Awesome , you just added %s to the organization'%person) #msg = 'Item put with id: '+idx flash('Awesome , you just added %s to the organization'%person,'UI') else: self.lggr.error('Awesome , you just added %s to the organization'%person) flash('There was an error adding %s to the organization.'%s,'ER') else: self.lggr.debug('%s is not a MyRing user. Please create it first.'%person) flash('%s is not a MyRing user. Please create it first.'%person,'ER') #redirect = '/'+handle+'/_people' redirect = url_for('avispa_rest.people_a_p', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status':200} return d #DELETE /a/b def delete_a_p_q(self,handle,person,*args,**kargs): #Will delete an existing person self.lggr.debug('Trying to delete the following person: %s'%person) #Check if the user exists or not if self.MAM.user_exists(person): result = self.PEM.delete_a_p_q(handle,person) if result: self.lggr.debug('You just deleted %s from the organization'%person) flash('You just deleted %s from the organization'%person,'UI') else: self.lggr.error('There was an error deleting %s from the organization.'%person) flash('There was an error deleting %s from the organization.'%person,'ER') else: self.lggr.debug('%s is not a MyRing user.'%person) flash('%s is not a MyRing user.'%person,'ER') #redirect = '/'+handle+'/_people' redirect = url_for('avispa_rest.people_a_p', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status':200} return d
class Upload: def __init__(self, handle): self.handle = handle self.rs_status = '' self.officialsizes = { 'r100': 100, 'r240': 240, 'r320': 320, 'r500': 500, 'r640': 640, 'r800': 800, 'r1024': 1024 } self.thumbnailsizes = {'t75': 75, 't150': 150} self.allowed_formats = set( ['txt', 'pdf', 'png', 'jpg', 'JPG', 'jpeg', 'gif']) logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, { 'tid': g.get('tid', None), 'ip': g.get('ip', None) }) def blob_from_s3(self, bucket, id): #Subtract original from s3 and put it in memory image_binary = '' return image_binary def blob_from_file(self, file): #Load the image blob print(file) file.seek(0) image_binary = file.read() return image_binary #DRIVER FUNCTION def do_upload(self, image_binary): response = {} image_sizes = [] #Load the image with Image(blob=image_binary) as img: #Prepare image components imgid = self._generate_imgid() filename = imgid + '.jpg' #Image analysis longside, shortside, orientation = self._img_orientation( img.width, img.height) #Constrain original if needed if longside > 2000: img = self._img_resize(img, 2000, orientation) path = '%s/%s' % (self.handle, 'o') self._s3_save(img, path, filename) m = self._generate_metadata(img.width, img.height, 'o') image_sizes.append(m) #Save scaled down versions and thumbnail #Plan of action regular_wo, thumb_wo = self._image_workorder(longside, shortside) #Scaled down versions for wo in regular_wo: with img.clone() as i: ii = self._img_resize(i, regular_wo[wo], orientation) path = '%s/%s' % (self.handle, wo) if STORE_MODE == 'LOCAL': self._local_save(i, path, filename) elif STORE_MODE == 'S3': self._s3_save(i, path, filename) m = self._generate_metadata(ii.width, ii.height, wo) image_sizes.append(m) #Thumbnail versions for wo in thumb_wo: with img.clone() as i: ii = self._img_resize(i, thumb_wo[wo], orientation) iii = self._img_thumbcrop(ii, orientation) path = '%s/%s' % (self.handle, wo) self._file_save(i, path, filename) m = self._generate_metadata(iii.width, iii.height, wo) image_sizes.append(m) response['status'] = self.rs_status response['imgid'] = imgid response['imgsizes'] = image_sizes return response #DRIVER FUNCTION def do_copy(self, from_handle, to_handle, imgid): #Pull file from S3 bucket f = self._pull_file_from_s3(origin, targetimgid) return response def _generate_metadata(self, width, height, sizename): multiplied = {} multiplied['mime-type'] = 'image/jpeg' multiplied['extension'] = 'jpg' multiplied['width'] = width multiplied['height'] = height multiplied['sizename'] = sizename multiplied['unit'] = 'pixel' #self.lggr.debug(multiplied) return multiplied def check_extension(self, filename): #TO-DO This a very soft check. Please implement Real Format Check if not '.' in filename and filename.rsplit( '.', 1)[1] in self.allowed_formats: self.lggr.error('Error: This file format is not allowed: ' + str(filename)) flash(u'This file format is not allowed: ' + str(filename), 'ER') self.rs_status = '415' return False return True def _pull_file_from_s3(self, handle, imgid): pass #1. Subtract image from S3 #2. Put it in self.f def _generate_imgid(self): return str(random.randrange(1000000000, 9999999999)) def _image_workorder(self, longside, shortside): regular_wo = {} thumb_wo = {} for r in self.officialsizes: if longside >= self.officialsizes[r]: regular_wo[r] = self.officialsizes[r] for t in self.thumbnailsizes: if shortside >= self.thumbnailsizes[t]: thumb_wo[t] = self.thumbnailsizes[t] return (regular_wo, thumb_wo) def _img_orientation(self, width, height): if width > height: longside = width shortside = height orientation = "landscape" if width < height: longside = height shortside = width orientation = "portrait" if width == height: longside = height shortside = width orientation = "square" return longside, shortside, orientation def _img_resize(self, img, mainside, orientation): if orientation == 'portrait': img.transform(resize='x' + str(mainside)) #Height based #img.resize(height=int(mainside)) elif orientation == 'landscape': img.transform(resize=str(mainside)) #Width based #img.resize(width=int(mainside)) #img.transform(resize=str(mainside)) elif orientation == 'square': img.transform(resize=str(mainside)) #Width based #img.resize(width=int(mainside)) return img def _img_thumbcrop(self, img, orientation): offset = abs(img.width - img.height) / 2 #This centers the crop if orientation == 'portrait': img.crop(0, offset, width=img.width, height=img.width) if orientation == 'landscape': img.crop(offset, 0, width=img.height, height=img.height) return img def _file_save(self, file, path, filename): self._s3_save(file, path, filename) def _s3_save(self, file, path, filename): self.lggr.info("Storing image in S3: %s/%s" % (path, filename)) conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) bucket = conn.get_bucket(IMAGE_BUCKET_NAME) #k = Key(bucket) k = boto.s3.key.Key(bucket) k.key = '%s/%s' % (path, filename) print(k) print(k.key) print(file) fl = cStringIO.StringIO() file.save(fl) #print fl fl.seek(0) k.set_contents_from_file(fl) k.set_acl('public-read') #AttributeError: 'Image' object has no attribute 'tell' #b = fl.read() #print(b) #k.set_contents_from_string(b) return True def check_upload_path(self, path): pass def check_filename(self): pass def set_max_filesize(self): pass def set_max_filename(self): pass def set_max_width(self): pass def set_max_height(self): pass def set_allowed_types(self, types): pass def set_image_properties(self): pass def set_xss_clean(self): pass def is_image(self): pass def is_allowed_filetype(self): pass def is_allowed_filesize(self): pass def is_allowed_dimensions(self): pass def validate_upload_path(self): pass def get_extension(self, filename): pass def clean_file_name(self, filename): pass def limit_filename_length(self, filename, length): pass def do_xss_clean(self): pass def set_error(self, msg): pass def display_errors(self): pass def mime_types(self, mime): pass def _prep_filename(self, filename): pass def _file_mime_type(self, file): pass
class CollectionsController: def __init__(self, tid=None, ip=None): logger = logging.getLogger('Avispa') self.lggr = AvispaLoggerAdapter(logger, {'tid': tid, 'ip': ip}) self.RIM = RingsModel(tid=tid, ip=ip) self.COM = CollectionsModel(tid=tid, ip=ip) self.CB = CollectionBuilder(tid=tid, ip=ip) # GET/a def get_a_x(self, handle, collection, idx, api=False, *args, **kargs): 'Show list of collections' collectionlist = self.COM.get_a_x(handle) count = 0 if collectionlist: for collection in collectionlist: count = count + 1 else: collectionlist = [] collectionlistlen = count #raise Exception("Debug") d = { 'template': 'avispa_rest/get_a_x.html', 'collectionlist': collectionlist, 'collectionlistlen': collectionlistlen } return d def get_rq_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection get_rq_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def get_rs_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection get_rs_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def get_q_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection get_q_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d # POST/a def post_a_x(self, handle, collection, idx, api=False, rqform=None, *args, **kargs): #Build the actual collection result = self.CB.post_a_x(rqform, handle) if result: self.lggr.debug('Awesome , you just created a new Collection') #msg = 'Item put with id: '+idx if api: out = {} out['Success'] = True out['Message'] = 'The collection has been created' d = {} d['api_out'] = json.dumps(out) d['template'] = '/base_json.html' else: flash("Your new Collection has been created", 'UI') #redirect = '/'+handle redirect = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} else: if api: out = {} out['Sucess'] = False out['Message'] = 'There was an error creating the Collection' data = {} data['api_out'] = json.dumps(out) d['template'] = '/base_json.html' else: flash("There was an error creating the Collection", 'UI') return d def post_rq_a_x(self, handle, collection, idx, api=False, *args, **kargs): #Generates de form to create the collection ringlist = self.RIM.user_get_rings(handle) d = { 'message': 'Using Collection post_rq_a_x for handle ' + handle, 'template': 'avispa_rest/post_rq_a_x.html', 'ringlist': ringlist } return d def post_rs_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection post_rs_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d #PUT /a def put_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection put_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def put_rq_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection put_rq_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def put_rs_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection put_rs_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d #PATCH /a def patch_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection patch_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def patch_rq_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection patch_rq_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def patch_rs_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection patch_rs_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d #DELETE /a def delete_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection delete_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def delete_rq_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection delete_rq_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def delete_rs_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection delete_rs_a for handle ' + handle, 'template': 'avispa_rest/index.html' } return d #SEARCH /a def search_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection search_a for handle ' + handle, 'template': 'avispa_rest/search_a.html' } return d def search_rq_a_x(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection search_rq_a for handle ' + handle, 'template': 'avispa_rest/search_rq_a.html' } return d # /a/b #GET /a/x/y def get_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): #THIS IS NOT USED . SEE CollectionsController.put_rq_a_x_y() instead d = { 'message': 'Using Collection get_a_x_y for handle ' + handle, 'template': 'avispa_rest/get_a.html' } return d def get_rq_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection get_rq_a_x_y for handle:' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d def get_rs_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection get_rs_a_x_y for handle:' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d #POST /a/x/y def post_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection post_a_x_y for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def post_rq_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection post_rq_a_x_y for handle ' + handle, 'template': 'avispa_rest/index.html' } return d def post_rs_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection post_rs_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d #PUT /a/x/y def put_a_x_y(self, handle, collection, idx, api=False, rqform=None, *args, **kargs): # Introduce the changes to the existing collection CB = CollectionBuilder() result = CB.put_a_x_y(rqform, handle, collection) if result: self.lggr.debug('Awesome , you just updated a Collection') #msg = 'Item put with id: '+idx flash("Your Collection has been updated", 'UI') redirect = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} else: d = { 'message': 'There was an error updating the collection', 'template': 'avispa_rest/index.html' } return d def put_rq_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): #Form to edit a collection ringlist = self.RIM.user_get_rings(handle) collectiond = self.COM.get_a_x_y( handle, collection) #It comes with just one collection collectionrings = [] for ring in collectiond['rings']: collectionrings.append(ring['handle'] + '_' + ring['ringname']) d = { 'message': 'Using Collection put_rq_a_x_y for handle ' + handle, 'template': 'avispa_rest/put_rq_a_x_y.html', 'ringlist': ringlist, 'collectionlist': collectiond, 'collectionrings': collectionrings } #raise Exception('debug') #[u'blacklabelrobot_tricoders_0.1.0', u'blacklabelrobot_pancreas_0.1.0', u'blacklabelrobot_intestino_0.1.0', u'blacklabelrobot_tricoders4_'] return d def put_rs_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection put_rs_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d #PATCH /a/x/y def patch_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection patch_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d def patch_rq_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection patch_rq_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d def patch_rs_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection patch_rs_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d #DELETE /a/x/y def delete_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): #Will delete an existing collection result = self.COM.delete_a_x_y(handle, collection) if result: self.lggr.debug('Awesome , you just deleted a Collection') #msg = 'Item put with id: '+idx flash("Your Collection has been deleted", 'UI') #redirect = '/'+handle redirect = url_for('avispa_rest.home', handle=handle, _external=True, _scheme=URL_SCHEME) d = {'redirect': redirect, 'status': 200} else: d = { 'message': 'There was an error deleting the collection', 'template': 'avispa_rest/index.html' } return d def delete_rq_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection delete_rq_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d def delete_rs_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection delete_rs_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/index.html' } return d #SEARCH /a/b def search_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection search_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/search_a_b.html' } return d def search_rq_a_x_y(self, handle, collection, idx, api=False, *args, **kargs): d = { 'message': 'Using Collection search_rq_a_x_y for handle ' + handle + ', collection:' + collection, 'template': 'avispa_rest/search_rq_a_b.html' } return d