def route_create(): """ Add a vendor [ADMIN ONLY] """ # only accept form data if request.method != 'POST': return redirect(url_for('vendors.route_list_admin')) if not 'group_id' in request.form: return _error_internal('Unable to add vendor as no data') if db.session.query(Vendor).filter(Vendor.group_id == request.form['group_id']).first(): flash('Failed to add vendor: Group ID already exists', 'warning') return redirect(url_for('vendors.route_list_admin'), 302) if len(request.form['group_id']) > 80: flash('Failed to add vendor: Group ID is too long', 'warning') return redirect(url_for('vendors.route_list_admin'), 302) r = Remote(name='embargo-%s' % request.form['group_id']) db.session.add(r) db.session.commit() v = Vendor(group_id=request.form['group_id'], remote_id=r.remote_id) db.session.add(v) db.session.commit() flash('Added vendor %s' % request.form['group_id'], 'info') # asynchronously rebuilt _async_regenerate_remote.apply_async(args=(r.remote_id,), queue='metadata') return redirect(url_for('vendors.route_show', vendor_id=v.vendor_id), 302)
def _demote_back_to_testing(fw): # from the server admin user = db.session.query(User).filter(User.username == '*****@*****.**').first() if not user: return # send email to uploading user if fw.user.get_action('notify-demote-failures'): send_email("[LVFS] Firmware has been demoted", fw.user.email_address, render_template('email-firmware-demote.txt', user=fw.user, fw=fw)) fw.mark_dirty() remote = db.session.query(Remote).filter(Remote.name == 'testing').first() remote.is_dirty = True # asynchronously sign straight away, even public remotes for r in set([remote, fw.remote]): r.is_dirty = True _async_regenerate_remote.apply_async(args=(r.remote_id,), queue='metadata', countdown=1) fw.remote_id = remote.remote_id fw.events.append(FirmwareEvent(remote_id=fw.remote_id, user_id=user.user_id)) db.session.commit() _event_log('Demoted firmware {} as reported success {}%'.format(fw.firmware_id, fw.success))
def route_limit_delete(firmware_limit_id): # get details about the firmware fl = db.session.query(FirmwareLimit).\ filter(FirmwareLimit.firmware_limit_id == firmware_limit_id).first() if not fl: flash('No firmware limit matched!', 'danger') return redirect(url_for('firmware.route_firmware')) # security check if not fl.fw.check_acl('delete-limit'): flash('Permission denied: Insufficient permissions to delete limits', 'danger') return redirect(url_for('firmware.route_firmware')) firmware_id = fl.firmware_id fl.fw.mark_dirty() db.session.delete(fl) db.session.commit() flash('Deleted limit', 'info') # asynchronously sign _async_regenerate_remote.apply_async(args=(fl.fw.remote.remote_id, ), queue='metadata') return redirect(url_for('firmware.route_limits', firmware_id=firmware_id))
def route_limit_create(): # get details about the firmware fw = db.session.query(Firmware).\ filter(Firmware.firmware_id == request.form['firmware_id']).first() if not fw: flash('No firmware matched!', 'danger') return redirect(url_for('firmware.route_firmware')) # security check if not fw.check_acl('@modify-limit'): flash('Permission denied: Unable to add restriction', 'danger') return redirect(url_for('firmware.route_show', firmware_id=fw.firmware_id)) # ensure has enough data for key in ['value', 'firmware_id']: if key not in request.form: return _error_internal('No %s form data found!', key) # add restriction fl = FirmwareLimit(firmware_id=request.form['firmware_id'], value=request.form['value'], user_agent_glob=request.form['user_agent_glob'], response=request.form['response']) db.session.add(fl) db.session.commit() fl.fw.mark_dirty() db.session.commit() flash('Added limit', 'info') # asynchronously sign _async_regenerate_remote.apply_async(args=(fl.fw.remote.remote_id,), queue='metadata') return redirect(url_for('firmware.route_limits', firmware_id=fl.firmware_id))
def route_retoken(vendor_id): """ Removes a vendor [ADMIN ONLY] """ vendor = db.session.query(Vendor).filter( Vendor.vendor_id == vendor_id).first() if not vendor: flash('Failed to delete vendor: No a vendor with that group ID', 'warning') return redirect(url_for('vendors.route_list_admin'), 302) # delete files with the old access token fns = glob( os.path.join(app.config['DOWNLOAD_DIR'], 'firmware-*-{}.*'.format(vendor.remote.access_token))) for fn in fns: os.remove(fn) # a random string vendor.remote.access_token = secrets.token_hex(nbytes=32) vendor.remote.is_dirty = True db.session.commit() # asynchronously rebuilt _async_regenerate_remote.apply_async(args=(vendor.remote.remote_id, ), queue='metadata') flash('Regenerated vendor access token', 'info') return redirect(url_for('vendors.route_list_admin'), 302)
def route_affiliation_change(firmware_id): """ Changes the assigned vendor ID for the firmware """ # change the vendor if 'vendor_id' not in request.form: return _error_internal('No vendor ID specified') # find firmware fw = db.session.query(Firmware).filter( Firmware.firmware_id == firmware_id).first() if not fw: flash('No firmware matched!', 'danger') return redirect(url_for('firmware.route_firmware')) # security check if not fw.check_acl('@modify-affiliation'): flash( 'Permission denied: Insufficient permissions to change affiliation', 'danger') return redirect(url_for('firmware.route_show', firmware_id=firmware_id)) vendor_id = int(request.form['vendor_id']) if vendor_id == fw.vendor_id: flash('No affiliation change required', 'info') return redirect( url_for('firmware.route_affiliation', firmware_id=fw.firmware_id)) if not g.user.check_acl('@admin') and \ not g.user.vendor.is_affiliate_for(vendor_id) and \ vendor_id != g.user.vendor_id: flash( 'Insufficient permissions to change affiliation to {}'.format( vendor_id), 'danger') return redirect(url_for('firmware.route_show', firmware_id=firmware_id)) old_vendor = fw.vendor fw.vendor_id = vendor_id db.session.commit() # do we need to regenerate remotes? if fw.remote.name.startswith('embargo'): fw.vendor.remote.is_dirty = True fw.user.vendor.remote.is_dirty = True old_vendor.remote.is_dirty = True fw.remote_id = fw.vendor.remote.remote_id fw.events.append( FirmwareEvent(remote_id=fw.remote_id, user_id=g.user.user_id)) fw.mark_dirty() db.session.commit() flash('Changed firmware vendor', 'info') # asynchronously sign _async_regenerate_remote.apply_async(args=(fw.remote.remote_id, ), queue='metadata') return redirect(url_for('firmware.route_show', firmware_id=fw.firmware_id))
def route_restriction_create(vendor_id): """ Allows changing a vendor [ADMIN ONLY] """ # check exists vendor = db.session.query(Vendor).filter(Vendor.vendor_id == vendor_id).first() if not vendor: flash('Failed to get vendor details: No a vendor with that group ID', 'warning') return redirect(url_for('vendors.route_list_admin'), 302) if not 'value' in request.form: return _error_internal('No value') vendor.restrictions.append(Restriction(value=request.form['value'])) db.session.commit() flash('Added restriction', 'info') # asynchronously rebuilt _async_regenerate_remote.apply_async(args=(vendor.remote.remote_id,), queue='metadata') return redirect(url_for('vendors.route_restrictions', vendor_id=vendor_id), 302)
def route_restriction_delete(vendor_id, restriction_id): """ Allows changing a vendor [ADMIN ONLY] """ # check exists vendor = db.session.query(Vendor).filter(Vendor.vendor_id == vendor_id).first() if not vendor: flash('Failed to get vendor details: No a vendor with that group ID', 'warning') return redirect(url_for('vendors.route_list_admin'), 302) for res in vendor.restrictions: if res.restriction_id == restriction_id: db.session.delete(res) db.session.commit() break flash('Deleted restriction', 'info') # asynchronously rebuilt _async_regenerate_remote.apply_async(args=(vendor.remote.remote_id,), queue='metadata') return redirect(url_for('vendors.route_restrictions', vendor_id=vendor_id), 302)
def route_create(): """ Add a vendor [ADMIN ONLY] """ # only accept form data if request.method != 'POST': return redirect(url_for('vendors.route_list_admin')) if not 'group_id' in request.form: return _error_internal('Unable to add vendor as no data') if db.session.query(Vendor).filter( Vendor.group_id == request.form['group_id']).first(): flash('Failed to add vendor: Group ID already exists', 'warning') return redirect(url_for('vendors.route_list_admin'), 302) if len(request.form['group_id']) > 80: flash('Failed to add vendor: Group ID is too long', 'warning') return redirect(url_for('vendors.route_list_admin'), 302) # use a random access token, unless running in debug mode if app.config.get('DEBUG', None): access_token = request.form['group_id'].replace('-', '_') else: access_token = secrets.token_hex(nbytes=32) r = Remote(name='embargo-%s' % request.form['group_id'], access_token=access_token, is_dirty=True) db.session.add(r) db.session.commit() v = Vendor(group_id=request.form['group_id'], remote_id=r.remote_id) db.session.add(v) db.session.commit() flash('Added vendor %s' % request.form['group_id'], 'info') # asynchronously rebuilt _async_regenerate_remote.apply_async(args=(r.remote_id, ), queue='metadata') return redirect(url_for('vendors.route_show', vendor_id=v.vendor_id), 302)
def _firmware_delete(fw): # find private remote remote = db.session.query(Remote).filter(Remote.name == 'deleted').first() if not remote: _event_log('No deleted remote') return # move file so it's no longer downloadable path = os.path.join(app.config['DOWNLOAD_DIR'], fw.filename) if os.path.exists(path): path_new = os.path.join(app.config['RESTORE_DIR'], fw.filename) shutil.move(path, path_new) # generate next cron run fw.mark_dirty() # asynchronously sign _async_regenerate_remote.apply_async(args=(fw.remote.remote_id,), queue='metadata') # mark as invalid fw.remote_id = remote.remote_id fw.events.append(FirmwareEvent(remote_id=fw.remote_id, user_id=g.user.user_id))
def route_promote(firmware_id, target): """ Promote or demote a firmware file from one target to another, for example from testing to stable, or stable to testing. """ # check valid if target not in ['stable', 'testing', 'private', 'embargo']: return _error_internal("Target %s invalid" % target) # check firmware exists in database fw = db.session.query(Firmware).filter( Firmware.firmware_id == firmware_id).first() if not fw: flash('No firmware {} exists'.format(firmware_id), 'danger') return redirect(url_for('firmware.route_firmware')) # security check if not fw.check_acl('@promote-' + target): flash('Permission denied: No QA access to {}'.format(firmware_id), 'danger') return redirect(url_for('firmware.route_show', firmware_id=firmware_id)) # vendor has to fix the problems first if target in ['stable', 'testing'] and fw.problems: probs = [] for problem in fw.problems: if problem.kind not in probs: probs.append(problem.kind) flash( 'Firmware has problems that must be fixed first: %s' % ','.join(probs), 'warning') return redirect( url_for('firmware.route_problems', firmware_id=firmware_id)) # set new remote if target == 'embargo': remote = fw.vendor.remote else: remote = db.session.query(Remote).filter(Remote.name == target).first() if not remote: return _error_internal('No remote for target %s' % target) # same as before if fw.remote.remote_id == remote.remote_id: flash('Cannot move firmware: Firmware already in that target', 'info') return redirect( url_for('firmware.route_target', firmware_id=firmware_id)) # invalidate both the remote it "came from", the one it's "going to" and # also the remote of the vendor that uploaded it remote.is_dirty = True fw.remote.is_dirty = True fw.vendor_odm.remote.is_dirty = True # invalidate the firmware as we're waiting for the metadata generation fw.mark_dirty() db.session.commit() # asynchronously sign for r in set([remote, fw.remote, fw.vendor_odm.remote]): r.is_dirty = True _async_regenerate_remote.apply_async(args=(r.remote_id, ), queue='metadata', countdown=1) # some tests only run when the firmware is in stable ploader.ensure_test_for_fw(fw) # sync everything we added db.session.commit() # asynchronously run _async_test_run_for_firmware.apply_async(args=(fw.firmware_id, )) # also dirty any ODM remote if uploading on behalf of an OEM if target == 'embargo' and fw.vendor != fw.user.vendor: fw.user.vendor.remote.is_dirty = True # all okay fw.remote_id = remote.remote_id fw.events.append( FirmwareEvent(remote_id=fw.remote_id, user_id=g.user.user_id)) db.session.commit() # send email for u in fw.get_possible_users_to_email: if u == g.user: continue if u.get_action('notify-promote'): send_email( "[LVFS] Firmware has been promoted", u.email_address, render_template('email-firmware-promoted.txt', user=g.user, fw=fw)) flash('Moved firmware', 'info') return redirect(url_for('firmware.route_target', firmware_id=firmware_id))