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, _): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Role, LayerWMS, RestrictionArea, Interface from c2cgeoportal_commons.models.static import User ogc_server_internal, _ = create_default_ogcserver() user1 = User(username="******", password="******") role1 = Role(name="__test_role1", description="__test_role1") user1.role_name = role1.name user1.email = "Tarenpion" main = Interface(name="main") layer1 = LayerWMS("testpoint_group_name", public=False) layer1.layer = "testpoint_group" layer1.ogc_server = ogc_server_internal layer1.interfaces = [main] layer2 = LayerWMS("testpoint_protected_2_name", public=False) layer2.layer = "testpoint_protected_2" layer2.ogc_server = ogc_server_internal layer2.interfaces = [main] area = "POLYGON((-100 30, -100 50, 100 50, 100 30, -100 30))" area = WKTElement(area, srid=21781) restricted_area1 = RestrictionArea("__test_ra1", "", [layer1, layer2], [role1], area) DBSession.add_all([user1, role1, layer1, layer2, restricted_area1]) DBSession.flush() transaction.commit()
def setup_method(self, _): import transaction from sqlalchemy import func from geoalchemy2 import WKTElement from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import FullTextSearch, Role, Interface from c2cgeoportal_commons.models.static import User user1 = User(username="******", password="******") role1 = Role(name="__test_role1", description="__test_role1") user1.role_name = role1.name user2 = User(username="******", password="******") role2 = Role(name="__test_role2", description="__test_role2") user2.role_name = role2.name entry1 = FullTextSearch() entry1.label = "label1" entry1.layer_name = "layer1" entry1.ts = func.to_tsvector("french", "soleil travail") entry1.the_geom = WKTElement("POINT(-90 -45)", 21781) entry1.public = True entry2 = FullTextSearch() entry2.label = "label2" entry2.layer_name = "layer2" entry2.ts = func.to_tsvector("french", "pluie semaine") entry2.the_geom = WKTElement("POINT(-90 -45)", 21781) entry2.public = False entry3 = FullTextSearch() entry3.label = "label3" entry3.layer_name = "layer3" entry3.ts = func.to_tsvector("french", "vent neige") entry3.the_geom = WKTElement("POINT(-90 -45)", 21781) entry3.public = False entry3.role = role2 entry4 = FullTextSearch() entry4.label = "label4" entry4.layer_name = "layer1" entry4.ts = func.to_tsvector("french", "soleil travail") entry4.the_geom = WKTElement("POINT(-90 -45)", 21781) entry4.public = True entry5 = FullTextSearch() entry5.label = "label5" entry5.ts = func.to_tsvector("french", "params") entry5.public = True entry5.params = {"floor": 5} entry5.actions = [{"action": "add_layer", "data": "layer1"}] entry6 = FullTextSearch() entry6.label = "label6" entry6.ts = func.to_tsvector("french", "params") entry6.interface = Interface("main") entry6.public = True DBSession.add_all([user1, user2, role1, role2, entry1, entry2, entry3, entry4, entry5, entry6]) transaction.commit()
def setup_method(self, _): import transaction from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Role, Functionality from c2cgeoportal_commons.models.static import User create_default_ogcserver() role1 = Role(name="__test_role1") user1 = User( username="******", password="******", role=role1 ) role2 = Role(name="__test_role2") user2 = User( username="******", password="******", role=role2 ) functionality1 = Functionality("__test_s", "db") functionality2 = Functionality("__test_a", "db1") functionality3 = Functionality("__test_a", "db2") role2.functionalities = [functionality1, functionality2, functionality3] DBSession.add_all([user1, user2, role1, role2]) transaction.commit()
def get_private_layers(ogc_server_ids): q = DBSession.query(LayerWMS) \ .filter(LayerWMS.public.is_(False)) \ .join(LayerWMS.ogc_server) \ .filter(OGCServer.id.in_(ogc_server_ids)) results = q.all() DBSession.expunge_all() return {r.id: r for r in results}
def teardown_method(self, _): testing.tearDown() from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import Shorturl import transaction DBSession.query(Shorturl).delete() transaction.commit()
def teardown_method(self, _): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User DBSession.query(User).filter(User.username == "__test_user1").delete() transaction.commit() pyramid.security.remember = None pyramid.security.remember = self.old_remember
def get_ogcserver_byname(self, name): try: result = DBSession.query(OGCServer).filter(OGCServer.name == name).one() DBSession.expunge(result) return result except NoResultFound: # pragma nocover log.error("OGSServer '{}' does not exists (existing: {}).".format( name, ",".join([t[0] for t in DBSession.query(OGCServer.name).all()]))) raise
def teardown_method(self, _): import transaction from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Role from c2cgeoportal_commons.models.static import User transaction.commit() DBSession.query(User).filter_by(username="******").delete() DBSession.query(Role).filter_by(name="__test_role").delete() transaction.commit()
def setUp(self): # noqa # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None self.clean() from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from c2cgeoportal_commons.models.main import \ Theme, LayerGroup, Interface, LayerWMS, LayerWMTS, Role, RestrictionArea main = Interface(name=u"desktop") role = Role(name=u"__test_role") user = User(username=u"__test_user", password=u"__test_user", role=role) user.email = "*****@*****.**" ogc_server_internal, _ = create_default_ogcserver() layer_wms = LayerWMS(name=u"__test_layer_wms", public=True) layer_wms.layer = "__test_public_layer" layer_wms.interfaces = [main] layer_wms.ogc_server = ogc_server_internal layer_wms_private = LayerWMS(name=u"__test_layer_wms_private", public=True) layer_wms_private.layer = "__test_private_layer" layer_wms_private.public = False layer_wms_private.interfaces = [main] layer_wms_private.ogc_server = ogc_server_internal layer_wmts = LayerWMTS(name=u"__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_wmts_private = LayerWMTS(name=u"__test_layer_wmts_private", public=True) layer_wmts_private.url = "http://example.com/1.0.0/WMTSCapabilities.xml" layer_wmts_private.layer = "map" layer_wmts_private.public = False layer_wmts_private.interfaces = [main] layer_group = LayerGroup(name=u"__test_layer_group") layer_group.children = [layer_wms, layer_wms_private, layer_wmts, layer_wmts_private] theme = Theme(name=u"__test_theme") theme.interfaces = [main] theme.children = [layer_group] restriction_area = RestrictionArea( name=u"__test_ra1", layers=[layer_wms_private, layer_wmts_private], roles=[role] ) DBSession.add_all([theme, restriction_area, user]) transaction.commit()
def setup_method(self, _): import transaction from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Role from c2cgeoportal_commons.models.static import User r = Role(name="__test_role") u = User( username="******", password="******", role=r ) DBSession.add_all([u, r]) 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 main = Interface(name="desktop") ogc_server, _ = create_default_ogcserver() layer_noscale = LayerWMS(name="__test_layer_noscale", public=True) layer_noscale.layer = "test_noscale" layer_noscale.interfaces = [main] layer_noscale.ogc_server = ogc_server layer_minscale = LayerWMS(name="__test_layer_minscale", public=True) layer_minscale.layer = "test_minscale" layer_minscale.interfaces = [main] layer_minscale.ogc_server = ogc_server layer_maxscale = LayerWMS(name="__test_layer_maxscale", public=True) layer_maxscale.layer = "test_maxscale" layer_maxscale.interfaces = [main] layer_maxscale.ogc_server = ogc_server layer_boothscale = LayerWMS(name="__test_layer_boothscale", public=True) layer_boothscale.layer = "test_boothscale" layer_boothscale.interfaces = [main] layer_boothscale.ogc_server = ogc_server layer_metadatascale = LayerWMS(name="__test_layer_metadatascale", public=True) layer_metadatascale.layer = "test_boothscale" layer_metadatascale.interfaces = [main] layer_metadatascale.ogc_server = ogc_server layer_metadatascale.metadatas = [ Metadata("minResolution", "100"), Metadata("maxResolution", "1000"), ] layer_group = LayerGroup(name="__test_layer_group") layer_group.children = [layer_noscale, layer_minscale, layer_maxscale, layer_boothscale, layer_metadatascale] theme = Theme(name="__test_theme") theme.interfaces = [main] theme.children = [layer_group] DBSession.add_all([theme]) transaction.commit()
def test_private(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User entry = self._create_entry_obj(params={ "version": "2" }, user=DBSession.query(User).filter_by(username=u"__test_user").one()) themes = entry.themes() self.assertEquals(themes["errors"], []) self.assertEquals( [self._only_name(t) for t in themes["themes"]], [{ "name": u"__test_theme", "children": [{ "name": u"__test_layer_group", "children": [{ "name": u"__test_layer_wms" }, { "name": u"__test_layer_wms_private" }, { "name": u"__test_layer_wmts" }, { "name": u"__test_layer_wmts_private" }] }] }] )
def _import_layer_wmts(self, layer, messages): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import OGCServer layers = [d.value for d in layer.metadatas if d.name == "queryLayers"] if len(layers) == 0: layers = [d.value for d in layer.metadatas if d.name == "wmsLayer"] server = [d.value for d in layer.metadatas if d.name == "ogcServer"] if len(server) >= 1 and len(layers) >= 1: for wms_layer in layers: try: db_server = DBSession.query(OGCServer).filter(OGCServer.name == server[0]).one() self._import_layer_attributes( db_server.url_wfs or db_server.url, wms_layer, layer.item_type, layer.name, messages ) except NoResultFound: print(colorize( "ERROR! the OGC server '{}' from the WMTS layer '{}' does not exist.".format( server[0], layer.name ), RED )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise
def test_group_update(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import LayerGroup layer_group_3 = DBSession.query(LayerGroup).filter(LayerGroup.name == "__test_layer_group_3").one() layer_group_3.children = layer_group_3.children[:-1] transaction.commit() entry = self._create_entry_obj(params={ "version": "2", "group": "__test_layer_group_3", "catalogue": "true", }) themes = entry.themes() self.assertEqual(self._get_filtered_errors(themes), set()) self.assertEqual( self._only_name(themes["group"]), { "name": "__test_layer_group_3", # order is important "children": [{ "name": "__test_layer_wmts" }, { "name": "__test_layer_internal_wms" }] } )
def _create_getcap_request(username=None): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User request = create_dummy_request() request.user = None if username is None else \ DBSession.query(User).filter_by(username=username).one() return request
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 teardown_method(self, _): testing.tearDown() from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import TreeItem, Interface, Dimension, OGCServer DBSession.query(Dimension).delete() for item in DBSession.query(TreeItem).all(): DBSession.delete(item) DBSession.query(Interface).filter( Interface.name == "main" ).delete() DBSession.query(OGCServer).delete() transaction.commit()
def default_user_validator(request, username, password): """ Validate the username/password. This is c2cgeoportal's default user validator. Return none if we are anonymous, the string to remember otherwise. """ from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = DBSession.query(User).filter_by(username=username).first() return username if user and user.validate_password(password) else None
def _get_layers_query(role_id, what): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Layer, RestrictionArea, Role q = DBSession.query(what) q = q.join(Layer.restrictionareas) q = q.join(RestrictionArea.roles) q = q.filter(Role.id == role_id) return q
def test_web_client_functionalities(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from tests.functional import create_dummy_request from c2cgeoportal_geoportal.views.entry import Entry request = create_dummy_request() request.static_url = lambda url: "http://example.com/dummy/static/url" request1 = create_dummy_request() request1.static_url = lambda url: "http://example.com/dummy/static/url" request1.user = DBSession.query(User).filter(User.username == "__test_user1").one() request2 = create_dummy_request() request2.static_url = lambda url: "http://example.com/dummy/static/url" request2.user = DBSession.query(User).filter(User.username == "__test_user2").one() settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] }, "available_in_templates": ["__test_s", "__test_a"], }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] }, } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) annon = Entry(request).get_cgxp_viewer_vars() u1 = Entry(request1).get_cgxp_viewer_vars() u2 = Entry(request2).get_cgxp_viewer_vars() self.assertEqual(annon["functionality"], {"__test_s": ["anonymous"], "__test_a": ["a1", "a2"]}) self.assertEqual(u1["functionality"], {"__test_s": ["registered"], "__test_a": ["r1", "r2"]}) self.assertEqual(u2["functionality"], {"__test_s": ["db"], "__test_a": ["db1", "db2"]})
def setup_method(self, _): # Always see the diff # https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff self.maxDiff = None cleanup_db() self._tables = [] import transaction from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Role, Interface, TreeItem, Theme, \ LayerGroup, OGCSERVER_AUTH_NOAUTH from c2cgeoportal_commons.models.static import User for treeitem in DBSession.query(TreeItem).all(): DBSession.delete(treeitem) self.role = Role(name="__test_role") self.user = User( username="******", password="******", role=self.role ) self.main = Interface(name="main") self.ogc_server, external_ogc_server = create_default_ogcserver() self.ogc_server.auth = OGCSERVER_AUTH_NOAUTH external_ogc_server.auth = OGCSERVER_AUTH_NOAUTH self.metadata = None self.layer_ids = [] self.layer_group_1 = LayerGroup(name="__test_layer_group_1") theme = Theme(name="__test_theme") theme.interfaces = [self.main] theme.children = [self.layer_group_1] DBSession.add_all([self.main, self.user, self.role, theme, self.layer_group_1]) transaction.commit()
def get_user_from_request(request, username=None): """ Return the User object for the request. Return ``None`` if: * user is anonymous * it does not exist in the database * the referer is invalid """ from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User try: if "auth" in request.params: auth_enc = request.params.get("auth") if auth_enc is not None: urllogin = request.registry.settings.get("urllogin", {}) aeskey = urllogin.get("aes_key") if aeskey is None: # pragma: nocover raise Exception("urllogin is not configured") now = int(time.time()) cipher = AES.new(aeskey) auth = json.loads(cipher.decrypt(binascii.unhexlify(auth_enc))) if "t" in auth and "u" in auth and "p" in auth: timestamp = int(auth["t"]) if now < timestamp and request.registry.validate_user( request, auth["u"], auth["p"] ): headers = pyramid.security.remember(request, auth["u"]) request.response.headerlist.extend(headers) except Exception as e: log.error("URL login error: {}".format(e)) if not hasattr(request, "is_valid_referer"): request.is_valid_referer = is_valid_referer(request, settings) if not request.is_valid_referer: log.warning( "Invalid referer for %s: %s", request.path_qs, repr(request.referer) ) return None if not hasattr(request, "user_"): request.user_ = None if username is None: username = request.authenticated_userid if username is not None: # We know we will need the role object of the # user so we use joined loading request.user_ = DBSession.query(User) \ .filter_by(username=username) \ .first() return request.user_
def _import(object_type, messages, callback=None): from c2cgeoportal_commons.models import DBSession items = DBSession.query(object_type) for item in items: messages.append(Message( None, item.name, None, [], "", "", (item.item_type, item.name.encode("ascii", errors="replace")) )) if callback is not None: callback(item, messages)
def __set__(self, obj, val): from c2cgeoportal_commons.models import DBSession o = getattr(obj, self.target) # if the obj as no child object or if the child object # does not correspond to the new value then we need to # read a new child object from the database if not o or getattr(o, self.value_attr) != val: relationship_property = class_mapper(obj.__class__) \ .get_property(self.target) child_cls = relationship_property.argument o = DBSession.query(child_cls).filter( getattr(child_cls, self.value_attr) == val).first() setattr(obj, self.target, o)
def __call__(self, filename, options): messages = [] try: self.env = bootstrap(filename) try: from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import Theme, LayerGroup, \ LayerWMS, LayerWMTS, FullTextSearch self._import(Theme, messages) self._import(LayerGroup, messages) self._import(LayerWMS, messages, self._import_layer_wms) self._import(LayerWMTS, messages, self._import_layer_wmts) for ln, in DBSession.query(FullTextSearch.layer_name).distinct().all(): if ln is not None and ln != "": messages.append(Message( None, ln, None, [], "", "", ("fts", ln.encode("ascii", errors="replace")) )) except ProgrammingError as e: print(colorize( "ERROR! The database is probably not up to date " "(should be ignored when happen during the upgrade)", RED )) print(colorize(e, RED)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise except NoSuchTableError as e: print(colorize( "ERROR! The schema didn't seem to exists " "(should be ignored when happen during the deploy)", RED )) print(colorize(e, RED)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise except OperationalError as e: print(colorize( "ERROR! The database didn't seem to exists " "(should be ignored when happen during the deploy)", RED )) print(colorize(e, RED)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise return messages
def teardown_method(self, _): testing.tearDown() from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import TreeItem, Interface, Metadata for t in DBSession.query(Metadata).all(): DBSession.delete(t) for item in DBSession.query(TreeItem).all(): DBSession.delete(item) DBSession.query(Interface).filter( Interface.name == "desktop" ).delete() transaction.commit()
def get(self): ref = self.request.matchdict["ref"] short_urls = DBSession.query(Shorturl).filter(Shorturl.ref == ref).all() if len(short_urls) != 1: raise HTTPNotFound("Ref '{0!s}' not found".format(ref)) short_urls[0].nb_hits += 1 short_urls[0].last_hit = datetime.now() set_common_headers( self.request, "shortener", NO_CACHE ) return HTTPFound(location=short_urls[0].url)
def test_reset_password(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from c2cgeoportal_geoportal.views.login import Login request = self._create_request_obj(POST={"login": "******"}) user, username, password, _ = Login(request)._loginresetpassword() assert user.temp_password is not None assert username == "__test_user1" request = self._create_request_obj(POST={ "login": username, "password": password }) response = Login(request).login() assert response.status_int == 200 assert json.loads(response.body.decode("utf-8")) == { "username": "******", "is_password_changed": False, "two_factor_enable": True, } request = self._create_request_obj( POST={ "login": username, "oldPassword": password, "newPassword": "******", "confirmNewPassword": "******", }) response = Login(request).change_password() assert json.loads(response.body.decode("utf-8")) == { "username": "******", "email": "*****@*****.**", "is_intranet": False, "two_factor_enable": False, "roles": [{ "name": "__test_role1", "id": self.role1_id }], "functionalities": {}, } user = DBSession.query(User).filter( User.username == "__test_user1").first() self.assertIsNone(user.temp_password) self.assertIsNotNone(user.password) self.assertNotEqual(len(user.password), 0)
def _is_authorized(self, internal_wms): if internal_wms.public: return True if self.request.user is None: return False else: restriction = DBSession.query(RestrictionArea).filter( RestrictionArea.roles.any( Role.id == self.request.user.role.id)).filter( RestrictionArea.layers.any( Layer.id == internal_wms.id)).first() # If not restriction is set then return unauthorized if restriction is None: return False return True
def _create_dummy_request(username=None): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User request = create_dummy_request({ "tinyowsproxy": { "tinyows_url": "http://localhost/tinyows", "ogc_server": "__test_ogc_server", # "online_resource": "http://domain.com/tinyows_proxy", # "proxy_online_resource": "http://domain.com/tinyows" } }) request.user = None if username is None else DBSession.query( User).filter_by(username=username).one() return request
def difference(self): body = loads(self.request.body) if "geometries" not in body or \ not isinstance(body["geometries"], list) or \ len(body["geometries"]) != 2: # pragma: no cover raise HTTPBadRequest("""Wrong body, it should be like that: { "geometries": [geomA, geomB] } """) return to_shape(DBSession.query(func.ST_Difference( from_shape(asShape(body["geometries"][0])), from_shape(asShape(body["geometries"][1])) )).scalar())
def setup_method(self, _): 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="******", role=self.role) self.main = Interface(name="main") DBSession.add(self.user) DBSession.add(self.role) DBSession.add(self.main) transaction.commit()
def _create_request_obj(username=None, params=None, **kwargs): if params is None: params = {} from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User request = create_dummy_request(**kwargs) request.route_url = lambda url, **kwargs: mapserv_url request.interface_name = "main" request.params = params if username is not None: request.user = DBSession.query(User).filter_by(username=username).one() return request
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 test_change_password(self): from c2cgeoportal_geoportal.views.login import Login from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = DBSession.query(User).filter_by(username="******").one() _2fa_totp_secret = pyotp.random_base32() totp = pyotp.TOTP(_2fa_totp_secret) user.tech_data["2fa_totp_secret"] = _2fa_totp_secret user.is_password_changed = True request = self._create_request_obj( username="******", POST={ "oldPassword": "******", "newPassword": "******", "confirmNewPassword": "******", "otp": totp.now(), }, ) response = Login(request).change_password() assert "Cookie" in dict(response.headers) assert set(user.tech_data.keys()) == {"2fa_totp_secret"} assert user.is_password_changed is True assert json.loads(response.body.decode("utf-8")) == { "email": "*****@*****.**", "functionalities": {}, "is_intranet": False, "roles": [], "two_factor_enable": True, "username": "******", } request = self._create_request_obj(POST={ "login": "******", "password": "******", "otp": totp.now() }) response = Login(request).login() assert "Cookie" in dict(response.headers) assert json.loads(response.body.decode("utf-8")) == { "username": "******", "email": "*****@*****.**", "is_intranet": False, "two_factor_enable": True, "roles": [], "functionalities": {}, }
def difference(self): body = loads(self.request.body) if ("geometries" not in body or not isinstance(body["geometries"], list) or len(body["geometries"]) != 2): # pragma: no cover raise HTTPBadRequest("""Wrong body, it should be like that: { "geometries": [geomA, geomB] } """) return to_shape( DBSession.query( func.ST_Difference(from_shape(asShape(body["geometries"][0])), from_shape(asShape( body["geometries"][1])))).scalar())
def teardown_method(self, _): testing.tearDown() from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import TreeItem, Interface, OGCServer for item in DBSession.query(TreeItem).all(): DBSession.delete(item) DBSession.query(OGCServer).delete() DBSession.query(Interface).filter( Interface.name == "main" ).delete() transaction.commit()
def test_wrong_login(self): from c2cgeoportal_geoportal.views.login import Login from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = DBSession.query(User).filter_by(username="******").one() _2fa_totp_secret = pyotp.random_base32() totp = pyotp.TOTP(_2fa_totp_secret) user.tech_data["2fa_totp_secret"] = _2fa_totp_secret user.is_password_changed = True request = self._create_request_obj(POST={ "password": "******", "otp": totp.now() }) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).login() request = self._create_request_obj(POST={ "login": "******", "password": "******" }) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).login() request = self._create_request_obj(POST={ "login": "******", "password": "******", "otp": totp.now() }) with pytest.raises(pyramid.httpexceptions.HTTPUnauthorized): Login(request).login() request = self._create_request_obj(POST={ "login": "******", "password": "******", "otp": "toto" }) with pytest.raises(pyramid.httpexceptions.HTTPUnauthorized): Login(request).login() request = self._create_request_obj(POST={ "login": "******", "otp": totp.now() }) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).login()
def locale_negotiator(request): lang = request.params.get("lang") if "/printproxy/report/" in request.path: from geoportailv3_geoportal.models import LuxPrintJob from c2cgeoportal_commons.models import DBSession # Language is stored in the database ref = request.path.split("/printproxy/report/")[1] if ref is not None: job = DBSession.query(LuxPrintJob).get(ref) if job is not None: if "lang" in json.loads(job.spec)["attributes"]: lang = json.loads(job.spec)["attributes"]["lang"] if lang is None: return request.accept_language.best_match( request.registry.settings.get("available_locale_names")) return lang
def _create_request_obj(username=None, **kwargs): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User request = create_dummy_request(**kwargs) request.registry.settings.update({ "authentication": { "two_factor": True, "two_factor_issuer_name": "CI" } }) if username is not None: request.user = DBSession.query(User).filter_by( username=username).one() return request
def authenticate_client_id( self, client_id: str, request: oauthlib.common.Request, *args: Any, **kwargs: Any, ) -> bool: """ Ensure client_id belong to a non-confidential client. A non-confidential client is one that is not required to authenticate through other means, such as using HTTP Basic. Note, while not strictly necessary it can often be very convenient to set request.client to the client object associated with the given client_id. Method is used by: - Authorization Code Grant """ del args, kwargs LOG.debug("authenticate_client_id %s", client_id) from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel params = dict(request.decoded_body) if "client_secret" in params: client_secret = params["client_secret"] elif "Authorization" in request.headers: username, password = basicauth.decode( request.headers["Authorization"]) assert client_id == username client_secret = password else: # Unable to get the client secret return False request.client = (DBSession.query(static.OAuth2Client).filter( static.OAuth2Client.client_id == client_id).filter( static.OAuth2Client.secret == client_secret).one_or_none()) LOG.debug("authenticate_client_id => %s", request.client is not None) return request.client is not None
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 teardown_method(self, _): testing.tearDown() import transaction from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import FullTextSearch DBSession.query(FullTextSearch).filter(FullTextSearch.label == "label 1").delete() DBSession.query(FullTextSearch).filter(FullTextSearch.label == "label 2").delete() DBSession.query(FullTextSearch).filter(FullTextSearch.label == "label 3").delete() transaction.commit()
def _create_dummy_request(username=None, params=None): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User request = create_dummy_request({ "fulltextsearch": { "languages": { "fr": "french", "en": "english", "de": "german", } } }, params=params) request.response = Response() request.user = None if username: request.user = DBSession.query(User) \ .filter_by(username=username).one() return request
def test_group_update(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import LayerGroup layer_group_3 = DBSession.query(LayerGroup).filter(LayerGroup.name == "__test_layer_group_3").one() layer_group_3.children = layer_group_3.children[:-1] transaction.commit() theme_view = self._create_theme_obj(params={"group": "__test_layer_group_3"}) themes = theme_view.themes() self.assertEqual(self._get_filtered_errors(themes), set()) self.assertEqual( self._only_name(themes["group"]), { "name": "__test_layer_group_3", # order is important "children": [{"name": "__test_layer_wmts"}, {"name": "__test_layer_internal_wms"}], }, )
def _is_download_authorized(self, town_name, user, referer): if referer is not None: if "bodfeature" in referer and "search4naila" in referer: return True if "weboffice_um" in referer: return True town_info = self._get_town_by_name(town_name) if (town_info is None or user is None or user.username is None): return False if (DBSession.query(LuxMeasurementLoginCommune).filter( func.lower(LuxMeasurementLoginCommune.login) == func.lower( func.geov3.getMainAccount(user.username))).filter( LuxMeasurementLoginCommune.num_commune == str( town_info.get('town_code'))).count() > 0): return True return False
def test_login(self): from pyramid.httpexceptions import HTTPUnauthorized from c2cgeoportal_geoportal.views.login import Login from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = DBSession.query(User).filter_by(username="******").one() user.is_password_changed = True request = self._create_request_obj(params={"came_from": "/came_from"}, POST={ "login": "******", "password": "******" }) response = Login(request).login() assert response.status_int == 302 assert response.headers["Location"] == "/came_from" request = self._create_request_obj(POST={ "login": "******", "password": "******" }) response = Login(request).login() assert response.status_int == 200 assert json.loads(response.body.decode("utf-8")) == { "username": "******", "email": "*****@*****.**", "is_intranet": False, "two_factor_enable": False, "roles": [{ "name": "__test_role1", "id": self.role1_id }], "functionalities": {}, } request = self._create_request_obj(POST={ "login": "******", "password": "******" }) login = Login(request) self.assertRaises(HTTPUnauthorized, login.login)
def test_wrong_login_change_password(self): from c2cgeoportal_geoportal.views.login import Login from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = DBSession.query(User).filter_by(username="******").one() user.tech_data["2fa_totp_secret"] = pyotp.random_base32() user.is_password_changed = True request = self._create_request_obj(username="******", POST={ "newPassword": "******", "confirmNewPassword": "******" }) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).change_password() request = self._create_request_obj(username="******", POST={ "oldPassword": "******", "confirmNewPassword": "******" }) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).change_password() request = self._create_request_obj(username="******", POST={ "oldPassword": "******", "newPassword": "******" }) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).change_password() request = self._create_request_obj( username="******", POST={ "oldPassword": "******", "newPassword": "******", "confirmNewPassword": "******" }, ) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).change_password()
def _import(object_type, messages, callback=None): from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel items = DBSession.query(object_type) for item in items: messages.append( Message( None, item.name, None, [], "", "", (item.item_type, item.name.encode("ascii", errors="replace")), ) ) if callback is not None: callback(item, messages)
def xsd_sequence_callback(tb, cls): from c2cgeoportal_commons.models import DBSession for k, p in cls.__dict__.items(): if not isinstance(p, _AssociationProxy): continue relationship_property = class_mapper(cls) \ .get_property(p.target) target_cls = relationship_property.argument query = DBSession.query(getattr(target_cls, p.value_attr)) attrs = {} attrs["minOccurs"] = "0" attrs["nillable"] = "true" attrs["name"] = k with tag(tb, "xsd:element", attrs) as tb: with tag(tb, "xsd:simpleType") as tb: with tag(tb, "xsd:restriction", {"base": "xsd:string"}) as tb: for value, in query: with tag(tb, "xsd:enumeration", {"value": value}): pass
def test_wrong_loginresetpassword(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from c2cgeoportal_geoportal.views.login import Login user = DBSession.query(User).filter_by(username="******").one() _2fa_totp_secret = pyotp.random_base32() totp = pyotp.TOTP(_2fa_totp_secret) user.tech_data["2fa_totp_secret"] = _2fa_totp_secret user.is_password_changed = True request = self._create_request_obj(POST={"otp": totp.now()}) with pytest.raises(pyramid.httpexceptions.HTTPBadRequest): Login(request).loginresetpassword() request = self._create_request_obj( POST={"login": "******"}) # Shouldn't raise an exception to avoid user enumeration Login(request).loginresetpassword()
def get_ogc_server_wms_url_ids(request): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import OGCServer from c2cgeoportal_geoportal.lib.cacheversion import VersionCache global ogc_server_wms_url_ids if ogc_server_wms_url_ids is None: ogc_server_wms_url_ids = VersionCache() errors = set() servers = ogc_server_wms_url_ids.get() if servers is None: servers = dict() ogc_server_wms_url_ids.set(servers) for ogc_server in DBSession.query(OGCServer).all(): url = get_url2(ogc_server.name, ogc_server.url, request, errors) if servers.get(url) is None: servers[url] = [] servers.get(url).append(ogc_server.id) return servers
def validate_refresh_token( self, refresh_token: str, client: "c2cgeoportal_commons.models.static.OAuth2Client", # noqa: F821 request: oauthlib.common.Request, *args: Any, **kwargs: Any, ) -> bool: """ Ensure the Bearer token is valid and authorized access to scopes. OBS! The request.user attribute should be set to the resource owner associated with this refresh token. Arguments: refresh_token: Unicode refresh token client: Client object set by you, see authenticate_client. request: The HTTP Request Method is used by: - Authorization Code Grant (indirectly by issuing refresh tokens) - Resource Owner Password Credentials Grant (also indirectly) - Refresh Token Grant """ del args, kwargs LOG.debug("validate_refresh_token %s", client.client_id if client else None) from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel bearer_token = (DBSession.query(static.OAuth2BearerToken).filter( static.OAuth2BearerToken.refresh_token == refresh_token).filter( static.OAuth2BearerToken.client_id == request.client.id ).filter(static.OAuth2BearerToken.expire_at > datetime.now()). one_or_none()) if bearer_token is not None: request.user = bearer_token.user return bearer_token is not None
def check(request): url = request.route_url("themes") session = requests.session() for interface, in DBSession.query(Interface.name).all(): params = {} params.update(default_params) params.update( interfaces_settings.get(interface, {}).get("params", {})) params["interface"] = interface interface_url_headers = build_url("checker_themes " + interface, url, request) response = session.get(params=params, **interface_url_headers) response.raise_for_status() result = response.json() if len(result["errors"]) != 0: raise Exception("Interface '{}': Theme with error\n{}".format( interface, "\n".join(result["errors"])))
def main(): parser = argparse.ArgumentParser( description="This script will rename all the theme elements to removes duplicated elements." ) 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 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 LayerV1, LayerWMS, LayerWMTS, LayerGroup, Theme for class_ in [LayerV1, LayerWMS, LayerWMTS, LayerGroup, Theme]: names = [] for item in DBSession.query(class_).all(): if item.name in names: i = 2 while "{}-{}".format(item.name, i) in names: i += 1 item.name = "{}-{}".format(item.name, i) names.append(item.name) transaction.commit()
def __download(self, num): if self.staging: url = "%s?ids=%s&token=%s" % ( self.config["casipo"]["staging_url"], num, self.config["casipo"]["fme_token"]) else: url = "%s?ids=%s&token=%s" % ( self.config["casipo"]["prod_url"], num, self.config["casipo"]["fme_token"]) db_ecadastre = DBSessions['ecadastre'] cnt = 0 try: sql = "select nextval_daily ('casipo_seq')" results = DBSession.execute(sql) for res in results: cnt = res[0] except Exception as e: log.exception(e) try: f = urllib.request.urlopen(url, None, 1800) data = f # YYYYMMJJ_Commune_Extrait_CASIPO_nn.pdf commune = "" sql = "select commune_administrative FROM DIFFDATA.communes_adm_cad_sections WHERE code_commune = " + str(int(num[0:3])) + " GROUP BY commune_administrative" results = db_ecadastre.execute(sql) for res in results: commune = res['commune_administrative'] self.filename = '/tmp/%s_%s_Extrait_CASIPO_%s.pdf' % (str(datetime.datetime.now().strftime("%Y%m%d")), commune, str(cnt)) with open(self.filename, 'wb') as fp: shutil.copyfileobj(data, fp) except Exception as e: log.exception(e) data = None log.debug(url) return
def default_user_validator(request, username, password): """ Validate the username/password. This is c2cgeoportal's default user validator. Return None if we are anonymous, the string to remember otherwise. """ del request # unused from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User user = DBSession.query(User).filter_by(username=username).first() if user is None: LOG.info('Unknow user "%s" tried to log in', username) return None if user.deactivated: LOG.info('Deactivated user "%s" tried to log in', username) return None if user.expired(): LOG.info('Expired user %s tried to log in', username) return None if not user.validate_password(password): LOG.info('User "%s" tried to log in with bad credentials', username) return None return username
def _import_layer_wmts(self, layer, messages): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.main import OGCServer layers = [d.value for d in layer.metadatas if d.name == "queryLayers"] if len(layers) == 0: layers = [d.value for d in layer.metadatas if d.name == "wmsLayer"] server = [d.value for d in layer.metadatas if d.name == "ogcServer"] if len(server) >= 1 and len(layers) >= 1: for wms_layer in layers: try: db_server = DBSession.query(OGCServer).filter( OGCServer.name == server[0]).one() self._import_layer_attributes( db_server.url_wfs or db_server.url, wms_layer, layer.item_type, layer.name, messages) except NoResultFound: print( colorize( "ERROR! the OGC server '{}' from the WMTS layer '{}' does not exist." .format(server[0], layer.name), RED)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise