def urlcreate(request, volume_name, g_name, g_password, host, port, read_write): session = request.session username = session['login_email'] user = db.read_user(username) kwargs = {} kwargs['port'] = int(port) kwargs['host'] = host kwargs['ms_username'] = g_name kwargs['ms_password'] = g_password kwargs['read_write'] = read_write vol = db.read_volume(volume_name) if not vol: return HttpResponse("No volume %s exists." % volume_name) if (vol.volume_id not in user.volumes_r) and (vol.volume_id not in user.volumes_rw): return HttpResponse( "Must have read rights to volume %s to create UG for it." % volume_name) try: new_ug = db.create_user_gateway(user, vol, **kwargs) except Exception as E: return HttpResponse("UG creation error: %s" % E) return HttpResponse("UG succesfully created: " + str(new_ug))
def allgateways(request): ''' View to look at all AG's in a tabular format, with owners and attached volumes. ''' session = request.session username = session['login_email'] # Get gateways try: qry = db.list_acquisition_gateways() except: qry = [] gateways = [] for g in qry: gateways.append(g) # Get volumes and owners vols = [] g_owners = [] for g in gateways: volset = [] for v in g.volume_ids: volset.append(db.read_volume(v)) vols.append(volset) attrs = {"SyndicateUser.owner_id ==":g.owner_id} g_owners.append(db.get_user(attrs)) gateway_vols_owners = zip(gateways, vols, g_owners) t = loader.get_template('gateway_templates/allacquisitiongateways.html') c = RequestContext(request, {'username':username, 'gateway_vols_owners':gateway_vols_owners}) return HttpResponse(t.render(c))
def deactivatevolume(request, volume_id): session = request.session username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) if request.method == "POST": form = libforms.Password(request.POST) if not form.is_valid(): session['message'] = "Password required." return redirect('django_volume.views.volumesettings', vol.volume_id) # Check password hash hash_check = Volume.generate_password_hash( form.cleaned_data['password'], vol.volume_secret_salt) if hash_check != vol.volume_secret_salted_hash: session['message'] = "Incorrect password." return redirect('django_volume.views.volumesettings', vol.volume_id) fields = {'active': False} db.update_volume(vol.volume_id, **fields) session['new_change'] = "We've deactivated your volume." session['next_url'] = '/syn/volume/' + str(vol.volume_id) session['next_message'] = "Click here to go back to your volume." return redirect('/syn/thanks') return redirect("/syn/volume/" + str(vol.volume_id))
def allgateways(request): ''' View to look at all AG's in a tabular format, with owners and attached volumes. ''' session = request.session username = session['login_email'] # Get gateways try: qry = db.list_acquisition_gateways() except: qry = [] gateways = [] for g in qry: gateways.append(g) # Get volumes and owners vols = [] g_owners = [] for g in gateways: volset = [] for v in g.volume_ids: volset.append(db.read_volume(v)) vols.append(volset) attrs = {"SyndicateUser.owner_id ==": g.owner_id} g_owners.append(db.get_user(attrs)) gateway_vols_owners = zip(gateways, vols, g_owners) t = loader.get_template('gateway_templates/allacquisitiongateways.html') c = RequestContext(request, { 'username': username, 'gateway_vols_owners': gateway_vols_owners }) return HttpResponse(t.render(c))
def test( path, args ): username = args['username'] # enforce types if args.has_key('version'): args['version'] = int(args['version']) if args.has_key( 'mtime_sec' ): args['mtime_sec'] = int(args['mtime_sec']) if args.has_key( 'mtime_nsec' ): args['mtime_nsec'] = int(args['mtime_nsec']) if args.has_key( 'mode' ): args['mode'] = int(args['mode']) if args.has_key( 'size' ): args['size'] = int(args['size']) volume_name = args['volume_name'] volume = storage.read_volume( volume_name ) if volume == None: raise Exception("No such volume '%s'" % volume_name ) user = storage.read_user( username ) if user == None: raise Exception("No such user '%s'" % username ) # update the entry rc = storage.update_msentry( user, volume, path, **args ) if rc != 0: raise Exception("storage.update_msentry rc = %s" % rc) return (200, "OK")
def test(path, args): username = args['username'] # enforce types if args.has_key('version'): args['version'] = int(args['version']) if args.has_key('mtime_sec'): args['mtime_sec'] = int(args['mtime_sec']) if args.has_key('mtime_nsec'): args['mtime_nsec'] = int(args['mtime_nsec']) if args.has_key('mode'): args['mode'] = int(args['mode']) if args.has_key('size'): args['size'] = int(args['size']) volume_name = args['volume_name'] volume = storage.read_volume(volume_name) if volume == None: raise Exception("No such volume '%s'" % volume_name) user = storage.read_user(username) if user == None: raise Exception("No such user '%s'" % username) # update the entry rc = storage.update_msentry(user, volume, path, **args) if rc != 0: raise Exception("storage.update_msentry rc = %s" % rc) return (200, "OK")
def viewgateway(request, g_id=0): ''' The view for viewing and changing any of the main settings on any UG. Passes forms for changing different settings, and the volumes attached to the gateway. ''' session = request.session username = session['login_email'] message = session.pop('message', "") g_id = int(g_id) g = db.read_user_gateway(g_id) if not g: logging.error("Error reading gateway %d : Does note exist" % g_id) message = "No user gateway with the ID %d exists." % g_id t = loader.get_template("gateway_templates/viewgateway_failure.html") c = Context({'message': message, 'username': username}) return HttpResponse(t.render(c)) # Create necessary forms location_form = gatewayforms.ModifyGatewayLocation(initial={ 'host': g.host, 'port': g.port }) change_form = gatewayforms.ChangeVolume() password_form = libforms.Password() change_password_form = libforms.ChangePassword() vol = db.read_volume(g.volume_id) if not vol: vol = None owner = None """ if g.volume_id != 0: logging.error("Volume ID %s in gateways volume_ids does not map to volume. Gateway: %s" % (g.volume_id, g_id)) return redirect('django_ug.views.allgateways') else: vol = None owner = None """ else: attrs = {"SyndicateUser.owner_id ==": vol.owner_id} owner = db.get_user(attrs) logging.info(owner) logging.info(vol.owner_id) t = loader.get_template("gateway_templates/viewusergateway.html") c = RequestContext( request, { 'username': username, 'gateway': g, 'message': message, 'vol': vol, 'owner': owner, 'location_form': location_form, 'change_form': change_form, 'password_form': password_form, 'change_password_form': change_password_form }) return HttpResponse(t.render(c))
def wrapper(*args, **kw): session = args[0].session user = db.read_user(session['login_email']) vol = db.read_volume(kw['volume_id']) if not vol: return redirect('django_volume.views.failure') if user.owner_id != vol.owner_id: return redirect('django_volume.views.failure') return f(*args, **kw)
def volumepermissions(request, volume_id): ''' View for the webpage that shows the current state of user permissions for the volume. Populates initial_perms if not already extant. ''' session = request.session username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) message = session.pop('message', "") initial_data = session.get('initial_perms' + str(volume_id), None) if not initial_data: rw_attrs = {'SyndicateUser.volumes_rw ==': vol.volume_id} rw = db.list_users(rw_attrs) r_attrs = {'SyndicateUser.volumes_r ==': vol.volume_id} r = db.list_users(r_attrs) initial_data = [] for u in rw: if u.owner_id == vol.owner_id: continue initial_data.append({'user': u.email, 'read': True, 'write': True}) for u in r: initial_data.append({ 'user': u.email, 'read': True, 'write': False }) session['initial_perms' + str(volume_id)] = initial_data PermissionFormSet = formset_factory(forms.Permissions, extra=0) addform = forms.AddPermissions passwordform = libforms.Password if initial_data: formset = PermissionFormSet(initial=initial_data) else: formset = None t = loader.get_template('volumepermissions.html') c = RequestContext( request, { 'username': username, 'volume': vol, # 'users':users, # 'rw':rw, # 'r':r, 'addform': addform, 'passwordform': passwordform, 'formset': formset, 'message': message }) return HttpResponse(t.render(c))
def test( path, args ): username = args['username'] volume_name = args['volume_name'] user = storage.read_user( username ) if user == None: raise Exception("user '%s' does not exist" % username ) volume = storage.read_volume( volume_name ) if volume == None: raise Exception("volume '%s' does not exist" % volume_name ) ents = [] if not path.endswith("/"): # read file ent = storage.read_msentry( user, volume, path ) if ent == None: raise Exception("No such entry: %s" % path ) if type(ent) == types.IntType: raise Exception("storage.read_msentry rc = %d" % ent ) ents.append( ent ) else: # read dir parent = storage.read_msentry( user, volume, path ) if parent == None: raise Exception("No such entry: %s" % path) if type(parent) == types.IntType: raise Exception("storage.read_msentry rc = %d" % parent) ents = storage.read_msentry_children( volume, path, parent.num_children ) ents = [parent] + ents msg = "<table border=\"1\"><tr>" for attr in MSEntry.required_attrs: msg += "<td><b>" + attr + "</b></td>" msg += "</tr>" for ent in ents: msg += "<tr>" for attr in MSEntry.required_attrs: msg += "<td>" + str( getattr(ent, attr) ) + "</td>" msg += "</tr>" msg += "</table>" return (200, msg)
def test(path, args): username = args['username'] volume_name = args['volume_name'] user = storage.read_user(username) if user == None: raise Exception("user '%s' does not exist" % username) volume = storage.read_volume(volume_name) if volume == None: raise Exception("volume '%s' does not exist" % volume_name) ents = [] if not path.endswith("/"): # read file ent = storage.read_msentry(user, volume, path) if ent == None: raise Exception("No such entry: %s" % path) if type(ent) == types.IntType: raise Exception("storage.read_msentry rc = %d" % ent) ents.append(ent) else: # read dir parent = storage.read_msentry(user, volume, path) if parent == None: raise Exception("No such entry: %s" % path) if type(parent) == types.IntType: raise Exception("storage.read_msentry rc = %d" % parent) ents = storage.read_msentry_children(volume, path, parent.num_children) ents = [parent] + ents msg = "<table border=\"1\"><tr>" for attr in MSEntry.required_attrs: msg += "<td><b>" + attr + "</b></td>" msg += "</tr>" for ent in ents: msg += "<tr>" for attr in MSEntry.required_attrs: msg += "<td>" + str(getattr(ent, attr)) + "</td>" msg += "</tr>" msg += "</table>" return (200, msg)
def delete_and_update(ag_id, attached_volume_ids): db.delete_acquisition_gateway(ag_id) for v in attached_volume_ids: vol = db.read_volume(v) if not vol: continue new_ag_ids = vol.ag_ids new_ag_ids.remove(ag_id) attrs = {"ag_ids": new_ag_ids} db.update_volume(v, **attrs) session.pop("ag_initial_data", None)
def delete_and_update(ag_id, attached_volume_ids): db.delete_acquisition_gateway(ag_id) for v in attached_volume_ids: vol = db.read_volume(v) if not vol: continue new_ag_ids = vol.ag_ids new_ag_ids.remove(ag_id) attrs = {"ag_ids":new_ag_ids} db.update_volume(v, **attrs) session.pop("ag_initial_data", None)
def delete_and_update(rg_id, attached_volume_ids): db.delete_replica_gateway(rg_id) for v in attached_volume_ids: vol = db.read_volume(v) if not vol: continue new_rg_ids = vol.rg_ids new_rg_ids.remove(rg_id) attrs = {"rg_ids":new_rg_ids} db.update_volume(v, **attrs) session.pop("rg_initial_data" + str(g_id), None)
def delete_and_update(rg_id, attached_volume_ids): db.delete_replica_gateway(rg_id) for v in attached_volume_ids: vol = db.read_volume(v) if not vol: continue new_rg_ids = vol.rg_ids new_rg_ids.remove(rg_id) attrs = {"rg_ids": new_rg_ids} db.update_volume(v, **attrs) session.pop("rg_initial_data" + str(g_id), None)
def changedesc(request, volume_id): session = request.session username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) if request.method != "POST": return redirect('/syn/volume/' + str(vol.volume_id) + '/settings') form = libforms.Password(request.POST) desc_form = forms.ChangeVolumeD(request.POST) old_data = {} if not form.is_valid(): session['message'] = "Password required." desc_form.is_valid() if desc_form.errors: session['old_data' + str(volume_id)] = "" else: session['old_data' + str(volume_id)] = desc_form.cleaned_data['description'] return redirect('django_volume.views.volumesettings', volume_id) # Check password hash hash_check = Volume.generate_password_hash(form.cleaned_data['password'], vol.volume_secret_salt) if hash_check != vol.volume_secret_salted_hash: session['message'] = "Incorrect password." desc_form.is_valid() if desc_form.errors: session['old_data' + str(volume_id)] = "" else: session['old_data' + str(volume_id)] = desc_form.cleaned_data['description'] return redirect('django_volume.views.volumesettings', volume_id) if not desc_form.is_valid(): session['message'] = "Invalid description field entries." return redirect('django_volume.views.volumesettings', volume_id) kwargs = {} if desc_form.cleaned_data['description']: kwargs['description'] = desc_form.cleaned_data['description'] db.update_volume(vol.volume_id, **kwargs) session.pop('old_data' + str(volume_id), None) session['new_change'] = "We've changed your volume description." session['next_url'] = '/syn/volume/' + str(vol.volume_id) session['next_message'] = "Click here to go back to your volume." return redirect('/syn/thanks')
def read_volume(name): """ Read a Volume. Positional arguments: name (str): The name of the Volume to read. Returns: On success, this method returns the Volume data. On failure, it raises an exception. Authorization: An administrator can read any Volume. A user can only read Volumes that (s)he owns. """ return storage.read_volume(name)
def test( path, args ): username = args['username'] volume_name = args['volume_name'] volume = storage.read_volume( volume_name ) if volume == None: raise Exception( "volume %s' does not exist" % volume_name ) user = storage.read_user( username ) if user == None: raise Exception( "user '%s' does not exist" % username ) # create the entry ftype = MSENTRY_TYPE_FILE size = 0 delim = "" if path.endswith("/"): ftype = MSENTRY_TYPE_DIR size = 4096 delim = "/" now_sec, now_nsec = storage.clock_gettime() rc = storage.create_msentry( user, volume, ftype=ftype, fs_path=path, url=os.path.join( "http://localhost:32780/", path.strip('/') ) + delim, version=1, ctime_sec=now_sec, ctime_nsec=now_nsec, mtime_sec=now_sec, mtime_nsec=now_nsec, owner_id=user.owner_id, volume_id=volume.volume_id, mode=0755, size=size ) if rc != 0: raise Exception("storage.create_msentry rc = %s" % rc) return (200, "OK")
def test(path, args): volume_name = args['volume_name'] username = args['username'] user = storage.read_user(username) volume = storage.read_volume(volume_name) if user == None: raise Exception("No such user '%s'" % username) if volume == None: raise Exception("No such volume '%s'" % volume_name) # delete the entry rc = storage.delete_msentry(user, volume, path) if rc != 0: raise Exception("storage.delete_msentry rc = %s" % rc) return (200, "OK")
def test(path, args): volume_name = args["volume_name"] username = args["username"] user = storage.read_user(username) volume = storage.read_volume(volume_name) if user == None: raise Exception("No such user '%s'" % username) if volume == None: raise Exception("No such volume '%s'" % volume_name) # delete the entry rc = storage.delete_msentry(user, volume, path) if rc != 0: raise Exception("storage.delete_msentry rc = %s" % rc) return (200, "OK")
def viewvolume(request, volume_id): session = request.session username = session['login_email'] user = db.read_user(username) vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.failure') UserInfo = namedtuple("UserInfo", ["email", "caps_str"]) user_info = [] user_info.append(UserInfo(email=user.email, caps_str="owner")) rw_users = db.list_rw_volume_users(vol.volume_id, sort=True, projection=['email']) ro_users = db.list_ro_volume_users(vol.volume_id, sort=True, projection=['email']) for u in rw_users: user_info.append(UserInfo(email=u.email, caps_str="read/write")) for u in ro_users: user_info.append(UserInfo(email=u.email, caps_str="read-only")) rgs = db.list_replica_gateways_by_volume(vol.volume_id) ags = db.list_acquisition_gateways_by_volume(vol.volume_id) t = loader.get_template('viewvolume.html') c = RequestContext( request, { 'username': username, 'volume': vol, 'ags': ags, 'rgs': rgs, 'user_info': user_info }) return HttpResponse(t.render(c))
def get( self, volume_name ): # get the volume try: volume = storage.read_volume( volume_name ) except: response_end( self, 404, "No such volume", "text/plain") return # get the owner try: user = storage.read_user( volume.owner_id ) except: response_end( self, 404, "No such user", "text/plain") return if user == None: response_end( self, 404, "No such user", "text/plain") user_cert_dict = user.makeCert() user_cert_txt = json.dumps( user_cert_dict ) response_end( self, 200, user_cert_txt, "application/json" ) return
def get(self, volume_name): # get the volume try: volume = storage.read_volume(volume_name) except: response_end(self, 404, "No such volume", "text/plain") return # get the owner try: user = storage.read_user(volume.owner_id) except: response_end(self, 404, "No such user", "text/plain") return if user == None: response_end(self, 404, "No such user", "text/plain") user_cert_dict = user.makeCert() user_cert_txt = json.dumps(user_cert_dict) response_end(self, 200, user_cert_txt, "application/json") return
def changevolumepassword(request, volume_id): session = request.session username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) if request.method != "POST": return redirect('/syn/volume/' + str(volume_id) + '/settings') form = libforms.ChangePassword(request.POST) if not form.is_valid(): session['message'] = "You must fill out all password fields." return redirect('django_volume.views.volumesettings', volume_id) else: # Check password hash hash_check = Volume.generate_password_hash( form.cleaned_data['oldpassword'], vol.volume_secret_salt) if hash_check != vol.volume_secret_salted_hash: session['message'] = "Incorrect password." return redirect('django_volume.views.volumesettings', volume_id) elif form.cleaned_data['newpassword_1'] != form.cleaned_data[ 'newpassword_2']: session['message'] = "Your new passwords did not match each other." return redirect('django_volume.views.volumesettings', volume_id) # Ok change password kwargs = {} new_volume_secret_salt, new_volume_secret_salted_hash = Volume.generate_volume_secret( form.cleaned_data['newpassword_1']) kwargs['volume_secret_salted_hash'] = new_volume_secret_salted_hash kwargs['volume_secret_salt'] = new_volume_secret_salt db.update_volume(vol.volume_id, **kwargs) session['new_change'] = "We've changed your volume's password." session['next_url'] = '/syn/volume/' + str(vol.volume_id) session['next_message'] = "Click here to go back to your volume." return redirect('/syn/thanks')
def allgateways(request): ''' List all UG gateways view ''' session = request.session username = session['login_email'] try: qry = db.list_user_gateways() except: qry = [] gateways = [] for g in qry: gateways.append(g) vols = [] for g in gateways: add_vol = db.read_volume(g.volume_id) if add_vol: vols.append(add_vol) else: vols.append([]) owners = [] for v in vols: if v: volume_owner = v.owner_id attrs = {"SyndicateUser.owner_id ==": volume_owner} owners.append(db.get_user(attrs)) else: owners.append("") gateway_vols_owners = zip(gateways, vols, owners) t = loader.get_template('gateway_templates/allusergateways.html') c = RequestContext(request, { 'username': username, 'gateway_vols_owners': gateway_vols_owners }) return HttpResponse(t.render(c))
def test(path, args): username = args['username'] volume_name = args['volume_name'] user = storage.read_user(username) volume = storage.read_volume(volume_name) if user == None: raise Exception("No such user '%s'" % username) if volume == None: raise Exception("No such volume '%s'" % volume_name) # resolve a path reply = Resolve(user, volume, path) # parse the reply reply_struct = ms_pb2.ms_reply() try: reply_struct.ParseFromString(reply) except Exception, e: raise Exception("Invalid Protobuf string")
def test( path, args ): username = args['username'] volume_name = args['volume_name'] user = storage.read_user( username ) volume = storage.read_volume( volume_name ) if user == None: raise Exception("No such user '%s'" % username ) if volume == None: raise Exception("No such volume '%s'" % volume_name) # resolve a path reply = Resolve( user, volume, path ) # parse the reply reply_struct = ms_pb2.ms_reply() try: reply_struct.ParseFromString( reply ) except Exception, e: raise Exception("Invalid Protobuf string")
def response_load_volume(request_handler, volume_name_or_id): """ Load a volume from the data store, given either its name or ID. Automatically reply with an error message via the given request handler. """ volume_read_start = storagetypes.get_time() volume = storage.read_volume(volume_name_or_id) volume_read_time = storagetypes.get_time() - volume_read_start if volume == None: # no volume response_volume_error(request_handler, 404) return (None, 404, None) if not volume.active: # inactive volume response_volume_error(request_handler, 503) return (None, 503, None) return (volume, 200, volume_read_time)
def response_load_volume( request_handler, volume_name_or_id ): """ Load a volume from the data store, given either its name or ID. Automatically reply with an error message via the given request handler. """ volume_read_start = storagetypes.get_time() volume = storage.read_volume( volume_name_or_id ) volume_read_time = storagetypes.get_time() - volume_read_start if volume == None: # no volume response_volume_error( request_handler, 404 ) return (None, 404, None) if not volume.active: # inactive volume response_volume_error( request_handler, 503 ) return (None, 503, None) return (volume, 200, volume_read_time)
def mygateways(request): ''' Show all of logged in user's UG's ''' session = request.session username = session['login_email'] user = db.read_user(username) try: attrs = {"UserGateway.owner_id ==": user.owner_id} gateways = db.list_user_gateways(attrs) except: gateways = [] vols = [] for g in gateways: vols.append(db.read_volume(g.volume_id)) gateway_vols = zip(gateways, vols) t = loader.get_template('gateway_templates/myusergateways.html') c = RequestContext(request, { 'username': username, 'gateway_vols': gateway_vols }) return HttpResponse(t.render(c))
def viewgateway(request, g_id=0): ''' The view for viewing and changing any of the main settings on any AG. Passes forms for changing different settings, and the volumes attached to the gateway. ''' session = request.session username = session['login_email'] g_id = int(g_id) # Check for passed error messages or inital data from session-state. message = session.pop('message', "") ag_initial_data = session.get('ag_initial_data' + str(g_id), []) # Make sure this gateway actually exists. g = db.read_acquisition_gateway(g_id) if not g: logging.error("Error reading gateway %s : Does not exist." % (g_id)) message = "No acquisition gateway with the ID %s exists." % g_id t = loader.get_template("gateway_templates/viewgateway_failure.html") c = Context({'message': message, 'username': username}) return HttpResponse(t.render(c)) # Create forms for changing location, adding volumes, # changing password, getting password, and changing config location_form = gatewayforms.ModifyGatewayLocation(initial={ 'host': g.host, 'port': g.port }) add_form = gatewayforms.GatewayAddVolume() json_form = gatewayforms.ModifyGatewayConfig() password_form = libforms.Password() change_password_form = libforms.ChangePassword() # Get all attached volumes and their respective owners owners = [] vols = [] for v_id in g.volume_ids: vol = db.read_volume(v_id) if not vol: logging.error( "Volume ID in gateways volume_ids does not map to volume. Gateway: %s" % g_name) else: vols.append(vol) attrs = {"SyndicateUser.owner_id ==": vol.owner_id} owners.append(db.get_user(attrs)) vol_owners = zip(vols, owners) # Create formatted data based on vols for the formset, if not passed in state. if not ag_initial_data: for v in vols: ag_initial_data.append({'volume_name': v.name, 'remove': False}) session['ag_initial_data' + str(g_id)] = ag_initial_data VolumeFormSet = formset_factory(gatewayforms.GatewayRemoveVolume, extra=0) if ag_initial_data: formset = VolumeFormSet(initial=ag_initial_data) else: formset = None t = loader.get_template("gateway_templates/viewacquisitiongateway.html") c = RequestContext( request, { 'username': username, 'gateway': g, 'message': message, 'vol_owners': vol_owners, 'location_form': location_form, 'add_form': add_form, 'json_form': json_form, 'remove_forms': formset, 'password_form': password_form, 'change_password_form': change_password_form }) return HttpResponse(t.render(c))
def changepermissions(request, volume_id): ''' This view handles modification or removal of rights to the volume for users who already had some rights. ''' session = request.session username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) PermissionFormSet = formset_factory(forms.Permissions, extra=0) if request.method != "POST": return redirect('/syn/volume/' + str(vol.volume_id) + '/permissions') else: passwordform = libforms.Password(request.POST) formset = PermissionFormSet(request.POST) if not passwordform.is_valid(): session['message'] = "Password required." return redirect('django_volume.views.volumepermissions', vol.volume_id) else: # Check password hash if vol.volume_secret_salted_hash != Volume.generate_password_hash( passwordform.cleaned_data['password'], vol.volume_secret_salt): session['message'] = "Incorrect password" return redirect('django_volume.views.volumepermissions', vol.volume_id) if not formset.is_valid(): session['message'] = "Invalid field entries." return redirect('django_volume.views.volumepermissions', vol.volume_id) else: initial_and_forms = zip(session['initial_perms' + str(volume_id)], formset.forms) for data, form in initial_and_forms: check_username = data['user'] check_read = form.cleaned_data['read'] check_write = form.cleaned_data['write'] check_user = db.read_user(check_username) if check_write and not check_read: session[ 'message'] = "Write permissions require read permissions as well." return redirect('django_volume.views.volumepermissions', vol.volume_id) if data['write']: if check_write: continue elif check_read: # Give read, take away write new_volumes_r = check_user.volumes_r + [vol.volume_id] new_volumes_rw = check_user.volumes_rw.remove( vol.volume_id) if not new_volumes_rw: new_volumes_rw = [] fields = { 'volumes_r': new_volumes_r, 'volumes_rw': new_volumes_rw } db.update_user(check_username, **fields) else: # change to no permissions new_volumes_rw = check_user.volumes_rw.remove( vol.volume_id) if not new_volumes_rw: new_volumes_rw = [] fields = {'volumes_rw': new_volumes_rw} db.update_user(check_username, **fields) elif data['read']: if check_write: # Give write, take away read new_volumes_r = check_user.volumes_r.remove( vol.volume_id) new_volumes_rw = check_user.volumes_rw + [ vol.volume_id ] if not new_volumes_r: new_volumes_r = [] fields = { 'volumes_r': new_volumes_r, 'volumes_rw': new_volumes_rw } db.update_user(check_username, **fields) elif check_read: continue else: # change to no permissions new_volumes_r = check_user.volumes_r.remove( vol.volume_id) if not new_volumes_r: new_volumes_r = [] fields = {'volumes_r': new_volumes_r} db.update_user(check_username, **fields) # Clear out stale data. session.pop("initial_perms" + str(volume_id), None) session['new_change'] = "We've saved your new permissions." session['next_url'] = '/syn/volume/' + str( vol.volume_id) + '/permissions' session[ 'next_message'] = "Click here to see your volumes permissions." return redirect('/syn/thanks')
def deletevolume(request, volume_id): ''' View for deleting volumes. Since so many other entites have properties related to volume ID's, numerous db updates need to be checked. CQ, they are all grouped together into the transactional helper method multi_update(). ''' # Clear out volume_id in properties for users, UG's, AG's, and RG's. @transactional(xg=True) def multi_update(vol, users, usergateways, acquisitiongateways, replicagateways): v_id = vol.volume_id db.delete_volume(v_id) logging.info(users) for user in users: fields = {} if v_id in user.volumes_o: new_volumes_o = user.volumes_o new_volumes_o.remove(v_id) fields['volumes_o'] = new_volumes_o if v_id in user.volumes_rw: new_volumes_rw = user.volumes_rw new_volumes_rw.remove(v_id) fields['volumes_rw'] = new_volumes_rw if v_id in user.volumes_r: new_volumes_r = user.volumes_r new_volumes_r.remove(v_id) fields['volumes_r'] = new_volumes_r if fields: db.update_user(user.email, **fields) for ug in usergateways: fields = {} fields['volume_id'] = 0 db.update_user_gateway(ug.g_id, **fields) for ag in acquisitiongateways: logging.info(ag) fields = {} new_ids = ag.volume_ids.remove(v_id) if not new_ids: fields['volume_ids'] = [] else: fields['volume_ids'] = new_ids db.update_acquisition_gateway(ag.g_id, **fields) for rg in replicagateways: fields = {} new_ids = rg.volume_ids.remove(v_id) if not new_ids: fields['volume_ids'] = [] else: fields['volume_ids'] = new_ids db.update_replica_gateway(rg.g_id, **fields) # Clear initial data session variable to prevent stale tables in ag.views.viewgateway and rg.views.viewgateway session.pop("rg_initial_data" + str(v_id), None) session.pop("ag_initial_data" + str(v_id), None) # Clear initial data session variable to prevent stale data in volume settings, change rgs, and change ags. session.pop("volume_initial_ags" + str(v_id), None) session.pop("volume_initial_rgs" + str(v_id), None) session = request.session message = session.pop('message', "") username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) if request.method == "POST": form = forms.DeleteVolume(request.POST) if form.is_valid(): # Check password hash hash_check = Volume.generate_password_hash( form.cleaned_data['password'], vol.volume_secret_salt) if hash_check == vol.volume_secret_salted_hash: # Ok to delete attrs = {} users = db.list_users( {'SyndicateUser.volumes_rw ==': vol.volume_id}) users.extend( db.list_users( {'SyndicateUser.volumes_r ==': vol.volume_id})) ags = db.list_acquisition_gateways_by_volume(vol.volume_id) rgs = db.list_replica_gateways_by_volume(vol.volume_id) ugs = db.list_user_gateways_by_volume(vol.volume_id) try: multi_update(vol, users, ugs, ags, rgs) except Exception as e: logging.error("Unable to delete volume %s" % e) session['message'] = "Unable to delete volume." return redirect('django_volume.views.deletevolume', volume_id=vol.volume_id) session['new_change'] = "We've deleted your volume." session['next_url'] = '/syn/volume/myvolumes/' session[ 'next_message'] = "Click here to go back to your volumes." return redirect('/syn/thanks') else: session['message'] = "Invalid password" return redirect('django_volume.views.deletevolume', volume_id=vol.volume_id) else: session['message'] = "Please fill out all entries" return redirect('django_volume.views.deletevolume', vol.volume_id) else: form = forms.DeleteVolume() t = loader.get_template('deletevolume.html') c = RequestContext(request, { 'username': username, 'form': form, 'message': message, 'volume': vol }) return HttpResponse(t.render(c))
def changegateways_rg(request, volume_id): session = request.session username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) @transactional(xg=True) def update(v_id, gnames, vfields, gfields): db.update_volume(v_id, **vfields) for g, gfield in zip(gnames, gfields): db.update_replica_gateway(g, **gfield) session.pop('volume_initial_rgs' + str(volume_id), None) # make sure this variable exists, i.e. they came from the settings page. if not 'volume_initial_rgs' + str(volume_id) in session: return redirect("django_volume.views.volumesettings", volume_id) if request.POST: passwordform = libforms.Password(request.POST) if not passwordform.is_valid(): session['message'] = "Password required." return redirect('django_volume.views.volumesettings', volume_id) else: hash_check = Volume.generate_password_hash( passwordform.cleaned_data['password'], vol.volume_secret_salt) if hash_check != vol.volume_secret_salted_hash: session['message'] = "Incorrect password." return redirect('django_volume.views.volumesettings', volume_id) GatewayFormset = formset_factory(forms.Gateway, extra=0) formset = GatewayFormset(request.POST) formset.is_valid() remove_gateways = [] remove_gateway_names = [] remove_gateway_ids = [] for data, form in zip(session['volume_initial_rgs' + str(volume_id)], formset.forms): if form.cleaned_data['remove']: g = db.read_replica_gateway(data['g_name']) remove_gateways.append(g) remove_gateway_names.append(data['g_name']) remove_gateway_ids.append(g.rg_id) if not remove_gateways: return redirect('django_volume.views.volumesettings', volume_id) new_rgs = list(set(vol.rg_ids) - set(remove_gateway_ids)) vfields = {'rg_ids': new_rgs} gfields = [] for g in remove_gateways: new_vol_ids = g.volume_ids new_vol_ids.remove(vol.volume_id) gfields.append({"volume_ids": new_vol_ids}) try: update(vol.volume_id, remove_gateway_names, vfields, gfields) except Exception as e: session['message'] = "Unable to update volume or RG's." return redirect('django_volume.views.volumesettings', volume_id) session['new_change'] = "We've updated your volume." session['next_url'] = '/syn/volume/' + str(vol.volume_id) + '/settings' session['next_message'] = "Click here to go back to your volume." return redirect('/syn/thanks') else: return redirect('django_volume.views.volumesettings', volume_id=vol.volume_id)
def register_complete( gateway ): """ Complete a gateway's registration, generating a shared session password. Only call this method once the given gateway has authenticated! Generate and return a serialized ms_registration_metadata protobuf. """ # generate a session password # TODO: lock this operation, so we put the gateway and generate the password atomically? session_pass = gateway.regenerate_session_password() gateway_fut = gateway.put_async() futs = [gateway_fut] registration_metadata = ms_pb2.ms_registration_metadata() # registration information registration_metadata.session_password = session_pass registration_metadata.session_expires = gateway.session_expires gateway.protobuf_cert( registration_metadata.cert, need_closure=True ) # find all Volumes volume = storage.read_volume( gateway.volume_id ) if volume == None: return (404, None) root = storage.get_volume_root( volume ) if root == None: return (404, None) # add volume and contents protobuf_volume( registration_metadata.volume, volume, root ) # add sealed private key, if given earlier if gateway.encrypted_gateway_private_key != None: registration_metadata.encrypted_gateway_private_key = gateway.encrypted_gateway_private_key # add flow control data registration_metadata.resolve_page_size = RESOLVE_MAX_PAGE_SIZE registration_metadata.max_connections = MAX_NUM_CONNECTIONS registration_metadata.max_batch_request_size = MAX_BATCH_REQUEST_SIZE registration_metadata.max_batch_async_request_size = MAX_BATCH_ASYNC_REQUEST_SIZE registration_metadata.max_transfer_time = MAX_TRANSFER_TIME # sign and serialize! registration_metadata.signature = "" data = registration_metadata.SerializeToString() registration_metadata.signature = volume.sign_message( data ) data = registration_metadata.SerializeToString() # save the gateway storage.wait_futures( futs ) gateway.FlushCache( gateway.g_id ) volume.FlushCache( volume.volume_id ) return (200, data)
def volumesettings(request, volume_id): ''' old_data is for keeping state while changing the description when the password is wrong, no password is entered, etc. initial_data is for keeping state of the gateways when mistakes are made etc. ''' session = request.session username = session['login_email'] vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) message = session.pop('message', "") initial_data_ag = session.get('volume_initial_ags' + str(volume_id), None) initial_data_rg = session.get('volume_initial_rgs' + str(volume_id), None) old_data = session.get('old_data' + str(volume_id), None) if not initial_data_ag: initial_data_ag = [] ags = db.list_acquisition_gateways_by_volume(vol.volume_id) for g in ags: initial_data_ag.append({'g_name': g.ms_username, 'remove': False}) session['volume_initial_ags' + str(volume_id)] = initial_data_ag if not initial_data_rg: initial_data_rg = [] rgs = db.list_replica_gateways_by_volume(vol.volume_id) for g in rgs: initial_data_rg.append({'g_name': g.ms_username, 'remove': False}) session['volume_initial_rgs' + str(volume_id)] = initial_data_rg if old_data: desc_form = forms.ChangeVolumeD(initial={'description': old_data}) else: desc_form = forms.ChangeVolumeD( initial={'description': vol.description}) pass_form = libforms.ChangePassword() password = libforms.Password() GatewayFormset = formset_factory(forms.Gateway, extra=0) if initial_data_rg: rg_form = GatewayFormset(initial=initial_data_rg) else: rg_form = None if initial_data_ag: ag_form = GatewayFormset(initial=initial_data_ag) else: ag_form = None t = loader.get_template('volumesettings.html') c = RequestContext( request, { 'username': username, 'volume': vol, 'desc_form': desc_form, 'pass_form': pass_form, 'password': password, 'message': message, 'ag_form': ag_form, 'rg_form': rg_form, }) return HttpResponse(t.render(c))
def addpermissions(request, volume_id): ''' This handler allows adding users to volumes so they can have either read access or read and write access. ''' session = request.session username = session['login_email'] if request.method != "POST": return redirect('syn/volume/' + str(vol.volume_id) + '/permissions') else: vol = db.read_volume(volume_id) if not vol: return redirect('django_volume.views.viewvolume', volume_id) addform = forms.AddPermissions(request.POST) passwordform = libforms.Password(request.POST) if not passwordform.is_valid(): session['message'] = "Password required." return redirect('django_volume.views.volumepermissions', vol.volume_id) else: # Check password hash if vol.volume_secret_salted_hash != Volume.generate_password_hash( passwordform.cleaned_data['password'], vol.volume_secret_salt): session['message'] = "Incorrect password" return redirect('django_volume.views.volumepermissions', vol.volume_id) if not addform.is_valid(): session[ 'message'] = "Incorrect entry fields: likely invalid email address." return redirect('django_volume.views.volumepermissions', vol.volume_id) # Ok to update else: new_username = addform.cleaned_data['user'] read = addform.cleaned_data['read'] write = addform.cleaned_data['write'] for data in session['initial_perms' + str(volume_id)]: if data['user'] == new_username: session['message'] = "User already has rights for volume." return redirect('django_volume.views.volumepermissions', vol.volume_id) new_user = db.read_user(new_username) if not new_user: session[ 'message'] = "No Syndicate user with the email {} exists.".format( new_username) return redirect('django_volume.views.volumepermissions', vol.volume_id) if vol.owner_id == new_user.owner_id: session['message'] = "You already own this volume." return redirect('django_volume.views.volumepermissions', vol.volume_id) if write: if read: new_volumes_rw = new_user.volumes_rw + [vol.volume_id] fields = {'volumes_rw': new_volumes_rw} db.update_user(new_username, **fields) else: session[ 'message'] = "Write permissions require read permissions as well." return redirect('django_volume.views.volumepermissions', vol.volume_id) elif read: new_volumes_r = new_user.volumes_r + [vol.volume_id] fields = {'volumes_r': new_volumes_r} db.update_user(new_username, **fields) # Clear out old permissions data. session.pop('initial_perms' + str(volume_id), None) session['new_change'] = "We've saved a new user to your volume." session['next_url'] = '/syn/volume/' + str( vol.volume_id) + '/permissions' session[ 'next_message'] = "Click here to see your volumes permissions." return redirect('/syn/thanks')
def register_complete(gateway): """ Complete a gateway's registration, generating a shared session password. Only call this method once the given gateway has authenticated! Generate and return a serialized ms_registration_metadata protobuf. """ # generate a session password # TODO: lock this operation, so we put the gateway and generate the password atomically? session_pass = gateway.regenerate_session_password() gateway_fut = gateway.put_async() futs = [gateway_fut] registration_metadata = ms_pb2.ms_registration_metadata() # registration information registration_metadata.session_password = session_pass registration_metadata.session_expires = gateway.session_expires gateway.protobuf_cert(registration_metadata.cert, need_closure=True) # find all Volumes volume = storage.read_volume(gateway.volume_id) if volume == None: logging.error("No such volume %s" % gateway.volume_id) return (404, None) root = storage.get_volume_root(volume) if root is None: logging.error("BUG: no root for volume %s" % volume.name) return (500, None) # add volume and contents protobuf_volume(registration_metadata.volume, volume, root) # add sealed private key, if given earlier if gateway.encrypted_gateway_private_key != None: registration_metadata.encrypted_gateway_private_key = gateway.encrypted_gateway_private_key # add flow control data registration_metadata.resolve_page_size = RESOLVE_MAX_PAGE_SIZE registration_metadata.max_connections = MAX_NUM_CONNECTIONS registration_metadata.max_batch_request_size = MAX_BATCH_REQUEST_SIZE registration_metadata.max_batch_async_request_size = MAX_BATCH_ASYNC_REQUEST_SIZE registration_metadata.max_transfer_time = MAX_TRANSFER_TIME # sign and serialize! registration_metadata.signature = "" data = registration_metadata.SerializeToString() registration_metadata.signature = volume.sign_message(data) data = registration_metadata.SerializeToString() # save the gateway storage.wait_futures(futs) gateway.FlushCache(gateway.g_id) volume.FlushCache(volume.volume_id) return (200, data)
def viewgateway(request, g_id=0): ''' The view for viewing and changing any of the main settings on any RG. Passes forms for changing different settings, and the volumes attached to the gateway. ''' session = request.session username = session['login_email'] g_id = int(g_id) # Check for any passed error messages and initial_data from state to save db calls. message = session.pop('message', "") rg_initial_data = session.get('rg_initial_data' + str(g_id), []) # Make sure gateway exists. g = db.read_replica_gateway(g_id) if not g: logging.error("Error reading gateway %d : Exception: %s" % (g_id, e)) message = "No replica gateway with the ID %d exists." % g_id t = loader.get_template("gateway_templates/viewgateway_failure.html") c = Context({'message':message, 'username':username}) return HttpResponse(t.render(c)) # Create forms for changing location, adding volumes, # changing password, getting password, and changing config location_form = gatewayforms.ModifyGatewayLocation(initial={'host':g.host, 'port':g.port}) add_form = gatewayforms.GatewayAddVolume() json_form = gatewayforms.ModifyGatewayConfig() password_form = libforms.Password() change_password_form = libforms.ChangePassword() # Get all attached volumes and their respective owners owners = [] vols = [] for v_id in g.volume_ids: vol = db.read_volume(v_id) if not vol: logging.error("Volume ID in gateways volume_ids does not map to volume. Gateway: %s" % g_name) else: vols.append(vol) attrs = {"SyndicateUser.owner_id ==": vol.owner_id} owners.append(db.get_user(attrs)) vol_owners = zip(vols, owners) # Create formatted data based on vols for the formset, if not passed in state. if not rg_initial_data: for v in vols: rg_initial_data.append({'volume_name':v.name, 'remove':False}) session['rg_initial_data' + str(g_id)] = rg_initial_data VolumeFormSet = formset_factory(gatewayforms.GatewayRemoveVolume, extra=0) if rg_initial_data: formset = VolumeFormSet(initial=rg_initial_data) else: formset = [] t = loader.get_template("gateway_templates/viewreplicagateway.html") c = RequestContext(request, {'username':username, 'gateway':g, 'message':message, 'vol_owners':vol_owners, 'location_form':location_form, 'add_form':add_form, 'json_form':json_form, 'remove_forms':formset, 'password_form':password_form, 'change_password_form':change_password_form}) return HttpResponse(t.render(c))