def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Theme, LayerGroup, Interface, LayerWMS main = Interface(name="desktop") ogc_server, _ = create_default_ogcserver() layer_wms = LayerWMS(name="__test_layer_wms", public=True) layer_wms.layer = "testpoint_unprotected" layer_wms.interfaces = [main] layer_wms.ogc_server = ogc_server layer_group = LayerGroup(name="__test_layer_group") layer_group.children = [layer_wms] theme = Theme(name="__test/theme") theme.interfaces = [main] theme.children = [ layer_group ] DBSession.add(theme) transaction.commit()
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Theme, LayerGroup, Interface, LayerWMS main = Interface(name="desktop") ogc_server, _ = create_default_ogcserver() layer_wms = LayerWMS(name="__test_layer_wms", public=True) layer_wms.layer = "testpoint_unprotected" layer_wms.interfaces = [main] layer_wms.ogc_server = ogc_server layer_group = LayerGroup(name="__test_layer_group") layer_group.children = [layer_wms] theme = Theme(name="__test/theme") theme.interfaces = [main] theme.children = [layer_group] DBSession.add(theme) transaction.commit()
def fill_tech_user_functionality(name, functionalities): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Functionality, Role role = DBSession.query(Role).filter_by(name=name).one() role.functionalities = [Functionality(name, value) for name, value in functionalities] DBSession.add(role) transaction.commit() caching.invalidate_region()
def __log_download_stats(self, objectids, download_link): pag_download = PagDownload() pag_download.objectids = objectids pag_download.download_link = download_link try: DBSession.add(pag_download) except Exception as e: log.exception(e) transaction.abort()
def _log_download_sketch_stats(self, filename, town): sketch_download = SketchDownload() if self.request.user is not None: sketch_download.login = self.request.user.username else: sketch_download.login = None sketch_download.application = self.request.host sketch_download.filename = filename sketch_download.directory = town DBSession.add(sketch_download) transaction.commit()
def create_default_ogcserver(): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import OGCServer transaction.commit() ogcserver = OGCServer(name="__test_ogc_server") ogcserver.url = mapserv_url DBSession.add(ogcserver) transaction.commit() caching.invalidate_region() return ogcserver
def main(): parser = argparse.ArgumentParser( description="Create and populate the database tables.") parser.add_argument('-i', '--iniconfig', default='production.ini', help='project .ini config file') parser.add_argument( '-n', '--app-name', default="app", help='The application name (optional, default is "app")') options = parser.parse_args() # read the configuration env = {} env.update(os.environ) env["LOG_LEVEL"] = "INFO" env["GUNICORN_ACCESS_LOG_LEVEL"] = "INFO" env["C2CGEOPORTAL_LOG_LEVEL"] = "WARN" fileConfig(options.iniconfig, defaults=env) get_app(options.iniconfig, options.app_name, options=env) from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Interface, OGCServer, Theme, LayerGroup, LayerWMS session = DBSession() interfaces = session.query(Interface).all() ogc_server = session.query(OGCServer).filter( OGCServer.name == "source for image/png").one() layer_borders = LayerWMS("Borders", "borders") layer_borders.interfaces = interfaces layer_borders.ogc_server = ogc_server layer_density = LayerWMS("Density", "density") layer_density.interfaces = interfaces layer_density.ogc_server = ogc_server group = LayerGroup("Demo") group.children = [layer_borders, layer_density] theme = Theme("Demo") theme.children = [group] theme.interfaces = interfaces session.add(theme) transaction.commit() print("Successfully added the demo theme")
def setup_method(self, _): self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = User(username="******", password="******") DBSession.add(user) user2 = User(username="******", password="******", deactivated=True) DBSession.add(user2) now = datetime.datetime.utcnow() user3 = User(username="******", password="******", expire_on=now) DBSession.add(user3) tomorrow = now + datetime.timedelta(days=1) user4 = User(username="******", password="******", expire_on=tomorrow) DBSession.add(user4) DBSession.flush()
def _log_download_measurement_stats(self, filename, town, parcel): mesurage_download = MesurageDownload() if self.request.user is None: mesurage_download.login = '******' else: mesurage_download.login = self.request.user.username mesurage_download.application = self.request.host mesurage_download.filename = filename mesurage_download.commune = town mesurage_download.parcelle = parcel DBSession.add(mesurage_download) transaction.commit()
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import OGCServer setup_db() ogcserver = OGCServer(name="MixedCaseOGCServer") ogcserver.url = "http://mapserver:8080/" DBSession.add(ogcserver) DBSession.flush() transaction.commit()
def setup_method(self, _): self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = User(username="******", password="******") DBSession.add(user) DBSession.flush() self.old_remember = pyramid.security.remember self.user = None def remember(request, user=None): self.user = user pyramid.security.remember = remember
def main(): parser = argparse.ArgumentParser( description="Create and populate the database tables." ) parser.add_argument( '-i', '--iniconfig', default='geoportal/production.ini', help='project .ini config file' ) parser.add_argument( '-n', '--app-name', default="app", help='The application name (optional, default is "app")' ) options = parser.parse_args() # read the configuration fileConfig(options.iniconfig, defaults=os.environ) get_app(options.iniconfig, options.app_name, options=os.environ) from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Interface, OGCServer, Theme, LayerGroup, LayerWMS session = DBSession() interfaces = session.query(Interface).all() ogc_server = session.query(OGCServer).filter(OGCServer.name == "source for image/png").one() layer_borders = LayerWMS("Borders", "borders") layer_borders.interfaces = interfaces layer_borders.ogc_server = ogc_server layer_density = LayerWMS("Density", "density") layer_density.interfaces = interfaces layer_density.ogc_server = ogc_server group = LayerGroup("Demo") group.children = [layer_borders, layer_density] theme = Theme("Demo") theme.children = [group] theme.interfaces = interfaces session.add(theme) transaction.commit()
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None # pylint: disable=invalid-name self._tables = [] from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User setup_db() user = User(username="******", password="******") user.email = "*****@*****.**" DBSession.add(user) testing.setUp().testing_securitypolicy(remember_result=[("Cookie", "Test")]) transaction.commit()
def ldap_user_validator(request, username, password): connector = get_ldap_connector(request) cm = connector.manager data = None with cm.connection() as conn: try: ldap_settings = request.registry.settings['ldap'] base_dn = ldap_settings['base_dn'] filter_tmpl = ldap_settings['filter_tmpl'].replace('%(login)s', username) message_id = conn.search( base_dn, filter_tmpl, ldap.SUBTREE, ldap.DEREF_ALWAYS) result = conn.get_response(message_id)[0] if len(result) > 0: data = result[0]['dn'] conn.unbind() except Exception as e: log.exception(e) conn.unbind() conn = None try: conn = cm.connection(data, password) conn.unbind() except Exception as e: log.exception(e) if conn is not None: conn.unbind() data = None connection = Connections() connection.login = username connection.application = request.host if data is not None: connection.action = "CONNECT" DBSession.add(connection) return username else: connection.action = "CONNECT ERROR" DBSession.add(connection) return None
def setup_method(self, _): setup_module() import transaction from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Role, Interface from c2cgeoportal_commons.models.static import User cleanup_db() self.metadata = None self.layer_ids = [] DBSession.query(User).delete() DBSession.query(User).filter(User.username == "__test_user").delete() self.role = Role(name="__test_role") self.user = User(username="******", password="******", settings_role=self.role, roles=[self.role]) self.main = Interface(name="main") DBSession.add(self.user) DBSession.add(self.role) DBSession.add(self.main) transaction.commit()
def setup_method(self, _): setup_module() import transaction from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Interface, Role from c2cgeoportal_commons.models.static import User setup_db() self.metadata = None self.layer_ids = [] for o in DBSession.query(User).all(): DBSession.delete(o) self.role = Role(name="__test_role") self.user = User(username="******", password="******", settings_role=self.role, roles=[self.role]) self.main = Interface(name="main") DBSession.add(self.user) DBSession.add(self.role) DBSession.add(self.main) create_default_ogcserver() transaction.commit()
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, Theme main = Interface(name="desktop") ogc_server = create_default_ogcserver() layer_wms_1 = LayerWMS(name="__test_layer_wms_1", public=True) layer_wms_1.layer = "testpoint_unprotected" layer_wms_1.interfaces = [main] layer_wms_1.ogc_server = ogc_server layer_wms_2 = LayerWMS(name="__test_layer_wms_2", public=True) layer_wms_2.layer = "testpoint_substitution" layer_wms_2.interfaces = [main] layer_wms_2.ogc_server = ogc_server layer_wms_3 = LayerWMS(name="__test_layer_wms_3", public=True) layer_wms_3.layer = "testpoint_unprotected,testpoint_substitution" layer_wms_3.interfaces = [main] layer_wms_3.ogc_server = ogc_server layer_group_1 = LayerGroup(name="__test_layer_group_1") layer_group_1.children = [layer_wms_1, layer_wms_2] layer_group_2 = LayerGroup(name="__test_layer_group_2") layer_group_2.children = [layer_wms_1, layer_wms_3] theme = Theme(name="__test_theme") theme.interfaces = [main] theme.children = [layer_group_1, layer_group_2] DBSession.add(theme) transaction.commit()
def setup_method(self, _): self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = User(username="******", password="******") DBSession.add(user) user2 = User(username="******", password="******", deactivated=True) DBSession.add(user2) now = datetime.datetime.utcnow() user3 = User(username="******", password="******", expire_on=now) DBSession.add(user3) tomorrow = now + datetime.timedelta(days=1) user4 = User(username="******", password="******", expire_on=tomorrow) DBSession.add(user4) DBSession.flush() self.old_remember = pyramid.security.remember self.user = None def remember(request, user=None): del request # Unused self.user = user pyramid.security.remember = remember
def _create_layer(self, exclude_properties=False, metadatas=None, geom_type=False): """ This function is central for this test class. It creates a layer with two features, and associates a restriction area to it. """ import transaction from sqlalchemy import Column, Table, types, ForeignKey from sqlalchemy.ext.declarative import declarative_base from geoalchemy2 import Geometry from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import RestrictionArea, LayerWMS self.__class__._table_index += 1 id = self.__class__._table_index engine = DBSession.c2c_rw_bind connection = engine.connect() if not self.metadata: self.metadata = declarative_base(bind=engine).metadata tablename = "geo_table_{0:d}".format(id) schemaname = "geodata" table1 = Table( "{0!s}_child".format(tablename), self.metadata, Column("id", types.Integer, primary_key=True), Column("name", types.Unicode), schema=schemaname ) self._tables.append(table1) table2 = Table( tablename, self.metadata, Column("id", types.Integer, primary_key=True), Column("child_id", types.Integer, ForeignKey("{0!s}.{1!s}_child.id".format(schemaname, tablename))), Column("name", types.Unicode, nullable=False), Column("deleted", types.Boolean), Column("last_update_user", types.Unicode), Column("last_update_date", types.DateTime), Column("date", types.Date), Column("start_time", types.Time), # Column("interval", Interval()), Column("short_name1", types.String, nullable=True), Column("short_name2", types.String(50), nullable=True), Column("short_number", types.Integer, nullable=True), Column("double_number", types.Float(precision=4)), Column("large_binary", types.LargeBinary(length=60), nullable=True), Column("value", types.Enum("one", "two", "three", name="an_enum_value")), Column("numeric", types.Numeric(precision=5, scale=2), nullable=True), Column("numeric2", types.Numeric(), nullable=True), schema=schemaname ) if geom_type: table2.append_column( Column("geom", Geometry("POINT", srid=21781)) ) else: table2.append_column( Column("geom", Geometry(srid=21781)) ) self._tables.append(table2) table2.drop(checkfirst=True) table1.drop(checkfirst=True) table1.create() table2.create() ins = table1.insert().values(name="c1é") connection.execute(ins).inserted_primary_key[0] ins = table1.insert().values(name="c2é") connection.execute(ins).inserted_primary_key[0] layer = LayerWMS(name="test_WMS_1", public=True) layer.layer = "test_wms" layer.id = id layer.geo_table = "{0!s}.{1!s}".format(schemaname, tablename) layer.interfaces = [self.main] layer.ogc_server = self.ogc_server if exclude_properties: layer.exclude_properties = "name" if metadatas: layer.metadatas = metadatas DBSession.add(self.layer_group_1) self.layer_group_1.children = self.layer_group_1.children + [layer] DBSession.add(self.layer_group_1) ra = RestrictionArea() ra.name = "__test_ra" ra.layers = [layer] ra.roles = [self.role] ra.readwrite = True DBSession.add(ra) transaction.commit() self.layer_ids.append(id) return id
def create(self): if "url" not in self.request.params: raise HTTPBadRequest("The parameter url is required") url = self.request.params["url"] # see: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline if len(url) > 8190: # pragma: no cover raise HTTPBadRequest("The parameter url is too long ({} > {})".format(len(url), 8190)) # Check that it is an internal URL... uri_parts = urlparse(url) hostname = uri_parts.hostname if "allowed_hosts" in self.settings: if hostname not in self.settings["allowed_hosts"]: # pragma: no cover raise HTTPBadRequest("The requested host is not allowed.") else: if hostname != self.request.server_name: raise HTTPBadRequest("The requested host '{0!s}' should be '{1!s}'".format( hostname, self.request.server_name )) shortened = False for base in self.short_bases: base_parts = urlparse(base) if uri_parts.path.startswith(base_parts.path): shortened = True ref = uri_parts.path.split("/")[-1] tries = 0 while not shortened: ref = "".join( random.choice(string.ascii_letters + string.digits) for i in range(self.settings.get("length", 4)) ) test_url = DBSession.query(Shorturl).filter(Shorturl.ref == ref).all() if len(test_url) == 0: break tries += 1 # pragma: no cover if tries > 20: # pragma: no cover message = "No free ref found, considere to increase the length" logging.error(message) raise HTTPInternalServerError(message) user_email = self.request.user.email \ if self.request.user is not None else None email = self.request.params.get("email") if not shortened: short_url = Shorturl() short_url.url = url short_url.ref = ref short_url.creator_email = user_email short_url.creation = datetime.now() short_url.nb_hits = 0 DBSession.add(short_url) if "base_url" in self.settings: s_url = self.settings["base_url"] + ref else: s_url = self.request.route_url("shortener_get", ref=ref) email = email or user_email smtp_config = self.request.registry.settings.get("smtp", {}) if \ email is not None and \ "email_from" in self.settings and \ "email_subject" in self.settings and \ "email_body" in self.settings: # pragma: no cover text = self.settings["email_body"] % { "full_url": url, "short_url": s_url, "message": self.request.params.get("message", ""), } send_email( self.settings["email_from"], [email], text.encode("utf-8"), self.settings["email_subject"], smtp_config ) set_common_headers( self.request, "shortener", NO_CACHE ) return {"short_url": s_url}
def get_route(self): coords = self.request.params.get('waypoints', '').split(',') lang = self.request.params.get('lang', 'fr') transport_mode = int(self.request.params.get('transportMode', 0)) criteria = int(self.request.params.get('criteria', 0)) avoid = self.request.params.get('avoid', '').split(',') prefer_bike_road =\ int(self.request.params.get('preferBikeRoad', False)) bike_avoid_hills =\ int(self.request.params.get('bikeAvoidHills', False)) if coords == ['']: coords = [] # At least two waypoints (4 coordinates) are required if len(coords) < 4: routing_success = False return HTTPBadRequest("Not enough waypoints (At least 2 required)") else: # Use Graphhopper for bicycle routing, Mapquest for all other modes if len(coords) <= 10 and transport_mode in [2]: r = GraphhopperRouter(self.config['routing']['graphhopper']) self.__setup_router(coords, lang, transport_mode, criteria, avoid, prefer_bike_road, bike_avoid_hills, r) try: r.execute() except HTTPError as e: if e.code == 429: r = MapquestRouter(self.config['routing']['mapquest']) self.__setup_router( coords, lang, transport_mode, criteria, avoid, prefer_bike_road, bike_avoid_hills, r) r.execute() else: raise e else: r = MapquestRouter(self.config['routing']['mapquest']) self.__setup_router( coords, lang, transport_mode, criteria, avoid, prefer_bike_road, bike_avoid_hills, r) r.execute() if r.geom and len(r.geom) > 0: routing_success = True else: routing_success = False r.errorMessages.append('An error occured') try: routing_stats = RoutingStats() routing_stats.transport_mode = transport_mode routing_stats.transport_criteria = criteria DBSession.add(routing_stats) except Exception as e: log.exception(e) transaction.abort() if routing_success: json_response = { "type": "FeatureCollection", "features": [ {'type': "Feature", 'properties': { 'success': routing_success, 'desc': r.desc, 'dist': int(r.dist), 'time': r.time, 'errorMessages': r.errorMessages, 'attribution': r.attribution}, 'geometry': r.geom}]} else: json_response = {'success': routing_success, 'geometry': None, 'desc': [], 'dist': 0, 'time': 0, 'errorMessages': r.errorMessages, 'attribution': r.attribution} return json_response
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Theme, LayerGroup, Interface, OGCServer, LayerWMS, LayerWMTS main = Interface(name="main") ogc_server_internal = create_default_ogcserver() ogc_server_external = OGCServer(name="__test_ogc_server_external", url="http://wms.geo.admin.ch/", image_type="image/jpeg") layer_internal_wms = LayerWMS(name="__test_layer_internal_wms", public=True) layer_internal_wms.layer = "__test_layer_internal_wms" layer_internal_wms.interfaces = [main] layer_internal_wms.ogc_server = ogc_server_internal layer_external_wms = LayerWMS(name="__test_layer_external_wms", layer="ch.swisstopo.dreiecksvermaschung", public=True) layer_external_wms.interfaces = [main] layer_external_wms.ogc_server = ogc_server_external layer_wmts = LayerWMTS(name="__test_layer_wmts", public=True) layer_wmts.url = "http://example.com/1.0.0/WMTSCapabilities.xml" layer_wmts.layer = "map" layer_wmts.interfaces = [main] layer_group_1 = LayerGroup(name="__test_layer_group_1") layer_group_1.children = [layer_internal_wms] layer_group_2 = LayerGroup(name="__test_layer_group_2") layer_group_2.children = [layer_external_wms] layer_group_3 = LayerGroup(name="__test_layer_group_3") layer_group_3.children = [layer_wmts] layer_group_4 = LayerGroup(name="__test_layer_group_4") layer_group_4.children = [layer_group_1, layer_group_2] layer_group_5 = LayerGroup(name="__test_layer_group_5") layer_group_5.children = [layer_group_1, layer_group_3] layer_group_6 = LayerGroup(name="__test_layer_group_6") layer_group_6.children = [layer_internal_wms] layer_group_7 = LayerGroup(name="__test_layer_group_7") layer_group_7.children = [layer_group_1, layer_group_6] layer_group_8 = LayerGroup(name="__test_layer_group_8") layer_group_8.children = [layer_group_2, layer_group_6] theme = Theme(name="__test_theme") theme.interfaces = [main] theme.children = [ layer_group_1, layer_group_2, layer_group_3, layer_group_4, layer_group_5, layer_group_7, layer_group_8, ] DBSession.add(theme) transaction.commit()
def save_bearer_token( self, token: Dict[str, Union[str, int]], request: oauthlib.common.Request, *args: Any, **kwargs: Any, ) -> None: """ Persist the Bearer token. The Bearer token should at minimum be associated with: - a client and it's client_id, if available - a resource owner / user (request.user) - authorized scopes (request.scopes) - an expiration time - a refresh token, if issued The Bearer token dict may hold a number of items:: { 'token_type': 'Bearer', 'access_token': 'askfjh234as9sd8', 'expires_in': 3600, 'scope': 'string of space separated authorized scopes', 'refresh_token': '23sdf876234', # if issued 'state': 'given_by_client', # if supplied by client } Note that while "scope" is a string-separated list of authorized scopes, the original list is still available in request.scopes Arguments: client_id: Unicode client identifier token: A Bearer token dict request: The HTTP Request Returns: The default redirect URI for the client Method is used by all core grant types issuing Bearer tokens: - Authorization Code Grant - Implicit Grant - Resource Owner Password Credentials Grant (might not associate a client) - Client Credentials grant """ del args, kwargs LOG.debug("save_bearer_token") from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel # Don't allows to have tow token for one user end one client bearer_token = (DBSession.query(static.OAuth2BearerToken).filter( static.OAuth2BearerToken.client_id == request.client.id).filter( static.OAuth2BearerToken.user_id == request.user.id).one_or_none()) if bearer_token is not None: bearer_token.access_token = token["access_token"] bearer_token.refresh_token = token["refresh_token"] bearer_token.expire_at = datetime.now() + timedelta( seconds=float(token["expires_in"])) else: bearer_token = static.OAuth2BearerToken() bearer_token.client_id = request.client.id bearer_token.user_id = request.user.id bearer_token.access_token = token["access_token"] bearer_token.refresh_token = token["refresh_token"] bearer_token.expire_at = datetime.now() + timedelta( seconds=float(token["expires_in"])) DBSession.add(bearer_token)
def save_authorization_code( self, client_id: str, code: Dict[str, str], request: oauthlib.common.Request, *args: Any, **kwargs: Any, ) -> None: """ Persist the authorization_code. The code should at minimum be stored with: - the client_id (client_id) - the redirect URI used (request.redirect_uri) - a resource owner / user (request.user) - the authorized scopes (request.scopes) - the client state, if given (code.get('state')) The 'code' argument is actually a dictionary, containing at least a 'code' key with the actual authorization code: {'code': 'sdf345jsdf0934f'} It may also have a 'state' key containing a nonce for the client, if it chose to send one. That value should be saved and used in 'validate_code'. Arguments: client_id: Unicode client identifier code: A dict of the authorization code grant and, optionally, state. request: The HTTP Request Method is used by: - Authorization Code Grant """ del args, kwargs LOG.debug("save_authorization_code %s", client_id) from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel user = pyramid.threadlocal.get_current_request().user_ # Don't allows to have two authentications for the same user and the same client authorization_code = (DBSession.query( static.OAuth2AuthorizationCode).filter( static.OAuth2AuthorizationCode.client_id == request.client.id). filter(static.OAuth2AuthorizationCode.user_id == user.id).one_or_none()) if authorization_code is not None: authorization_code.code = code["code"] authorization_code.expire_at = datetime.now() + timedelta( minutes=self.authorization_expires_in) authorization_code.redirect_uri = request.redirect_uri else: authorization_code = static.OAuth2AuthorizationCode() authorization_code.client_id = request.client.id authorization_code.code = code["code"] authorization_code.user_id = user.id authorization_code.expire_at = datetime.now() + timedelta( minutes=self.authorization_expires_in) authorization_code.redirect_uri = request.redirect_uri DBSession.add(authorization_code)
def main(): """ Emergency user create and password reset script example, reset toto password to foobar: ./docker-compose-run manage_users -p foobar toto example, create user foo with password bar and role admin: ./docker-compose-run manage_users -c -r role_admin -p bar foo to get the options list, do: ./docker-compose-run manage_users -h """ usage = """Usage: %prog [options] USERNAME Reset a user password. The username is used as password if the password is not provided with the corresponding option. User can be created if it does not exist yet.""" parser = argparse.ArgumentParser(description=usage) parser.add_argument( "-i", "--app-config", default="geoportal/production.ini", dest="app_config", help="The application .ini config file (optional, default is " "'production.ini')" ) parser.add_argument( "-n", "--app-name", default="app", dest="app_name", help="The application name (optional, default is 'app')" ) parser.add_argument( "-p", "--password", help="Set password (if not set, username is used as password" ) parser.add_argument( "-c", "--create", action="store_true", default=False, help="Create user if it does not already exist" ) parser.add_argument( "-r", "--rolename", default="role_admin", help="The role name which must exist in the database" ) parser.add_argument( "-e", "--email", default=None, help="The user email" ) parser.add_argument( 'user', nargs='1', help="The user" ) options = parser.parse_args() username = options.user app_config = options.app_config app_name = options.app_name if app_name is None and "#" in app_config: app_config, app_name = app_config.split("#", 1) if not os.path.isfile(app_config): parser.error("Cannot find config file: {0!s}".format(app_config)) # loading schema name from config and setting its value to the # corresponding global variable from c2cgeoportal_geoportal # Ignores pyramid deprecation warnings warnings.simplefilter("ignore", DeprecationWarning) fileConfig(app_config, defaults=os.environ) get_app(app_name, options.app_name, options=os.environ) # must be done only once we have loaded the project config from c2cgeoportal_commons.models import DBSession, main, static print("\n") # check that user exists sess = DBSession() query = sess.query(static.User).filter_by(username="******".format(username)) result = query.count() if result == 0: if not options.create: # if doesn"t exist and no -c option, throw error raise Exception("User {0!s} does not exist in database".format(username)) else: print(("User {0!s} does not exist in database, creating".format(username))) # if does not exist and -c option, create user password = options.password if options.password is not None else username email = options.email if options.email is not None else username # get roles query_role = sess.query(main.Role).filter( main.Role.name == "{0!s}".format(options.rolename)) if query_role.count() == 0: # role not found in db? raise Exception("Role matching {0!s} does not exist in database".format( options.rolename )) role = query_role.first() user = static.User( username="******".format(username), password="******".format(password), email="{0!s}".format(email), role=role ) sess.add(user) transaction.commit() print(("User {0!s} created with password {1!s} and role {2!s}".format( username, password, options.rolename ))) else: # if user exists (assuming username are unique) user = query.first() if options.password is not None: print(("Password set to: {0!s}".format(options.password))) user.password = "******".format(options.password) if options.email is not None: user.email = options.email sess.add(user) transaction.commit() print(("Password resetted for user {0!s}".format(username)))
def main(): """ Emergency user create and password reset script example, reset toto password to foobar: ./docker-compose-run manage_users -p foobar toto example, create user foo with password bar and role admin: ./docker-compose-run manage_users -c -r role_admin -p bar foo to get the options list, do: ./docker-compose-run manage_users -h """ usage = """Usage: %prog [options] USERNAME Reset a user password. The username is used as password if the password is not provided with the corresponding option. User can be created if it does not exist yet.""" parser = argparse.ArgumentParser(description=usage) parser.add_argument( "-i", "--app-config", default="geoportal/production.ini", dest="app_config", help="The application .ini config file (optional, default is " "'production.ini')") parser.add_argument( "-n", "--app-name", default="app", dest="app_name", help="The application name (optional, default is 'app')") parser.add_argument( "-p", "--password", help="Set password (if not set, username is used as password") parser.add_argument("-c", "--create", action="store_true", default=False, help="Create user if it does not already exist") parser.add_argument("-r", "--rolename", default="role_admin", help="The role name which must exist in the database") parser.add_argument("-e", "--email", default=None, help="The user email") parser.add_argument('user', nargs='1', help="The user") options = parser.parse_args() username = options.user app_config = options.app_config app_name = options.app_name if app_name is None and "#" in app_config: app_config, app_name = app_config.split("#", 1) if not os.path.isfile(app_config): parser.error("Cannot find config file: {0!s}".format(app_config)) # loading schema name from config and setting its value to the # corresponding global variable from c2cgeoportal_geoportal # Ignores pyramid deprecation warnings warnings.simplefilter("ignore", DeprecationWarning) fileConfig(app_config, defaults=os.environ) get_app(app_name, options.app_name, options=os.environ) # must be done only once we have loaded the project config from c2cgeoportal_commons.models import DBSession, main, static print("\n") # check that user exists sess = DBSession() query = sess.query( static.User).filter_by(username="******".format(username)) result = query.count() if result == 0: if not options.create: # if doesn"t exist and no -c option, throw error raise Exception( "User {0!s} does not exist in database".format(username)) else: print(("User {0!s} does not exist in database, creating".format( username))) # if does not exist and -c option, create user password = options.password if options.password is not None else username email = options.email if options.email is not None else username # get roles query_role = sess.query(main.Role).filter( main.Role.name == "{0!s}".format(options.rolename)) if query_role.count() == 0: # role not found in db? raise Exception( "Role matching {0!s} does not exist in database".format( options.rolename)) role = query_role.first() user = static.User(username="******".format(username), password="******".format(password), email="{0!s}".format(email), role=role) sess.add(user) transaction.commit() print(( "User {0!s} created with password {1!s} and role {2!s}".format( username, password, options.rolename))) else: # if user exists (assuming username are unique) user = query.first() if options.password is not None: print(("Password set to: {0!s}".format(options.password))) user.password = "******".format(options.password) if options.email is not None: user.email = options.email sess.add(user) transaction.commit() print(("Password reset for user {0!s}".format(username)))
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None self._tables = [] from c2cgeoportal_geoportal.lib import functionality functionality.FUNCTIONALITIES_TYPES = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Role, \ RestrictionArea, TreeItem, Theme, LayerGroup, Interface, LayerWMS from c2cgeoportal_commons.models.static import User from sqlalchemy import Column, Table, types from sqlalchemy.ext.declarative import declarative_base from geoalchemy2 import Geometry for o in DBSession.query(RestrictionArea).all(): DBSession.delete(o) for o in DBSession.query(Role).all(): DBSession.delete(o) for o in DBSession.query(User).all(): DBSession.delete(o) for o in DBSession.query(TreeItem).all(): DBSession.delete(o) ogcserver = create_default_ogcserver() role1 = Role(name="__test_role1") role1.id = 999 user1 = User(username="******", password="******", settings_role=role1, roles=[role1]) user1.email = "*****@*****.**" role2 = Role(name="__test_role2", extent=WKTElement( "POLYGON((1 2, 1 4, 3 4, 3 2, 1 2))", srid=21781 )) user2 = User(username="******", password="******", settings_role=role2, roles=[role2]) main = Interface(name="main") engine = DBSession.c2c_rw_bind engine.connect() a_geo_table = Table( "a_geo_table", declarative_base(bind=engine).metadata, Column("id", types.Integer, primary_key=True), Column("geom", Geometry("POINT", srid=21781)), schema="geodata" ) self._tables = [a_geo_table] a_geo_table.drop(checkfirst=True) a_geo_table.create() private_layer = LayerWMS(name="__test_private_layer", public=False) private_layer.layer = "__test_private_layer" private_layer.geo_table = "geodata.a_geo_table" private_layer.interfaces = [main] private_layer.ogc_server = ogcserver group = LayerGroup(name="__test_layer_group") group.children = [private_layer] theme = Theme(name="__test_theme") theme.children = [group] theme.interfaces = [main] DBSession.add(RestrictionArea( name="__test_ra1", description="", layers=[private_layer], roles=[role1], )) DBSession.add(RestrictionArea( name="__test_ra2", description="", layers=[private_layer], roles=[role2], readwrite=True, )) DBSession.add_all([ user1, user2, role1, role2, theme, group, private_layer, ]) transaction.commit()
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Theme, LayerGroup, Interface, LayerWMS, Metadata desktop = Interface(name="desktop") ogc_server_internal, _ = create_default_ogcserver() layer_wms = LayerWMS(name="__test_layer_internal_wms", public=True) layer_wms.layer = "__test_layer_internal_wms" layer_wms.ogc_server = ogc_server_internal layer_wms.interfaces = [desktop] layer_wms.metadatas = [ Metadata("string", "string"), Metadata("list", "1, 2, a"), Metadata("boolean", "y"), Metadata("boolean2", "no"), Metadata("boolean3", "Hello"), Metadata("integer", "1"), Metadata("float", "5.5"), Metadata("json", '{"test": 123}'), Metadata("json_wrong", '{"test": 123'), Metadata("date", "Sep 25 2003"), Metadata("time", "10:36:28"), Metadata("datetime", "Sep 25 10:36:28 BRST 2003"), Metadata("date2", "Sep 25 10:36:28 BRST 2003"), Metadata("time2", "Sep 25 10:36:28 BRST 2003"), Metadata("datetime2", "Hello"), Metadata("url1", "http://example.com/hi?a=b#c"), Metadata("url2", "static:///path/icon.png"), Metadata("url3", "static://static/path/icon.png"), Metadata("url4", "static://cgxp/path/icon.png"), Metadata("url5", "static://project:static/path/icon.png"), Metadata("url6", "static://project:cgxp/path/icon.png"), Metadata("url7", "config://server"), Metadata("url8", "config://server/index.html"), Metadata("url9", "/dummy/static/icon.png"), Metadata("url10", "dummy/static/icon.png"), Metadata("url11", "https:///static/icon.png"), Metadata("url12", "static://test"), Metadata("url13", "static://test/"), Metadata("url14", "config:///static/icon.png"), Metadata("url15", "config://unknown_server"), Metadata("url16", "https://"), Metadata("url17", "https:///"), Metadata("url18", "https:///static"), Metadata("url19", ""), Metadata("url20", "/"), Metadata("unknown", "Hello"), ] layer_group = LayerGroup(name="__test_layer_group") layer_group.children = [layer_wms] theme = Theme(name="__test_theme") theme.interfaces = [desktop] theme.children = [layer_group] DBSession.add(theme) transaction.commit()
def _create_layer(self, exclude_properties=False, metadatas=None, geom_type=False): """ This function is central for this test class. It creates a layer with two features, and associates a restriction area to it. """ import transaction from sqlalchemy import Column, Table, types, ForeignKey from sqlalchemy.ext.declarative import declarative_base from geoalchemy2 import Geometry from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import RestrictionArea, LayerWMS self.__class__._table_index += 1 id = self.__class__._table_index engine = DBSession.c2c_rw_bind connection = engine.connect() if not self.metadata: self.metadata = declarative_base(bind=engine).metadata tablename = "geo_table_{0:d}".format(id) schemaname = "geodata" table1 = Table( "{0!s}_child".format(tablename), self.metadata, Column("id", types.Integer, primary_key=True), Column("name", types.Unicode), schema=schemaname, ) self._tables.append(table1) table2 = Table( tablename, self.metadata, Column("id", types.Integer, primary_key=True), Column( "child_id", types.Integer, ForeignKey("{0!s}.{1!s}_child.id".format( schemaname, tablename))), Column("name", types.Unicode, nullable=False), Column("deleted", types.Boolean), Column("last_update_user", types.Unicode), Column("last_update_date", types.DateTime), Column("date", types.Date), Column("start_time", types.Time), # Column("interval", Interval()), Column("short_name1", types.String, nullable=True), Column("short_name2", types.String(50), nullable=True), Column("short_number", types.Integer, nullable=True), Column("double_number", types.Float(precision=4)), Column("large_binary", types.LargeBinary(length=60), nullable=True), Column("value", types.Enum("one", "two", "three", name="an_enum_value")), Column("numeric", types.Numeric(precision=5, scale=2), nullable=True), Column("numeric2", types.Numeric(), nullable=True), schema=schemaname, ) if geom_type: table2.append_column(Column("geom", Geometry("POINT", srid=21781))) else: table2.append_column(Column("geom", Geometry(srid=21781))) self._tables.append(table2) table2.drop(checkfirst=True) table1.drop(checkfirst=True) table1.create() table2.create() ins = table1.insert().values(name="c1é") connection.execute(ins).inserted_primary_key[0] ins = table1.insert().values(name="c2é") connection.execute(ins).inserted_primary_key[0] layer = LayerWMS(name="test_WMS_1", public=True) layer.layer = "test_wms" layer.id = id layer.geo_table = "{0!s}.{1!s}".format(schemaname, tablename) layer.interfaces = [self.main] layer.ogc_server = self.ogc_server if exclude_properties: layer.exclude_properties = "name" if metadatas: layer.metadatas = metadatas DBSession.add(self.layer_group_1) self.layer_group_1.children = self.layer_group_1.children + [layer] DBSession.add(self.layer_group_1) ra = RestrictionArea() ra.name = "__test_ra" ra.layers = [layer] ra.roles = [self.role] ra.readwrite = True DBSession.add(ra) transaction.commit() self.layer_ids.append(id) return id
class Import: def __init__(self, options): self.options = options self.imported = set() settings = get_config("config.yaml") package = settings["package"] self.fts_languages = settings["fulltextsearch"]["languages"] self.languages = settings["available_locale_names"] # must be done only once we have loaded the project config from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import FullTextSearch, Interface, Theme, Role self.session = DBSession() self.session.execute(FullTextSearch.__table__.delete().where(FullTextSearch.from_theme == True)) # noqa self._ = {} for lang in self.languages: self._[lang] = translation( "{}-client".format(package), os.path.join(package, "locale/"), [lang]) query = self.session.query(Interface) if options.interfaces is not None: query = query.filter( Interface.name.in_(options.interfaces) ) self.interfaces = query.all() self.public_theme = {} self.public_group = {} for interface in self.interfaces: self.public_theme[interface.id] = [] self.public_group[interface.id] = [] for theme in self.session.query(Theme).filter_by(public=True).all(): self._add_theme(theme) for role in self.session.query(Role).all(): for theme in self.session.query(Theme).all(): self._add_theme(theme, role) transaction.commit() def _add_fts(self, item, interface, action, role): from c2cgeoportal_commons.models.main import FullTextSearch key = ( item.name if self.options.name else item.id, interface.id, role.id if role is not None else None ) if key not in self.imported: self.imported.add(key) for lang in self.languages: fts = FullTextSearch() fts.label = self._[lang].gettext(item.name) fts.role = role fts.interface = interface fts.lang = lang fts.public = role is None fts.ts = func.to_tsvector(self.fts_languages[lang], fts.label) fts.actions = [{ "action": action, "data": item.name, }] fts.from_theme = True self.session.add(fts) def _add_theme(self, theme, role=None): fill = False for interface in self.interfaces: if interface in theme.interfaces: for child in theme.children: fill = self._add_block(child, interface, role) or fill if fill and self.options.themes: if role is None: self.public_theme[interface.id].append(theme.id) if role is None or theme.id not in self.public_theme[interface.id]: self._add_fts(theme, interface, "add_theme", role) def _add_block(self, group, interface, role): return self._add_group(group, interface, self.options.blocks, role) def _add_folder(self, group, interface, role): return self._add_group(group, interface, self.options.folders, role) def _add_group(self, group, interface, export, role): from c2cgeoportal_commons.models.main import LayerGroup fill = False for child in group.children: if isinstance(child, LayerGroup): fill = self._add_folder(child, interface, role) or fill else: fill = self._add_layer(child, interface, role) or fill if fill and export: if role is None: self.public_group[interface.id].append(group.id) if role is None or group.id not in self.public_group[interface.id]: self._add_fts(group, interface, "add_group", role) return fill @staticmethod def _layer_visible(layer, role): for restrictionarea in layer.restrictionareas: if role in restrictionarea.roles: return True return False def _add_layer(self, layer, interface, role): from c2cgeoportal_commons.models.main import LayerV1 if isinstance(layer, LayerV1): return False if role is None: fill = layer.public and interface in layer.interfaces else: fill = interface in layer.interfaces and not layer.public and \ self._layer_visible(layer, role) if fill and self.options.layers: self._add_fts(layer, interface, "add_layer", role) return fill
def create(self): if "url" not in self.request.params: raise HTTPBadRequest("The parameter url is required") url = self.request.params["url"] # see: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline if len(url) > 8190: # pragma: no cover raise HTTPBadRequest( "The parameter url is too long ({} > {})".format( len(url), 8190)) # Check that it is an internal URL... uri_parts = urlparse(url) hostname = uri_parts.hostname if "allowed_hosts" in self.settings: if hostname not in self.settings[ "allowed_hosts"]: # pragma: no cover raise HTTPBadRequest("The requested host is not allowed.") else: if hostname != self.request.server_name: raise HTTPBadRequest( "The requested host '{0!s}' should be '{1!s}'".format( hostname, self.request.server_name)) shortened = False for base in self.short_bases: base_parts = urlparse(base) if uri_parts.path.startswith(base_parts.path): shortened = True ref = uri_parts.path.split("/")[-1] tries = 0 while not shortened: ref = "".join( random.choice(string.ascii_letters + string.digits) for i in range(self.settings.get("length", 4))) test_url = DBSession.query(Shorturl).filter( Shorturl.ref == ref).all() if len(test_url) == 0: break tries += 1 # pragma: no cover if tries > 20: # pragma: no cover message = "No free ref found, considere to increase the length" logging.error(message) raise HTTPInternalServerError(message) user_email = self.request.user.email \ if self.request.user is not None else None email = self.request.params.get("email") if not shortened: short_url = Shorturl() short_url.url = url short_url.ref = ref short_url.creator_email = user_email short_url.creation = datetime.now() short_url.nb_hits = 0 DBSession.add(short_url) if "base_url" in self.settings: s_url = self.settings["base_url"] + ref else: s_url = self.request.route_url("shortener_get", ref=ref) email = email or user_email if email is not None: # pragma: no cover send_email_config( self.request.registry.settings, "shortener", email, full_url=url, short_url=s_url, message=self.request.params.get("message", ""), ) set_common_headers(self.request, "shortener", NO_CACHE) return {"short_url": s_url}
def lux_report_create(self): token = self.config["authtkt_secret"] print_servers = DBSession.query(LuxPrintServers).all() if os.environ.get('FAKE_PRINT_URLS'): print_urls = os.environ.get('FAKE_PRINT_URLS').split(',') else: print_urls = [print_server.url for print_server in print_servers] urllib.request.getproxies = lambda: {} valid_print_urls = [] if print_urls is not None and len(print_urls) > 0: for url in print_urls: try: test_url = url.replace("/print/geoportailv3", "") urllib.request.urlopen(test_url) valid_print_urls.append(url) except Exception as e: log.exception(e) log.error("Print server not available : " + url) print_url = valid_print_urls[random.randint( 0, len(valid_print_urls) - 1)] else: print_url = self.config["print_url"] spec = json.loads( self.request.body.decode("utf-8").replace( ".app.geoportail", ".geoportail").replace("vectortiles.geoportail.lu", "vectortiles-print.geoportail.lu")) for map_layer in spec["attributes"]["map"]["layers"]: if "baseURL" in map_layer and\ "ogcproxywms" in map_layer["baseURL"]: if "customParams" in map_layer: map_layer["customParams"]["GP_TOKEN"] = token else: map_layer["customParams"] = {"GP_TOKEN": token} if self.request.user and\ self.request.user.ogc_role is not None and\ self.request.user.ogc_role != -1: if "customParams" in map_layer: map_layer["customParams"]["roleOGC"] =\ str(self.request.user.ogc_role) else: map_layer["customParams"] =\ {"roleOGC": str(self.request.user.ogc_role)} for layer in map_layer["layers"]: internal_wms = DBSession.query(LuxLayerInternalWMS).filter( LuxLayerInternalWMS.layer == layer).first() if internal_wms is not None and\ not self._is_authorized(internal_wms): return HTTPUnauthorized() if "longUrl" in spec["attributes"]: opener = urllib.request.build_opener(urllib.request.HTTPHandler()) data = urllib.parse.urlencode( {"url": spec["attributes"]["longUrl"]}) content = opener.open("https://map.geoportail.lu/short/create", data=data.encode('utf-8')).read() shortner = json.loads(content) spec["attributes"]["url"] = shortner["short_url"] spec["attributes"]["qrimage"] =\ "https://map.geoportail.lu/main/wsgi/qr?url=" + \ spec["attributes"]["url"] job = LuxPrintJob() job.spec = json.dumps(spec) if "longUrl" in spec["attributes"]: spec["attributes"].pop('longUrl', None) if "firstPagesUrls" in spec["attributes"]: spec["attributes"].pop('firstPagesUrls', None) self.request.body = str.encode(json.dumps(spec)) resp, content = self._proxy( "%s/report.%s" % (print_url, self.request.matchdict.get("format"))) job.id = json.loads(content)["ref"] job.print_url = print_url job.creation = datetime.now() DBSession.add(job) return self._build_response(resp, content, False, "print")
def create(self) -> Dict[str, str]: if "url" not in self.request.params: raise HTTPBadRequest("The parameter url is required") url = self.request.params["url"] # see: https://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline if len(url) > 8190: raise HTTPBadRequest( f"The parameter url is too long ({len(url)} > {8190})") # Check that it is an internal URL... uri_parts = urlparse(url) if "allowed_hosts" in self.settings: if uri_parts.netloc not in self.settings["allowed_hosts"]: raise HTTPBadRequest( f"The requested host '{uri_parts.netloc}' is not part of allowed hosts: " f"{', '.join(self.settings['allowed_hosts'])}") else: hostname = uri_parts.hostname if hostname != self.request.server_name: raise HTTPBadRequest( f"The requested host '{hostname!s}' should be '{self.request.server_name!s}'" ) shortened = False for base in self.short_bases: base_parts = urlparse(base) if uri_parts.path.startswith(base_parts.path): shortened = True ref = uri_parts.path.split("/")[-1] tries = 0 while not shortened: ref = "".join( random.choice(string.ascii_letters + string.digits) # nosec for i in range(self.settings.get("length", 4))) test_url = DBSession.query(Shorturl).filter( Shorturl.ref == ref).all() if not test_url: break tries += 1 if tries > 20: message = "No free ref found, considered to increase the length" logger.error(message) raise HTTPInternalServerError(message) user_email = self.request.user.email if self.request.user is not None else None email = self.request.params.get("email") if not shortened: short_url = Shorturl() short_url.url = url short_url.ref = ref short_url.creator_email = user_email short_url.creation = datetime.now() short_url.nb_hits = 0 DBSession.add(short_url) if "base_url" in self.settings: s_url = self.settings["base_url"] + ref else: s_url = self.request.route_url("shortener_get", ref=ref) if email is not None: send_email_config( self.request.registry.settings, "shortener", email, full_url=url, short_url=s_url, message=self.request.params.get("message", ""), application_url=self.request.route_url("base"), current_url=self.request.current_route_url(), ) set_common_headers(self.request, "shortener", Cache.PRIVATE_NO) return {"short_url": s_url}
class Import: def __init__(self, options): self.options = options self.imported = set() settings = get_config("config.yaml") package = settings["package"] self.fts_languages = settings["fulltextsearch"]["languages"] self.languages = settings["available_locale_names"] # must be done only once we have loaded the project config from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import FullTextSearch, Interface, Theme, Role self.session = DBSession() self.session.execute(FullTextSearch.__table__.delete().where( FullTextSearch.from_theme == True)) # noqa self._ = {} for lang in self.languages: self._[lang] = translation("{}-client".format(package), os.path.join(package, "locale/"), [lang]) query = self.session.query(Interface) if options.interfaces is not None: query = query.filter(Interface.name.in_(options.interfaces)) self.interfaces = query.all() self.public_theme = {} self.public_group = {} for interface in self.interfaces: self.public_theme[interface.id] = [] self.public_group[interface.id] = [] for theme in self.session.query(Theme).filter_by(public=True).all(): self._add_theme(theme) for role in self.session.query(Role).all(): for theme in self.session.query(Theme).all(): self._add_theme(theme, role) transaction.commit() def _add_fts(self, item, interface, action, role): from c2cgeoportal_commons.models.main import FullTextSearch key = (item.name if self.options.name else item.id, interface.id, role.id if role is not None else None) if key not in self.imported: self.imported.add(key) for lang in self.languages: fts = FullTextSearch() fts.label = self._unicode_str(self._[lang].gettext(item.name)) fts.role = role fts.interface = interface fts.lang = lang fts.public = role is None fts.ts = func.to_tsvector(self.fts_languages[lang], fts.label) fts.actions = [{ "action": action, "data": item.name, }] fts.from_theme = True self.session.add(fts) def _add_theme(self, theme, role=None): fill = False for interface in self.interfaces: if interface in theme.interfaces: for child in theme.children: fill = self._add_block(child, interface, role) or fill if fill and self.options.themes: if role is None: self.public_theme[interface.id].append(theme.id) if role is None or theme.id not in self.public_theme[ interface.id]: self._add_fts(theme, interface, "add_theme", role) def _add_block(self, group, interface, role): return self._add_group(group, interface, self.options.blocks, role) def _add_folder(self, group, interface, role): return self._add_group(group, interface, self.options.folders, role) def _add_group(self, group, interface, export, role): from c2cgeoportal_commons.models.main import LayerGroup fill = False for child in group.children: if isinstance(child, LayerGroup): fill = self._add_folder(child, interface, role) or fill else: fill = self._add_layer(child, interface, role) or fill if fill and export: if role is None: self.public_group[interface.id].append(group.id) if role is None or group.id not in self.public_group[interface.id]: self._add_fts(group, interface, "add_group", role) return fill @staticmethod def _layer_visible(layer, role): for restrictionarea in layer.restrictionareas: if role in restrictionarea.roles: return True return False def _add_layer(self, layer, interface, role): from c2cgeoportal_commons.models.main import LayerV1 if isinstance(layer, LayerV1): return False if role is None: fill = layer.public and interface in layer.interfaces else: fill = interface in layer.interfaces and not layer.public and \ self._layer_visible(layer, role) if fill and self.options.layers: self._add_fts(layer, interface, "add_layer", role) return fill @staticmethod def _unicode_str(string): return string.decode('utf-8') if isinstance(string, str) else string
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import \ Theme, LayerGroup, Interface, LayerWMS, LayerWMTS, Dimension ogc_server, _ = create_default_ogcserver() main = Interface(name="main") layer_wms_1 = LayerWMS(name="__test_layer_wms_1", public=True) layer_wms_1.layer = "__test_layer_wms_1" layer_wms_1.interfaces = [main] layer_wms_1.ogc_server = ogc_server Dimension("A", "a", layer_wms_1) layer_wms_2 = LayerWMS(name="__test_layer_wms_2", public=True) layer_wms_2.layer = "__test_layer_wms_2" layer_wms_2.interfaces = [main] layer_wms_2.ogc_server = ogc_server Dimension("A", "b", layer_wms_2) layer_wms_3 = LayerWMS(name="__test_layer_wms_3", public=True) layer_wms_3.layer = "__test_layer_wms_3" layer_wms_3.interfaces = [main] layer_wms_3.ogc_server = ogc_server Dimension("A", None, layer_wms_3) layer_wms_4 = LayerWMS(name="__test_layer_wms_4", public=True) layer_wms_4.layer = "__test_layer_wms_4" layer_wms_4.interfaces = [main] layer_wms_4.ogc_server = ogc_server Dimension("A", "a", layer_wms_4) layer_wms_5 = LayerWMS(name="__test_layer_wms_5", public=True) layer_wms_5.layer = "__test_layer_wms_5" layer_wms_5.interfaces = [main] layer_wms_5.ogc_server = ogc_server Dimension("B", "b", layer_wms_5) layer_wms_6 = LayerWMS(name="__test_layer_wms_6", public=True) layer_wms_6.layer = "__test_layer_wms_6" layer_wms_6.interfaces = [main] layer_wms_6.ogc_server = ogc_server Dimension("FILTER", "countries:\"name\" IN ( 'Germany' , 'Italy' )", layer_wms_6) layer_wmts = LayerWMTS(name="__test_layer_wmts", public=True) layer_wmts.url = "http://example.com/1.0.0/WMTSCapabilities.xml" layer_wmts.layer = "map" layer_wmts.interfaces = [main] Dimension("B", "b", layer_wmts) layer_wmts_2 = LayerWMTS(name="__test_layer_wmts_2", public=True) layer_wmts_2.url = "http://example.com/1.0.0/WMTSCapabilities.xml" layer_wmts_2.layer = "map" layer_wmts_2.interfaces = [main] Dimension("FILTER", "countries:\"name\" IN ( 'Germany' , 'Italy' )", layer_wmts_2) layer_group_1 = LayerGroup(name="__test_layer_group_1") layer_group_1.children = [layer_wms_1, layer_wmts, layer_wmts_2] layer_group_2 = LayerGroup(name="__test_layer_group_2") layer_group_2.children = [layer_wms_1, layer_wms_2] layer_group_3 = LayerGroup(name="__test_layer_group_3") layer_group_3.children = [layer_wms_1, layer_wms_3] layer_group_4 = LayerGroup(name="__test_layer_group_4") layer_group_4.children = [layer_wms_1, layer_wms_4] layer_group_5 = LayerGroup(name="__test_layer_group_5") layer_group_5.children = [layer_wms_1, layer_wms_5, layer_wms_6] layer_group_6 = LayerGroup(name="__test_layer_group_6") layer_group_6.children = [layer_wms_3] theme = Theme(name="__test_theme") theme.interfaces = [main] theme.children = [ layer_group_1, layer_group_2, layer_group_3, layer_group_4, layer_group_5, layer_group_6, ] DBSession.add(theme) transaction.commit()
def _create_layer( self, public=False, none_area=False, attr_list=False, exclude_properties=False, metadatas=None, geom_type=False, ): """This function is central for this test class. It creates a layer with two features, and associates a restriction area to it.""" import transaction from geoalchemy2 import Geometry, WKTElement from sqlalchemy import CheckConstraint, Column, ForeignKey, Table, types from sqlalchemy.ext.declarative import declarative_base from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import LayerWMS, OGCServer, RestrictionArea if self._tables is None: self._tables = [] self.__class__._table_index += 1 id = self.__class__._table_index engine = DBSession.c2c_rw_bind connection = engine.connect() if not self.metadata: self.metadata = declarative_base(bind=engine).metadata tablename = "table_{0:d}".format(id) table1 = Table( "{0!s}_child".format(tablename), self.metadata, Column("id", types.Integer, primary_key=True), Column("name", types.Unicode), schema="public", ) if geom_type: table1.append_column(Column("geom", Geometry("POINT", srid=21781))) else: table1.append_column(Column("geom", Geometry(srid=21781))) self._tables.append(table1) table2 = Table( tablename, self.metadata, Column("id", types.Integer, primary_key=True), Column("child_id", types.Integer, ForeignKey("public.{0!s}_child.id".format(tablename))), Column("name", types.Unicode), Column( "email", types.Unicode, CheckConstraint( """email ~* '^[A-Za-z0-9._%%-] +@[A-Za-z0-9.-]+[.][A-Za-z]+$'""", name="proper_email", ), ), Column("last_update_user", types.Unicode), Column("last_update_date", types.DateTime), schema="public", ) if geom_type: table2.append_column(Column("geom", Geometry("POINT", srid=21781))) else: table2.append_column(Column("geom", Geometry(srid=21781))) self._tables.append(table2) table1.drop(checkfirst=True) table2.drop(checkfirst=True) table1.create() table2.create() ins = table1.insert().values(name="c1é") c1_id = connection.execute(ins).inserted_primary_key[0] ins = table1.insert().values(name="c2é") c2_id = connection.execute(ins).inserted_primary_key[0] ins = table2.insert().values(child_id=c1_id, name="foo", geom=WKTElement("POINT(5 45)", 21781)) connection.execute(ins) ins = table2.insert().values(child_id=c2_id, name="bar", geom=WKTElement("POINT(6 46)", 21781)) connection.execute(ins) if attr_list: ins = table2.insert().values(child_id=c2_id, name="aaa,bbb,foo", geom=WKTElement("POINT(6 46)", 21781)) connection.execute(ins) ogc_server = DBSession.query(OGCServer).filter( OGCServer.name == "__test_ogc_server").one() layer = LayerWMS() layer.id = id layer.name = str(id) layer.ogc_server = ogc_server layer.geo_table = tablename layer.public = public layer.interface = [self.main] if exclude_properties: layer.exclude_properties = "name" if metadatas: layer.metadatas = metadatas DBSession.add(layer) if not public: ra = RestrictionArea() ra.name = "__test_ra" ra.layers = [layer] ra.roles = [self.role] ra.readwrite = True if not none_area: poly = "POLYGON((4 44, 4 46, 6 46, 6 44, 4 44))" ra.area = WKTElement(poly, srid=21781) DBSession.add(ra) transaction.commit() self.layer_ids.append(id) return id
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Theme, LayerGroup, Interface, LayerWMS, Metadata desktop = Interface(name="desktop") ogc_server_internal = create_default_ogcserver() layer_wms = LayerWMS(name="__test_layer_internal_wms", public=True) layer_wms.layer = "__test_layer_internal_wms" layer_wms.ogc_server = ogc_server_internal layer_wms.interfaces = [desktop] layer_wms.metadatas = [ Metadata("string", "string"), Metadata("list", "1, 2, a"), Metadata("boolean", "y"), Metadata("boolean2", "no"), Metadata("boolean3", "Hello"), Metadata("integer", "1"), Metadata("float", "5.5"), Metadata("json", '{"test": 123}'), Metadata("json_wrong", '{"test": 123'), Metadata("date", "Sep 25 2003"), Metadata("time", "10:36:28"), Metadata("datetime", "Sep 25 10:36:28 BRST 2003"), Metadata("date2", "Sep 25 10:36:28 BRST 2003"), Metadata("time2", "Sep 25 10:36:28 BRST 2003"), Metadata("datetime2", "Hello"), Metadata("url1", "http://example.com/hi?a=b#c"), Metadata("url2", "static:///path/icon.png"), Metadata("url3", "static://static/path/icon.png"), Metadata("url4", "static://cgxp/path/icon.png"), Metadata("url5", "static://project:static/path/icon.png"), Metadata("url6", "static://project:cgxp/path/icon.png"), Metadata("url7", "config://server"), Metadata("url8", "config://server/index.html"), Metadata("url9", "/dummy/static/icon.png"), Metadata("url10", "dummy/static/icon.png"), Metadata("url11", "https:///static/icon.png"), Metadata("url12", "static://test"), Metadata("url13", "static://test/"), Metadata("url14", "config:///static/icon.png"), Metadata("url15", "config://unknown_server"), Metadata("url16", "https://"), Metadata("url17", "https:///"), Metadata("url18", "https:///static"), Metadata("url19", ""), Metadata("url20", "/"), Metadata("unknown", "Hello"), ] layer_group = LayerGroup(name="__test_layer_group") layer_group.children = [layer_wms] theme = Theme(name="__test_theme") theme.interfaces = [desktop] theme.children = [layer_group] DBSession.add(theme) transaction.commit()
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import ( Dimension, Interface, LayerGroup, LayerWMS, LayerWMTS, Theme, ) ogc_server = create_default_ogcserver() main = Interface(name="main") layer_wms_1 = LayerWMS(name="__test_layer_wms_1", public=True) layer_wms_1.layer = "testpoint_unprotected" layer_wms_1.interfaces = [main] layer_wms_1.ogc_server = ogc_server Dimension("A", "a", layer_wms_1) layer_wms_2 = LayerWMS(name="__test_layer_wms_2", public=True) layer_wms_2.layer = "testpoint_unprotected" layer_wms_2.interfaces = [main] layer_wms_2.ogc_server = ogc_server Dimension("A", "b", layer_wms_2) layer_wms_3 = LayerWMS(name="__test_layer_wms_3", public=True) layer_wms_3.layer = "testpoint_unprotected" layer_wms_3.interfaces = [main] layer_wms_3.ogc_server = ogc_server Dimension("A", None, layer_wms_3) layer_wms_4 = LayerWMS(name="__test_layer_wms_4", public=True) layer_wms_4.layer = "testpoint_unprotected" layer_wms_4.interfaces = [main] layer_wms_4.ogc_server = ogc_server Dimension("A", "a", layer_wms_4) layer_wms_5 = LayerWMS(name="__test_layer_wms_5", public=True) layer_wms_5.layer = "testpoint_unprotected" layer_wms_5.interfaces = [main] layer_wms_5.ogc_server = ogc_server Dimension("B", "b", layer_wms_5) layer_wms_6 = LayerWMS(name="__test_layer_wms_6", public=True) layer_wms_6.layer = "testpoint_unprotected" layer_wms_6.interfaces = [main] layer_wms_6.ogc_server = ogc_server Dimension("FILTER", "countries:\"name\" IN ( 'Germany' , 'Italy' )", layer_wms_6) layer_wms_7 = LayerWMS(name="__test_layer_wms_7", public=True) layer_wms_7.layer = "testpoint_unprotected" layer_wms_7.interfaces = [main] layer_wms_7.ogc_server = ogc_server Dimension("FLOOR", None, layer_wms_7, "floor") layer_wmts = LayerWMTS(name="__test_layer_wmts", public=True) layer_wmts.url = "http://tilecloudchain/1.0.0/WMTSCapabilities.xml" layer_wmts.layer = "map" layer_wmts.interfaces = [main] Dimension("B", "b", layer_wmts) layer_wmts_2 = LayerWMTS(name="__test_layer_wmts_2", public=True) layer_wmts_2.url = "http://tilecloudchain/1.0.0/WMTSCapabilities.xml" layer_wmts_2.layer = "map" layer_wmts_2.interfaces = [main] Dimension("FILTER", "countries:\"name\" IN ( 'Germany' , 'Italy' )", layer_wmts_2) layer_group_1 = LayerGroup(name="__test_layer_group_1") layer_group_1.children = [layer_wms_1, layer_wmts, layer_wmts_2] layer_group_2 = LayerGroup(name="__test_layer_group_2") layer_group_2.children = [layer_wms_1, layer_wms_2] layer_group_3 = LayerGroup(name="__test_layer_group_3") layer_group_3.children = [layer_wms_1, layer_wms_3] layer_group_4 = LayerGroup(name="__test_layer_group_4") layer_group_4.children = [layer_wms_1, layer_wms_4] layer_group_5 = LayerGroup(name="__test_layer_group_5") layer_group_5.children = [layer_wms_1, layer_wms_5, layer_wms_6] layer_group_6 = LayerGroup(name="__test_layer_group_6") layer_group_6.children = [layer_wms_3] layer_group_7 = LayerGroup(name="__test_layer_group_7") layer_group_7.children = [layer_wms_7] theme = Theme(name="__test_theme") theme.interfaces = [main] theme.children = [ layer_group_1, layer_group_2, layer_group_3, layer_group_4, layer_group_5, layer_group_6, layer_group_7, ] DBSession.add(theme) transaction.commit()
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Theme, LayerGroup, Interface, OGCServer, LayerWMS, LayerWMTS main = Interface(name="main") ogc_server_internal, _ = create_default_ogcserver() ogc_server_external = OGCServer(name="__test_ogc_server_external", url="http://wms.geo.admin.ch/", image_type="image/jpeg") layer_internal_wms = LayerWMS(name="__test_layer_internal_wms", public=True) layer_internal_wms.layer = "__test_layer_internal_wms" layer_internal_wms.interfaces = [main] layer_internal_wms.ogc_server = ogc_server_internal layer_external_wms = LayerWMS(name="__test_layer_external_wms", layer="ch.swisstopo.dreiecksvermaschung", public=True) layer_external_wms.interfaces = [main] layer_external_wms.ogc_server = ogc_server_external layer_wmts = LayerWMTS(name="__test_layer_wmts", public=True) layer_wmts.url = "http://example.com/1.0.0/WMTSCapabilities.xml" layer_wmts.layer = "map" layer_wmts.interfaces = [main] layer_group_1 = LayerGroup(name="__test_layer_group_1") layer_group_1.children = [layer_internal_wms] layer_group_2 = LayerGroup(name="__test_layer_group_2") layer_group_2.children = [layer_external_wms] layer_group_3 = LayerGroup(name="__test_layer_group_3") layer_group_3.children = [layer_wmts] layer_group_4 = LayerGroup(name="__test_layer_group_4") layer_group_4.children = [layer_group_1, layer_group_2] layer_group_5 = LayerGroup(name="__test_layer_group_5") layer_group_5.children = [layer_group_1, layer_group_3] layer_group_6 = LayerGroup(name="__test_layer_group_6") layer_group_6.children = [layer_internal_wms] layer_group_7 = LayerGroup(name="__test_layer_group_7") layer_group_7.children = [layer_group_1, layer_group_6] layer_group_8 = LayerGroup(name="__test_layer_group_8") layer_group_8.children = [layer_group_2, layer_group_6] theme = Theme(name="__test_theme") theme.interfaces = [main] theme.children = [ layer_group_1, layer_group_2, layer_group_3, layer_group_4, layer_group_5, layer_group_7, layer_group_8, ] DBSession.add(theme) transaction.commit()