def get(self, email): # Get values server = request.headers.get('server') # Validate required fields validation = Validation() validation.add_required_field('email', email) validation.add_required_field('server', server) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) success, code, message = user_service.send_email_confirm( user.id, server) db.session.commit() if success: logging.info('LocalUser-controller: RequestConfirm: success: %s', user.id) return {'success': True} else: if code == 10: return Failures.rate_exceeded() return {'success': False, 'message': message, 'code': 520}
def loadFromQuery(lat, lng, radiusKM = 5): if radiusKM > MAX_SAFE_QUERY_DIST_KM: raise RuntimeError("Queries with radii greater than " + str(MAX_SAFE_QUERY_DIST_KM) + " may cause data loss due to webserver limitations") outProjectionCode = 4326 lineURL = "https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer/2/query?geometry=" + str(lng) + "," + str(lat) + "&outFields=GNIS_NAME%2C+LENGTHKM%2C+STREAMLEVE%2C+FCODE%2C+OBJECTID%2C+ARBOLATESU&geometryType=esriGeometryPoint&inSR=4326&outSR=" + str(outProjectionCode) + "&distance=" + str(radiusKM*1000) + "&units=esriSRUnit_Meter&returnGeometry=true&f=geojson" req = queryWithAttempts(lineURL, QUERY_ATTEMPTS, queryName="lineData", timeout = TIMEOUT) if Failures.isFailureCode(req): if __debug__: print("could not read query") return req try: lineLayer = json.loads(req.text)["features"] except: if __debug__: print("could not read query") return Failures.QUERY_PARSE_FAILURE_CODE if len(lineLayer) == 0: return Failures.EMPTY_QUERY_CODE sites = loadSitesFromQuery(lat, lng, radiusKM) if Failures.isFailureCode(sites): return sites dataBoundary = DataBoundary(point=(lng, lat), radius = Helpers.approxKmToDegrees(radiusKM - DATA_PADDING)) data = BaseData(lineLayer = lineLayer, siteLayer = sites, dataBoundary = dataBoundary) return data
def post(self): # Get values server = request.headers.get('server') email = request.form.get('email') source = request.form.get('source') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('email', email) validation.add_required_field('source', source) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) # Validate auth source if user.auth_source != source: return Failures.wrong_auth_source(user.auth_source) logging.info('OAuth-controller: Validate: success: %s', user.id) return {'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name }}
def get(self, id_user): # Parse numbers try: id_user = int(id_user) except: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) logging.info('User-controller: getUserById: success: %s (%s)', id_user, user.screen_name) return { 'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source } }
def get(id_user): # Parse numbers try: id_user = int(id_user) except ValueError: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) logging.info('User-controller: getUserById: success: %s (%s)', id_user, user.screen_name) return {'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source }}
def post(self): # Get values server = request.headers.get('server') id_user = request.form.get('idUser') browser = request.form.get('browser') ip_address = request.form.get('ipAddress') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('idUser', id_user) validation.add_required_field('browser', browser) validation.add_required_field('ipAddress', ip_address) if not validation.is_valid(): return validation.get_validation_response() # Parse numbers try: id_user = int(id_user) except: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) if not user.confirmed: return Failures.email_not_confirmed() if user.blocked: return Failures.user_blocked() # Delete expired tokens AuthenticationToken.query.filter( AuthenticationToken.validity < datetime.datetime.now()).delete() db.session.flush() # Generate token token = str(uuid.uuid1()) # Save token and browser information authentication_token = AuthenticationToken() authentication_token.id_user = id_user authentication_token.browser = browser authentication_token.server = server authentication_token.ip_address = ip_address authentication_token.validity = datetime.datetime.now( ) + datetime.timedelta(minutes=120) authentication_token.token = token db.session.add(authentication_token) db.session.commit() logging.info( 'AuthToken-controller: Request auth token: success: %s -> %s*****', user.id, token[0:6]) return {'success': True, 'token': token}
def post(self, email): # Get values token = request.form.get('token') password = request.form.get('password') password_confirm = request.form.get('password-confirm') # Validate required fields validation = Validation() validation.add_required_field('email', email) validation.add_required_field('token', token) validation.add_required_field('password', password) validation.add_required_field('password-confirm', password_confirm) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) # Validate password strength and confirm if password != password_confirm: return Failures.passwords_do_not_match() if not user_service.check_password_complexity(password): return Failures.password_complexity() # Delete expired tokens ResetToken.query.filter( ResetToken.validity < datetime.datetime.now()).delete() db.session.flush() reset_token = ResetToken.query.filter_by(token=token).first() if reset_token is None: # Unkown token return {'success': False, 'code': 510} if reset_token.id_user != user.id: # Token is not for this user return {'success': False, 'code': 510} salt, password_hash = user_service.get_password_hash(password) user.password = password_hash user.salt = salt db.session.delete(reset_token) db.session.commit() logging.info('LocalUser-controller: DoPasswordReset: success: %s', user.id) return {'success': True}
def post(self, email): # Get values token = request.form.get('token') password = request.form.get('password') password_confirm = request.form.get('password-confirm') # Validate required fields validation = Validation() validation.add_required_field('email', email) validation.add_required_field('token', token) validation.add_required_field('password', password) validation.add_required_field('password-confirm', password_confirm) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) # Validate password strength and confirm if password != password_confirm: return Failures.passwords_do_not_match() if not user_service.check_password_complexity(password): return Failures.password_complexity() # Delete expired tokens ResetToken.query.filter(ResetToken.validity < datetime.datetime.now()).delete() db.session.flush() reset_token = ResetToken.query.filter_by(token=token).first() if reset_token is None: # Unkown token return {'success': False, 'code': 510} if reset_token.id_user != user.id: # Token is not for this user return {'success': False, 'code': 510} salt, password_hash = user_service.get_password_hash(password) user.password = password_hash user.salt = salt db.session.delete(reset_token) db.session.commit() logging.info('LocalUser-controller: DoPasswordReset: success: %s', user.id) return {'success': True}
def post(id_user): screen_name = request.form.get('screenname') # Validate required fields validation = Validation() validation.add_required_field('id-user', id_user) validation.add_required_field('screenname', screen_name) if not validation.is_valid(): return validation.get_validation_response() # Validate the id parameter as an integer try: id_user = int(id_user) except ValueError: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) # Attempt to retrieve the proposed screen name to ensure that it is available user_by_email = user_service.get_user_by_screen_name(screen_name) if user_by_email is not None: if user.id != user_by_email.id: return Failures.screen_name_already_in_use(screen_name) # The screen name is available, Assign it to the user profile user.screen_name = screen_name db.session.commit() logging.info('User-controller: doInfoChange: success: %s (%s)', id_user, user.screen_name) return { 'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source } }
def post(self): # Get values email = request.form.get('email') # User account email address token = request.form.get( 'token') # Token assigned to account during account registration # Validate required fields validation = Validation() validation.add_required_field('email', email) validation.add_required_field('token', token) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) # Delete expired tokens ConfirmToken.query.filter( ConfirmToken.validity < datetime.datetime.now()).delete() db.session.flush() confirm_token = ConfirmToken.query.filter_by(token=token).first() if confirm_token is None: # Unknown token return {'success': False, 'code': 510} if confirm_token.id_user != user.id: # Token is not for this user return {'success': False, 'code': 510} # Set user account status to 'Confirmed' user.confirmed = True # Delete the account confirmation token; it is no longer required db.session.delete(confirm_token) # Commit the user account changes db.session.commit() logging.info('LocalUser-controller: DoConfirm: success: %s', user.id) return {'success': True}
def get(email): # TODO: Validate the format of the email address before attempting database IO # Validate user exists, is validated and is not blocked user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) logging.info('User-controller: getUserByEmail: success: %s (%s)', email, user.screen_name) return { 'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source } }
def getNearestPlace (lat, lng, timeout = 5): locationsUrl = "https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer/18/query?geometry=" + str(lng) +"," + str(lat) + "&geometryType=esriGeometryPoint&inSR=4326&outSR=4326&distance=7000&units=esriSRUnit_Meter&outFields=*&returnGeometry=true&f=geojson" result = queryWithAttempts(locationsUrl, QUERY_ATTEMPTS, timeout = timeout, queryName="nearPlaces") if Failures.isFailureCode(result): return result try: data = json.loads(result.text) except: return Failures.QUERY_PARSE_FAILURE_CODE features = data["features"] nearestFeatureDistance = sys.maxsize nearestFeature = None for feature in features: attrib = feature["properties"] point = feature["geometry"]["coordinates"][0] distance = Helpers.fastMagDist(point[1], point[0], lat, lng) if distance < nearestFeatureDistance: nearestFeatureDistance = distance nearestFeature = feature attrib = nearestFeature["properties"] stateAlpha = attrib["state_alpha"] placeName = attrib["gaz_name"] nearestPoint = nearestFeature["geometry"]["coordinates"][0] distance = Helpers.degDistance(nearestPoint[1], nearestPoint[0], lat, lng) return {"distanceToPlace":distance, "placeName":placeName, "state":stateAlpha}
def getXNeighborIDs(self, siteID, huc, numNeighbors): """ Get numNeighbors neighboring IDs above and below siteID :param siteID: The siteID. :param huc: The 2 digit huc code that the site is within. :param numNeighbors: The number of neighbors to get above and below siteID. :return: A list of all site IDs within the range. """ hucCode = huc[:2] loadResults = self.loadHucWeb(hucCode) if Failures.isFailureCode(loadResults): return loadResults numIds = len(self.ids[hucCode]) matchIndex = numIds - 1 for i, thisID in enumerate(self.ids[hucCode]): if thisID[:2] == siteID[:2]: if thisID == siteID or Helpers.siteIDCompare(thisID, siteID) > 0: testcmp = Helpers.siteIDCompare(thisID, siteID) matchIndex = i break minIndex = max(0, matchIndex - numNeighbors) upperIndex = min(numIds - 1, matchIndex + numNeighbors) return self.ids[hucCode][minIndex:upperIndex]
def getNeighborIDs(self, siteID, huc): """ Get the two nearest sequential neighbors to a siteID. Upstream neighbor meaning the site with the next lower DSN number than the input ID. :param siteID: The siteID. :param huc: The 2 digit huc code that the site is within. :return: (upstream neighbor, downstream neighbor) """ hucCode = huc[:2] loadResults = self.loadHucWeb(hucCode) if Failures.isFailureCode(loadResults): return loadResults matchIndex = self.ids[hucCode].index(siteID) if matchIndex == -1: return Failures.MISSING_SITEID_CODE numIds = len(self.ids[hucCode]) if matchIndex < numIds - 1: downstreamNeighbor = self.ids[hucCode][matchIndex + 1] if downstreamNeighbor[:2] != siteID[:2]: #if this neighbor is a different part code it's not valid downstreamNeighbor = None if matchIndex > 0: upstreamNeighbor = self.ids[hucCode][matchIndex - 1] if upstreamNeighbor[:2] != siteID[:2]: upstreamNeighbor = None #lower neighbor is lower in number, not in terms of downstream, vice versa return (upstreamNeighbor, downstreamNeighbor)
def getNearestBridges (lat, lng, timeout = 5): locationsUrl = "https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer/10/query?geometry=" + str(lng) +"," + str(lat) + "&geometryType=esriGeometryPoint&inSR=4326&outSR=4326&distance=7000&units=esriSRUnit_Meter&outFields=*&returnGeometry=true&f=geojson" result = queryWithAttempts(locationsUrl, QUERY_ATTEMPTS, timeout = timeout, queryName="nearBridges") if Failures.isFailureCode(result): return result try: data = json.loads(result.text) except: return Failures.QUERY_PARSE_FAILURE_CODE features = data["features"] bridges = [] for feature in features: attrib = feature["properties"] point = feature["geometry"]["coordinates"][0] distance = Helpers.degDistance(point[1], point[0], lat, lng) name = attrib["gaz_name"] bridges.append(PointOfContext(point=point, distance=distance, name=name)) return bridges
def getNextUpstreamSite(self, segment, downstreamPositionOnSegment): """ Find the next upstream site using backtracking if required. :param segment: The segment to search downstream from. :param downStreamPositionOnSegment: The position on the segment the search started from. This is used to get accurate distance measurements. :return: The found site or an error code.""" #get the first upstream site upstreamSitesInfo = self.collectSortedUpstreamSites( segment, downstreamPositionOnSegment, siteLimit=1) #if this failed, return failure code now if Failures.isFailureCode(upstreamSitesInfo): return upstreamSitesInfo upstreamSites = upstreamSitesInfo[0] # we are only looking for one upstream site here, but, we only need this distance variable in the case # where we don't find any upstream sites and have to backtrack. Thus, in that case, collectSortedUp... will have explored all of the graph # upstream from segment totalDistance = upstreamSitesInfo[1] foundSite = None if upstreamSites is not None and len(upstreamSites) > 0: foundSite = upstreamSites[ 0] #get the first upstream site / distance tuple if foundSite is not None: #we found a site. Great! return it #return (siteID, distance upstream to site) return (foundSite[0], foundSite[1]) #return (foundSite.siteID, summedDistance) else: #no site found upstream... #find the next major branch by backtracking nextUpstreamSegment = self.findNextLowerStreamLevelPath(segment) if Failures.isFailureCode(nextUpstreamSegment): return nextUpstreamSegment else: #we found a mainstream branch! if __debug__: print("successful backtrack. Found next main branch") #recursively call this function again starting at the first node of the next mainstream branch #the next mainstream branch should be the continuation of our trib in ID space newSearch = self.getNextUpstreamSite( nextUpstreamSegment[0], nextUpstreamSegment[0].length) if Failures.isFailureCode(newSearch): return newSearch else: #we found a site in the new search! #we want to return the new site and the distance to it plus the distance upstream along our trib return (newSearch[0], newSearch[1] + totalDistance)
def post(self): # Get values server = request.headers.get('server') email = request.form.get('email') password = request.form.get('password') password_confirm = request.form.get('password-confirm') locale = request.form.get('locale') screen_name = request.form.get('screenname') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('email', email) validation.add_required_field('password', password) validation.add_required_field('password-confirm', password_confirm) validation.add_required_field('locale', locale) validation.add_required_field('screenname', screen_name) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate email is not yet used existing_user = user_service.get_user_by_email(email) if existing_user is not None: return Failures.email_already_in_use(email) # Validate screen name is not yet used existing_user = user_service.get_user_by_screen_name(screen_name) if existing_user is not None: return Failures.screen_name_already_in_use(screen_name) # Validate password strength and confirm if password != password_confirm: return Failures.passwords_do_not_match() if not user_service.check_password_complexity(password): return Failures.password_complexity() id_user = user_service.create_local_user(server, email, password, locale, screen_name) user_service.send_email_confirm(id_user, server) db.session.commit() logging.info('User-controller: register success: %s', id_user) # Create user return {'success': True, 'user': id_user}
def post(id_user): screen_name = request.form.get('screenname') # Validate required fields validation = Validation() validation.add_required_field('id-user', id_user) validation.add_required_field('screenname', screen_name) if not validation.is_valid(): return validation.get_validation_response() # Validate the id parameter as an integer try: id_user = int(id_user) except ValueError: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) # Attempt to retrieve the proposed screen name to ensure that it is available user_by_email = user_service.get_user_by_screen_name(screen_name) if user_by_email is not None: if user.id != user_by_email.id: return Failures.screen_name_already_in_use(screen_name) # The screen name is available, Assign it to the user profile user.screen_name = screen_name db.session.commit() logging.info('User-controller: doInfoChange: success: %s (%s)', id_user, user.screen_name) return {'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source }}
def post(self): # Get values email = request.form.get('email') # User account email address token = request.form.get('token') # Token assigned to account during account registration # Validate required fields validation = Validation() validation.add_required_field('email', email) validation.add_required_field('token', token) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) # Delete expired tokens ConfirmToken.query.filter(ConfirmToken.validity < datetime.datetime.now()).delete() db.session.flush() confirm_token = ConfirmToken.query.filter_by(token=token).first() if confirm_token is None: # Unknown token return {'success': False, 'code': 510} if confirm_token.id_user != user.id: # Token is not for this user return {'success': False, 'code': 510} # Set user account status to 'Confirmed' user.confirmed = True # Delete the account confirmation token; it is no longer required db.session.delete(confirm_token) # Commit the user account changes db.session.commit() logging.info('LocalUser-controller: DoConfirm: success: %s', user.id) return {'success': True}
def collectSortedUpstreamSites (self, segment, downStreamPositionOnSegment, siteLimit = 1, autoExpand = True): # contains tuples of the form (site, dist to site) foundSites = [] # reverse order of segment.sites since normally it is ordered upstream->downstream # since we are collecting sites from downstream->upstream for site in reversed(segment.sites): if site.distDownstreamAlongSegment < downStreamPositionOnSegment and len(foundSites) < siteLimit: foundSites.append((site, downStreamPositionOnSegment - site.distDownstreamAlongSegment)) if len(foundSites) >= siteLimit: #return the list of found sites and the distance upstream of the last site found return (foundSites, foundSites[-1][1]) #get upstream tributaries of this path stack = [] stack.append(segment) summedDistance = 0 firstSegment = True while len(stack) > 0: thisSegment = stack.pop() # if there was a site on the first segment, we would catch it in # our first case at the beginning # we avoid this if passing on a site below our query on the first segment by checking # if this is the first segment we are looking at if firstSegment is False: for site in reversed(thisSegment.sites): if len(foundSites) < siteLimit: foundSites.append((site, summedDistance + (thisSegment.length - site.distDownstreamAlongSegment))) else: break summedDistance += thisSegment.length else: summedDistance += downStreamPositionOnSegment if len(foundSites) >= siteLimit: break #reverse the list. We want the lowest priority tribs to be looked at first newBranches = thisSegment.upStreamNode.getSortedUpstreamBranches() stack.extend(reversed(newBranches)) #expand graph if necessary thisSegmentPosition = thisSegment.upStreamNode.position #if during navigation, we reach edge of safe data boundary, expand with new query if autoExpand is True and not self.streamGraph.pointWithinSafeDataBoundary(thisSegmentPosition): graphExpansion = self.streamGraph.expandGraph(thisSegmentPosition[1], thisSegmentPosition[0]) if Failures.isFailureCode(graphExpansion): return graphExpansion elif self.terminateSearchOnQuery is True: return Failures.QUERY_TERMINATE_CODE firstSegment = False return (foundSites, summedDistance)
def get(self, email): # Get server URL server = request.headers.get('server') logging.info("Requesting email confirmation for %s from server %s", email, server) # Validate required fields validation = Validation() validation.add_required_field('email', email) validation.add_required_field('server', server) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) success, code, message = user_service.send_email_confirm(user.id, server) db.session.commit() if success: logging.info('LocalUser-controller: RequestConfirm: success: %s', user.id) return {'success': True} else: if code == 10: return Failures.rate_exceeded() elif code == 99: return { 'success': False, 'message': message, 'code': 540 } else: return { 'success': False, 'message': message, 'code': 520 }
def post(self): # Get values server = request.headers.get('server') email = request.form.get('email') password = request.form.get('password') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('email', email) validation.add_required_field('password', password) if not validation.is_valid(): return validation.get_validation_response() # Validate user exists, is validated and is not blocked user = user_services.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if not user.confirmed: return Failures.email_not_confirmed(email) if user.blocked: return Failures.user_blocked(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) if not rate_limiting_services.has_sufficient_tokens(user.id, 'failed-password', 1): return Failures.rate_exceeded() # The password might not be encoded correctly when submitted. This # could cause the check_password method to fault. We trap that # possibility and address it here. try: if not user_services.check_password(user.id, password): rate_limiting_services.consume_tokens(user.id, 'failed-password', 1) return Failures.wrong_password(email) except TypeError: return Failures.password_unknown_format("Unicode-objects must be encoded before hashing") db.session.commit() logging.info('Authenticate-controller: Authenticate: success: %s', email) return { 'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source }}
def expandGraph(self, lat, lng): if __debug__: print("Expanding graph!") baseData = loadFromQuery(lat, lng) if Failures.isFailureCode(baseData): if __debug__: print("could not expand graph") return baseData self.addGeom(baseData) return True
def post(self, id_user): # Get values old_password = request.form.get('old-password') password = request.form.get('password') password_confirm = request.form.get('password-confirm') # Validate required fields validation = Validation() validation.add_required_field('id_user', id_user) validation.add_required_field('old-password', old_password) validation.add_required_field('password', password) validation.add_required_field('password_confirm', password_confirm) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) # Validate password strength and confirm if password != password_confirm: return Failures.passwords_do_not_match() if not user_service.check_password_complexity(password): return Failures.password_complexity() if not user_service.check_password(id_user, old_password): # Token is not for this user return {'success': False, 'code': 530} salt, password_hash = user_service.get_password_hash(password) user.password = password_hash user.salt = salt db.session.commit() logging.info('LocalUser-controller: PasswordChange: success: %s', user.id) return {'success': True}
def expandGraph(self, lat, lng): """ Expand the graph at x,y with queried data. Return true if successful """ if __debug__: print("Expanding graph!") baseData = loadFromQuery(lat, lng) if Failures.isFailureCode(baseData): if __debug__: print("could not expand graph") return baseData self.addGeom(baseData) return True
def post(self, id_user): screen_name = request.form.get('screenname') # Validate required fields validation = Validation() validation.add_required_field('id-user', id_user) validation.add_required_field('screenname', screen_name) if not validation.is_valid(): return validation.get_validation_response() # Parse numbers try: id_user = int(id_user) except: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) user_by_email = user_service.get_user_by_screen_name(screen_name) if user_by_email is not None: if user.id != user_by_email.id: return Failures.screen_name_already_in_use(screen_name) user.screen_name = screen_name db.session.commit() logging.info('User-controller: doInfoChange: success: %s (%s)', id_user, user.screen_name) return { 'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source } }
def post(id_user): locale = request.form.get('locale') # Validate required fields validation = Validation() validation.add_required_field('id-user', id_user) validation.add_required_field('locale', locale) if not validation.is_valid(): return validation.get_validation_response() # Parse numbers try: id_user = int(id_user) except ValueError: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) user.locale = locale db.session.commit() logging.info('User-controller: doLocaleChange: success: %s (%s)', id_user, user.screen_name) return { 'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source } }
def loadHucWeb(self, code): """ Load all sites from a given huc code into the manager object. :param code: The HUC code being loaded. """ if code in self.ids: return True ids = GDALData.loadHUCSites(code) if Failures.isFailureCode(ids): return ids self.ids[code] = sorted(ids, key=lambda id: Helpers.getFullID(id)) return True
def findNextLowerStreamLevelPath(self, segment, downStreamPositionOnSegment=0, expand=True): """ Navigate downstream until a path with lower streamlevel is found. :param segment: The segment to search downstream from. :param downStreamPositionOnSegment: The position on the segment the search started from. This is used to get accurate distance measurements. :param expand: Do we expand the graph to help fulfil this query? :return: This function returns the first segment directly upstream from the junction of the main path and the tributary that 'segment' is on. """ tribLevel = segment.streamLevel dist = -downStreamPositionOnSegment #when we sum dist up, we must subtract #this from the first segment's length queue = [] queue.append(segment) nextMainPath = None while len(queue) > 0: current = queue.pop(0) dist += current.length if current.streamLevel < tribLevel: #if we find a lower stream level it is downstream from the trib we started on # so to find the next main stream path, we have to go up from this segment along the matching streamlevel neighbor upstreamNeighbors = current.upStreamNode.getUpstreamNeighbors() for neighbor in upstreamNeighbors: if neighbor.streamLevel == current.streamLevel: nextMainPath = neighbor break else: downstreamPoint = current.downStreamNode.position if not self.streamGraph.pointWithinSafeDataBoundary( downstreamPoint) and expand: graphExpansion = self.streamGraph.expandGraph( downstreamPoint[1], downstreamPoint[0]) if Failures.isFailureCode(graphExpansion): return graphExpansion elif self.terminateSearchOnQuery is True: return Failures.QUERY_TERMINATE_CODE nextSegments = current.downStreamNode.getDownstreamNeighbors( ) #getCodedNeighbors(DOWNSTREAM)#most likely only one such segment unless there is a fork in the river queue.extend(nextSegments) if nextMainPath is not None: return (nextMainPath, dist) else: return Failures.END_OF_BASIN_CODE
def beautifyID (siteID, lowerBound, upperBound, warningLog): siteID = str(siteID) shortenedID = siteID[:7] DSN = int(Helpers.getFullID(siteID)[2:]) partCode = siteID[:2] lowerBoundDSN = int(Helpers.getFullID(lowerBound)[2:]) upperBoundDSN = int(Helpers.getFullID(upperBound)[2:]) roundingPrecisions = [100, 50, 20, 10, 5, 2, 1] #now check if this number exists already idsInfo = GDALData.getSiteIDsStartingWith(shortenedID) if Failures.isFailureCode(idsInfo): warningLog.addWarning(WarningLog.LOW_PRIORITY, "Cannot verify if this site number already exists(" + idsInfo + "). Ensure this step is manually completed.") return siteID siteLayer = idsInfo existingNumbers = set() for site in siteLayer: siteNumber = site["properties"]["site_no"] existingNumbers.add(siteNumber) for roundTo in roundingPrecisions: roundedDSN = Helpers.roundTo(DSN, roundTo) fullRounded = Helpers.buildFullID(partCode, roundedDSN) if fullRounded not in existingNumbers and Helpers.betweenBounds(roundedDSN, lowerBoundDSN, upperBoundDSN): return Helpers.shortenID(fullRounded) #if we haven't returned yet we have a problem. idMinusExtension = siteID[:8] #as a last ditch effort, try all extensions to find one that's unique if len(existingNumbers) > 0: #if the ID we want is taken, try all possible extensions until one is free for i in range(0, 100): testExtension = str(i) if len(testExtension) == 1: testExtension = "0" + testExtension testNewID = idMinusExtension + testExtension testNewDSN = int(testNewID[2:]) if testNewID not in existingNumbers and Helpers.betweenBounds(testNewDSN, lowerBoundDSN, upperBoundDSN): return testNewID warningLog.addWarning(WarningLog.MED_PRIORITY, "Failed to find gap in ID space for new ID. This ID already exists.") return siteID
def get(self, email): # Get values server = request.headers.get('server') # Validate required fields validation = Validation() validation.add_required_field('email', email) validation.add_required_field('server', server) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate user exits user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) if not user.confirmed: return Failures.email_not_confirmed(user.email) success, code, message = user_service.send_password_reset(user.id, server) db.session.commit() if success: logging.info('LocalUser-controller: RequestPasswordReset: success: %s', user.id) return {'success': True} else: if code == 10: return Failures.rate_exceeded() return { 'success': False, 'message': message, 'code': 520 }
def post(id_user): locale = request.form.get('locale') # Validate required fields validation = Validation() validation.add_required_field('id-user', id_user) validation.add_required_field('locale', locale) if not validation.is_valid(): return validation.get_validation_response() # Parse numbers try: id_user = int(id_user) except ValueError: return Failures.not_a_number('idUser', id_user) # Validate user exists, is validated and is not blocked user = user_service.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) user.locale = locale db.session.commit() logging.info('User-controller: doLocaleChange: success: %s (%s)', id_user, user.screen_name) return {'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source }}
def post(self): # Get values server = request.headers.get('server') email = request.form.get('email') locale = request.form.get('locale') screen_name = request.form.get('screenname') source = request.form.get('source') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('email', email) validation.add_required_field('locale', locale) validation.add_required_field('screenname', screen_name) validation.add_required_field('source', source) validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate email is not yet used existing_user = user_service.get_user_by_email(email) if existing_user is not None: return Failures.email_already_in_use(email) # Validate screen name is not yet used existing_user = user_service.get_user_by_screen_name(screen_name) if existing_user is not None: return Failures.screen_name_already_in_use(screen_name) id_user = user_service.create_oauth_user(server, email, source, locale, screen_name) db.session.commit() logging.info('OAuth-controller: create success: %s', id_user) # Create user return {'success': True, 'user': id_user}
def getSiteIDsStartingWith (siteID, timeout = TIMEOUT): similarSitesQuery = "https://waterdata.usgs.gov/nwis/inventory?search_site_no=" + siteID + "&search_site_no_match_type=beginning&site_tp_cd=ST&group_key=NONE&format=sitefile_output&sitefile_output_format=xml&column_name=site_no&column_name=station_nm&column_name=site_tp_cd&column_name=dec_lat_va&column_name=dec_long_va&column_name=huc_cd&list_of_search_criteria=search_site_no%2Csite_tp_cd" result = queryWithAttempts (similarSitesQuery, QUERY_ATTEMPTS, timeout = timeout, queryName="similarSiteIds") if Failures.isFailureCode(result): return result geoJsonResults = buildGeoJson(result.text) try: sitesLayer = json.loads(geoJsonResults)["features"] except: if __debug__: print("could not read query") return Failures.QUERY_PARSE_FAILURE_CODE return (sitesLayer)
def get(self, bucket_type, id_user, count): # Validate required fields validation = Validation() validation.add_required_field('bucket_type', bucket_type) validation.add_required_field('id_user', id_user) validation.add_required_field('count', count) if not validation.is_valid(): return validation.get_validation_response() # Parse numbers try: id_user = int(id_user) except ValueError: return Failures.not_a_number('idUser', id_user) try: count = int(count) except ValueError: return Failures.not_a_number('count', count) # Validate user exists, is validated and is not blocked user = user_services.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) if user.blocked: return Failures.user_blocked() if not user.confirmed: return Failures.email_not_confirmed() bucket_types = app.config['CLOUD_SESSION_PROPERTIES'][ 'bucket.types'].split(',') if bucket_type not in bucket_types: return Failures.unknown_bucket_type(bucket_type) result, next_time = rate_limiting_services.consume_tokens( user.id, bucket_type, 1) if not result: db.session.commit() return Failures.rate_exceeded( next_time.strftime("%Y-%m-%d %H:%M:%S")) db.session.commit() logging.info( 'RateLimiting-controller: ConsumeMultiple: success: %s (%s - %s)', id_user, bucket_type, count) return {'success': True}
def post(self): # Get values server = request.headers.get('server') email = request.form.get('email') password = request.form.get('password') #browser = request.form.get('browser') #ip_address = request.form.get('ipAddress') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('email', email) validation.add_required_field('password', password) #validation.add_required_field('browser', browser) #validation.add_required_field('ipAddress', ip_address) if not validation.is_valid(): return validation.get_validation_response() # Validate user exists, is validated and is not blocked user = user_services.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if not user.confirmed: return Failures.email_not_confirmed() if user.blocked: return Failures.user_blocked() if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) if not rate_limiting_services.has_sufficient_tokens( user.id, 'failed-password', 1): return Failures.rate_exceeded() if not user_services.check_password(user.id, password): rate_limiting_services.consume_tokens(user.id, 'failed-password', 1) db.session.commit() return Failures.wrong_password() db.session.commit() logging.info('Authenticate-controller: Authenticate: success: %s', user.id) return { 'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source } }
def post(self): # Get values server = request.headers.get('server') email = request.form.get('email') password = request.form.get('password') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('email', email) validation.add_required_field('password', password) if not validation.is_valid(): return validation.get_validation_response() # Validate user exists, is validated and is not blocked user = user_services.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) if not user.confirmed: return Failures.email_not_confirmed(email) if user.blocked: return Failures.user_blocked(email) if user.auth_source != 'local': return Failures.wrong_auth_source(user.auth_source) if not rate_limiting_services.has_sufficient_tokens(user.id, 'failed-password', 1): return Failures.rate_exceeded() if not user_services.check_password(user.id, password): rate_limiting_services.consume_tokens(user.id, 'failed-password', 1) db.session.commit() return Failures.wrong_password(email) db.session.commit() logging.info('Authenticate-controller: Authenticate: success: %s', email) return {'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source }}
def __init__(self, lat, lng, withheldSites=[]): self.lat = lat self.lng = lng self.warningLog = WarningLog.WarningLog(lat, lng) self.streamGraph = StreamGraph(withheldSites=withheldSites, warningLog=self.warningLog) self.siteIDManager = SiteIDManager() self.context = None self.baseData = GDALData.loadFromQuery(self.lat, self.lng) if Failures.isFailureCode(self.baseData): if __debug__: print("could not get data") self.warningLog.addWarning(WarningLog.HIGH_PRIORITY, self.baseData) else: self.streamGraph.addGeom(self.baseData) self.siteNameContext = None
def get(self, bucket_type, id_user, count): # Validate required fields validation = Validation() validation.add_required_field('bucket_type', bucket_type) validation.add_required_field('id_user', id_user) validation.add_required_field('count', count) if not validation.is_valid(): return validation.get_validation_response() # Parse numbers try: id_user = int(id_user) except ValueError: return Failures.not_a_number('idUser', id_user) try: count = int(count) except ValueError: return Failures.not_a_number('count', count) # Validate user exists, is validated and is not blocked user = user_services.get_user(id_user) if user is None: return Failures.unknown_user_id(id_user) if user.blocked: return Failures.user_blocked() if not user.confirmed: return Failures.email_not_confirmed() bucket_types = app.config['CLOUD_SESSION_PROPERTIES']['bucket.types'].split(',') if bucket_type not in bucket_types: return Failures.unknown_bucket_type(bucket_type) result, next_time = rate_limiting_services.consume_tokens(user.id, bucket_type, 1) if not result: db.session.commit() return Failures.rate_exceeded(next_time.strftime("%Y-%m-%d %H:%M:%S")) db.session.commit() logging.info('RateLimiting-controller: ConsumeMultiple: success: %s (%s - %s)', id_user, bucket_type, count) return {'success': True}
def get(screen_name): # Validate user exists, is validated and is not blocked user = user_service.get_user_by_screen_name(screen_name) if user is None: return Failures.unknown_user_screen_name(screen_name) logging.info('User-controller: getUserByScreenname: success: %s (%s)', screen_name, user.screen_name) return {'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source }}
def get(email): # TODO: Validate the format of the email address before attempting database IO # Validate user exists, is validated and is not blocked user = user_service.get_user_by_email(email) if user is None: return Failures.unknown_user_email(email) logging.info('User-controller: getUserByEmail: success: %s (%s)', email, user.screen_name) return {'success': True, 'user': { 'id': user.id, 'email': user.email, 'locale': user.locale, 'screenname': user.screen_name, 'authentication-source': user.auth_source, 'bdmonth': user.birth_month, 'bdyear': user.birth_year, 'parent-email': user.parent_email, 'parent-email-source': user.parent_email_source }}
def post(): # Get values server = request.headers.get('server') email = request.form.get('email') password = request.form.get('password') password_confirm = request.form.get('password-confirm') locale = request.form.get('locale') screen_name = request.form.get('screenname') # COPPA support birth_month = request.form.get('bdmonth') birth_year = request.form.get('bdyear') parent_email = request.form.get('parent-email') parent_email_source = request.form.get('parent-email-source') # Validate required fields validation = Validation() validation.add_required_field('server', server) validation.add_required_field('email', email) validation.add_required_field('password', password) validation.add_required_field('password-confirm', password_confirm) validation.add_required_field('locale', locale) validation.add_required_field('screenname', screen_name) # COPPA support validation.add_required_field('bdmonth', birth_month) validation.add_required_field('bdyear', birth_year) if parent_email: validation.check_email('parent-email', parent_email) if not validation.is_valid(): return validation.get_validation_response() # Verify user email address validation.check_email('email', email) if not validation.is_valid(): return validation.get_validation_response() # Validate email is not yet used existing_user = user_service.get_user_by_email(email) if existing_user is not None: return Failures.email_already_in_use(email) # Validate screen name is not yet used existing_user = user_service.get_user_by_screen_name(screen_name) if existing_user is not None: return Failures.screen_name_already_in_use(screen_name) # Validate password strength and confirm if password != password_confirm: return Failures.passwords_do_not_match() if not user_service.check_password_complexity(password): return Failures.password_complexity() # Write user details to the database id_user = user_service.create_local_user( server, email, password, locale, screen_name, birth_month, birth_year, parent_email, parent_email_source) # Send a confirmation request email to user or parent (result, errno, mesg) = user_service.send_email_confirm(id_user, server) if result: # Commit the database record db.session.commit() logging.info('User-controller: register success: %s', id_user) # Create user return {'success': True, 'user': id_user} else: logging.error("Unable to register user. Error %s: %s", errno, mesg) return {'success': False, 'user': 0}