def del_user(user_id): """ Deletes all sites owned by the given user. User ID must match the supplied token. This also clears the cred cache of any entries for the user. """ log = current_app.log db = request.db Site = db.tables.Site Cred = db.tables.Cred auth_user_id = SiteService.get_current_uid() # Check the user is deleting their own items if auth_user_id != user_id: log.warn("User %u tried to delete sites belonging to user %u.", auth_user_id, user_id) abort(404) sites = Site.query.filter_by(site_owner=auth_user_id).all() num_sites = len(sites) creds = Cred.query.filter_by(cred_owner=auth_user_id).all() num_creds = len(creds) with managed_session(request, message="Database error while deleting sites", http_error_code=500) as session: for cred in creds: session.delete(cred) for site in sites: session.delete(site) log.info("Deleted all sites for user %u (%u sites, %u creds deleted).", auth_user_id, num_sites, num_creds) return ""
def remove_all(ids): """Remove jobs from database.""" if isinstance(ids, int): ids = (ids, ) with managed_session(current_app, message="Error removing all jobs.", http_error_code=500) as session: session.query.filter(Job.id.in_(set(ids))).delete()
def update(self): """Update session with current element.""" message = "Error updating job element" try: with managed_session(current_app, message=message) as session: session.merge(self) except IntegrityError as err: if 'constraint failed' in str(err): abort(400, description= "Max tries reached, no more attempts allowed") abort(500, description=message) except Exception: abort(500, description=message)
def logoff_session(site_id): """ Delete a session for the current user at a given site. """ log = current_app.log db = request.db Cred = db.tables.Cred user_id = SiteService.get_current_uid() cred = Cred.query.filter_by(cred_owner=user_id, site_id=site_id).first() if cred: with managed_session(request, message="Database error while deleting creds", http_error_code=500) as session: session.delete(cred) log.info("Deleted session for user %u at site %u.", user_id, site_id) return ""
def del_site(site_id): """ Delete a site (including all endpoints). """ log = current_app.log db = request.db Site = db.tables.Site user_id = SiteService.get_current_uid() # By adding the owner to the query, we prevent a user # deleting anything but their own sites site = Site.query.filter_by(site_id=site_id, site_owner=user_id).first_or_404() with managed_session(request, message="Database error while deleting site", http_error_code=500) as session: session.delete(site) log.info("Deleted site ID %u.", site_id) return ""
def delete(self, db): """ Delete this object from DB. """ with managed_session(db) as m_session: m_session.delete(self)
def save(self, db): """ Save this object to the DB. """ with managed_session(db) as m_session: m_session.add(self)
def update(self): """Update session with current job.""" with managed_session(current_app, message="Error updating job", http_error_code=500) as session: session.merge(self)
def remove(self): """Remove job from session.""" with managed_session(current_app, message="Error removing job", http_error_code=500) as session: session.delete(self)
def add(self): """Add job to session.""" with managed_session(current_app, message="Error adding job", http_error_code=500) as session: session.add(self)
def logon_session(site_id): """ Create a session for the current user at a given site. """ log = current_app.log db = request.db Site = db.tables.Site Cred = db.tables.Cred user_id = SiteService.get_current_uid() # Decode POST data if not request.data: log.warn("Missing post data for logon.") return "Missing POST data", 400 cred_data = json.loads(request.data) username = cred_data.get("username", None) password = cred_data.get("password", None) lifetime = cred_data.get("lifetime", None) vo_name = cred_data.get("vo", None) if not username or not password or not lifetime: log.warn("Missing post field in logon.") return "Required field missing", 400 # Check user can see the site site = Site.query.filter_by(site_id=site_id).first_or_404() is_owner = (site.site_owner == user_id) if not (is_owner or site.public): log.warn("User %u tried to login to site %u (access denied).", user_id, site_id) abort(404) # This user can't see the requested site # Check the site auth configuration if site.auth_type == 1: # VOMS login if not vo_name: log.warn( "User %u did not specify required VO name for site %u", user_id, site_id) return "VO required", 400 if not vo_name in current_app.vo_list: log.warn( "User %u requested unknown VO '%s' for login to site %u.", user_id, vo_name, site_id) return "Unknown VO name", 400 # Process the different possible CA info combinations ca_info = None if site.user_ca_cert or site.service_ca_cert: ca_info = [] if site.user_ca_cert: ca_info.append(site.user_ca_cert) if site.service_ca_cert: ca_info.append(site.service_ca_cert) elif current_app.cadir: ca_info = current_app.cadir # Actually run the myproxy command try: proxy = MyProxyUtils.logon(site.auth_uri, username, password, ca_info, vo_name, lifetime, myproxy_bin=current_app.myproxy_bin, vomses=current_app.vomses, log=log) except Exception as err: log.error("Failed to login user: %s", str(err)) return "Login failed: %s" % str(err), 400 # Clear the TZInfo as it should be UTC anyway and the database # uses naive date-time formats. cred_expiry = X509Utils.get_cert_expiry(proxy).replace(tzinfo=None) new_cred = Cred(cred_owner=user_id, site_id=site_id, cred_username=username, cred_expiry=cred_expiry, cred_value=proxy) with managed_session(request, message="Database error while storing proxy", http_error_code=500) as session: session.merge(new_cred) return ""
def add_site(): """ Add a site in the database. """ log = current_app.log db = request.db Site = db.tables.Site Endpoint = db.tables.Endpoint site_data = {} endpoints = [] try: if not request.data: return "Missing POST data", 400 raw_site_data = json.loads(request.data) # Required fields for key in ('site_name', 'site_desc', 'auth_type', 'auth_uri', 'public', 'def_path'): raw_val = raw_site_data.get(key, None) if raw_val is None: return "Required field %s missing" % key, 400 site_data[key] = raw_val # Optional fields for key in ('user_ca_cert', 'service_ca_cert'): raw_val = raw_site_data.get(key, None) if raw_val: site_data[key] = raw_val # Check the auth types if site_data["auth_type"] not in (0, 1): log.warn("Unable to add site: Invalid auth_type (%s)", site_data["auth_type"]) return "Invalid auth_type.", 400 if not SiteService.check_uri(site_data["auth_uri"]): log.warn("Unable to add site: Invalid auth_uri (%s)", site_data["auth_uri"]) return "Invalid auth_uri.", 400 # Extra fields site_data["site_owner"] = SiteService.get_current_uid() # Endpoints raw_eps = raw_site_data.get('endpoints', []) for raw_ep in raw_eps: if not SiteService.check_uri(raw_ep): log.warn("Unable to add site: Bad endpoint (%s)", raw_ep) return "Invalid endpoint format.", 400 endpoints.extend(raw_eps) except Exception as err: log.warn("POST data error from client: %s", str(err)) return "Malformed POST data", 400 # Now actually try to create the site new_site = Site(**site_data) try: with managed_session(request) as session: session.add(new_site) session.flush() # Ensure new_site gets an ID site_id = new_site.site_id # Also create the endpoints for ep_uri in endpoints: session.add(Endpoint(site_id=site_id, ep_uri=ep_uri)) except IntegrityError: # site_name is probably not unique log.info("Failed to add new non-unique site %s.", new_site.site_name) return "site_name is not unique", 409 except Exception as err: # Some kind of other database error? log.error("Failed to add new site %s (%s).", site_data['site_name'], str(err)) return "Failed to add site to DB", 500 log.info("Added site %s with %u endpoints (ID %u).", new_site.site_name, len(endpoints), new_site.site_id) return jsonify(new_site.site_id)
def run_db_session(self, test_request, **kwargs): with managed_session(test_request, **kwargs) as db_session: self.assertEquals(db_session, test_request.db.session)