Skip to content

📘 API Reference Core

Georama Core

apps

CoreConfig

Bases: AppConfig

Source code in src/georama/core/apps.py
4
5
6
class CoreConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'georama.core'

default_auto_field = 'django.db.models.BigAutoField' class-attribute instance-attribute

name = 'georama.core' class-attribute instance-attribute

asgi

ASGI config for core project.

It exposes the ASGI callable as a module-level variable named application.

For more information on this file, see https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/

application = get_asgi_application() module-attribute

auth

ALL_AUTHENTICATION_METHODS = [('BASIC_HTTP', 'georama.core.auth.http_basic_auth.basic_http_authentication_middleware')] module-attribute

HTTP_HEADER_ENCODING = 'iso-8859-1' module-attribute

BaseAuthentication

All authentication classes should extend BaseAuthentication.

Source code in src/georama/core/auth/__init__.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class BaseAuthentication:
    """
    All authentication classes should extend BaseAuthentication.
    """

    def authenticate(self, request: HttpRequest):
        """
        Authenticate the request and return a two-tuple of (user, token).
        """
        raise NotImplementedError(".authenticate() must be overridden.")

    def authenticate_header(self, request: HttpRequest):
        """
        Return a string to be used as the value of the `WWW-Authenticate`
        header in a `401 Unauthenticated` response, or `None` if the
        authentication scheme should return `403 Permission Denied` responses.
        """

authenticate(request)

Authenticate the request and return a two-tuple of (user, token).

Source code in src/georama/core/auth/__init__.py
26
27
28
29
30
def authenticate(self, request: HttpRequest):
    """
    Authenticate the request and return a two-tuple of (user, token).
    """
    raise NotImplementedError(".authenticate() must be overridden.")

authenticate_header(request)

Return a string to be used as the value of the WWW-Authenticate header in a 401 Unauthenticated response, or None if the authentication scheme should return 403 Permission Denied responses.

Source code in src/georama/core/auth/__init__.py
32
33
34
35
36
37
def authenticate_header(self, request: HttpRequest):
    """
    Return a string to be used as the value of the `WWW-Authenticate`
    header in a `401 Unauthenticated` response, or `None` if the
    authentication scheme should return `403 Permission Denied` responses.
    """

get_authentication_methods_middlewares(selected_auth_methods)

Source code in src/georama/core/auth/__init__.py
13
14
15
16
17
18
def get_authentication_methods_middlewares(selected_auth_methods: List[str]) -> List[str]:
    return [
        m
        for auth_method, m in ALL_AUTHENTICATION_METHODS
        if auth_method in selected_auth_methods
    ]

get_authorization_header(request)

Return request's 'Authorization:' header, as a bytestring.

Hide some test client ickyness where the header can be unicode.

Source code in src/georama/core/auth/__init__.py
40
41
42
43
44
45
46
47
48
49
50
def get_authorization_header(request: HttpRequest):
    """
    Return request's 'Authorization:' header, as a bytestring.

    Hide some test client ickyness where the header can be unicode.
    """
    auth = request.META.get("HTTP_AUTHORIZATION", b"")
    if isinstance(auth, str):
        # Work around django test client oddness
        auth = auth.encode(HTTP_HEADER_ENCODING)
    return auth

http_basic_auth

log = logging.getLogger(__name__) module-attribute

BasicAuthentication

Bases: BaseAuthentication

HTTP Basic authentication against username/password.

Source code in src/georama/core/auth/http_basic_auth.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class BasicAuthentication(BaseAuthentication):
    """
    HTTP Basic authentication against username/password.
    """

    www_authenticate_realm = "api"

    def authenticate(self, request) -> Tuple[User, None] | None:
        """
        Returns a `User` if a correct username and password have been supplied
        using HTTP Basic authentication.  Otherwise returns `None`.
        """
        auth = get_authorization_header(request).split()

        if not auth or auth[0].lower() != b"basic":
            return None

        if len(auth) == 1:
            msg = _("Invalid basic header. No credentials provided.")
            log.debug(msg)
            raise PermissionDenied(msg)
        elif len(auth) > 2:
            msg = _("Invalid basic header. Credentials string should not contain spaces.")
            log.debug(msg)
            raise PermissionDenied(msg)

        try:
            try:
                auth_decoded = base64.b64decode(auth[1]).decode("utf-8")
            except UnicodeDecodeError:
                auth_decoded = base64.b64decode(auth[1]).decode("latin-1")

            userid, password = auth_decoded.split(":", 1)
        except (TypeError, ValueError, UnicodeDecodeError, binascii.Error):
            msg = _("Invalid basic header. Credentials not correctly base64 encoded.")
            log.debug(msg)
            raise PermissionDenied(msg)

        return self.authenticate_credentials(userid, password, request)

    def authenticate_credentials(
        self, userid, password, request=None
    ) -> Tuple[User, None] | None:
        """
        Authenticate the userid and password against username and password
        with optional request for context.
        """
        credentials = {get_user_model().USERNAME_FIELD: userid, "password": password}
        user = authenticate(request=request, **credentials)

        if user is None:
            msg = _("Invalid username/password.")
            log.debug(msg)
            raise PermissionDenied(msg)

        if not user.is_active:
            msg = _("User inactive or deleted.")
            log.debug(msg)
            raise PermissionDenied(msg)

        return user, None

    def authenticate_header(self, request):
        return 'Basic realm="%s"' % self.www_authenticate_realm
www_authenticate_realm = 'api' class-attribute instance-attribute
authenticate(request)

Returns a User if a correct username and password have been supplied using HTTP Basic authentication. Otherwise returns None.

Source code in src/georama/core/auth/http_basic_auth.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def authenticate(self, request) -> Tuple[User, None] | None:
    """
    Returns a `User` if a correct username and password have been supplied
    using HTTP Basic authentication.  Otherwise returns `None`.
    """
    auth = get_authorization_header(request).split()

    if not auth or auth[0].lower() != b"basic":
        return None

    if len(auth) == 1:
        msg = _("Invalid basic header. No credentials provided.")
        log.debug(msg)
        raise PermissionDenied(msg)
    elif len(auth) > 2:
        msg = _("Invalid basic header. Credentials string should not contain spaces.")
        log.debug(msg)
        raise PermissionDenied(msg)

    try:
        try:
            auth_decoded = base64.b64decode(auth[1]).decode("utf-8")
        except UnicodeDecodeError:
            auth_decoded = base64.b64decode(auth[1]).decode("latin-1")

        userid, password = auth_decoded.split(":", 1)
    except (TypeError, ValueError, UnicodeDecodeError, binascii.Error):
        msg = _("Invalid basic header. Credentials not correctly base64 encoded.")
        log.debug(msg)
        raise PermissionDenied(msg)

    return self.authenticate_credentials(userid, password, request)
authenticate_credentials(userid, password, request=None)

Authenticate the userid and password against username and password with optional request for context.

Source code in src/georama/core/auth/http_basic_auth.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def authenticate_credentials(
    self, userid, password, request=None
) -> Tuple[User, None] | None:
    """
    Authenticate the userid and password against username and password
    with optional request for context.
    """
    credentials = {get_user_model().USERNAME_FIELD: userid, "password": password}
    user = authenticate(request=request, **credentials)

    if user is None:
        msg = _("Invalid username/password.")
        log.debug(msg)
        raise PermissionDenied(msg)

    if not user.is_active:
        msg = _("User inactive or deleted.")
        log.debug(msg)
        raise PermissionDenied(msg)

    return user, None
authenticate_header(request)
Source code in src/georama/core/auth/http_basic_auth.py
79
80
def authenticate_header(self, request):
    return 'Basic realm="%s"' % self.www_authenticate_realm

basic_http_authentication_middleware(get_response)

Source code in src/georama/core/auth/http_basic_auth.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
def basic_http_authentication_middleware(get_response):
    def middleware(request: HttpRequest) -> HttpResponse:
        basic_http_auth = BasicAuthentication()
        # www_authenticate_realm unused at the moment,
        # but setting it as a reminder if used in the future
        basic_http_auth.www_authenticate_realm = "georama"

        if not request.user.is_authenticated:
            try:
                user_token = basic_http_auth.authenticate(request)
                if user_token is not None:
                    log.debug(_("User was authenticated."))
                    request.user = user_token[0]
            except PermissionDenied:
                # AuthenticationFailed: there was a http auth header,
                # but auth failed: consider the user unlogged.
                log.debug(_("User was not authenticated."))
                return HttpResponse("Unauthorized", status=401)
            except Exception as e:
                log.error(e)
        response = get_response(request)
        return response

    return middleware

entities

models

log = logging.getLogger(__name__) module-attribute

PermissionInterface dataclass

Source code in src/georama/core/entities/models.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@dataclass
class PermissionInterface:
    published_as_type: str
    action: str
    target_identifier: str
    target_name: str

    @property
    def codename(self) -> str:
        return f"{self.published_as_type}_{self.action}_{self.target_identifier}"

    def readable_name(self, target_readable_identifier) -> str:
        """Creates the permission name stored in the db and used in the django admin

        Is a method and not a property to avoid database queries for Permission checking."""
        return f"Can {self.action} {self.target_name} ({target_readable_identifier})"
action instance-attribute
codename property
published_as_type instance-attribute
target_identifier instance-attribute
target_name instance-attribute
__init__(published_as_type, action, target_identifier, target_name)
readable_name(target_readable_identifier)

Creates the permission name stored in the db and used in the django admin

Is a method and not a property to avoid database queries for Permission checking.

Source code in src/georama/core/entities/models.py
24
25
26
27
28
def readable_name(self, target_readable_identifier) -> str:
    """Creates the permission name stored in the db and used in the django admin

    Is a method and not a property to avoid database queries for Permission checking."""
    return f"Can {self.action} {self.target_name} ({target_readable_identifier})"

PublishedAs

Bases: PublishedAsRoleNameSystem

Source code in src/georama/core/entities/models.py
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
class PublishedAs(PublishedAsRoleNameSystem):
    title = models.CharField(max_length=1000, null=True, default=None, blank=True)
    description = models.TextField(null=True, default=None, blank=True)
    license = models.TextField(
        default="""
    This dataset is made available under the Open Database
    License: http://opendatacommons.org/licenses/odbl/1.0/.
    Any rights in individual contents of the database are licensed
    under the Database Contents
    License: http://opendatacommons.org/licenses/dbcl/1.0/
    """
    )
    fees = models.TextField(default="No fees apply.")
    access_constraints = models.TextField(default="No access constraints apply.")

    @classmethod
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        models.signals.pre_delete.connect(delete_publishedas_db_permissions, sender=cls)

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        save_publishedas_db_permissions(self)

    def delete(self, using=None, keep_parents=False):
        super().delete(
            using=using,
            keep_parents=keep_parents,
        )

    class Meta:
        abstract = True
access_constraints = models.TextField(default='No access constraints apply.') class-attribute instance-attribute
description = models.TextField(null=True, default=None, blank=True) class-attribute instance-attribute
fees = models.TextField(default='No fees apply.') class-attribute instance-attribute
license = models.TextField(default='\n This dataset is made available under the Open Database\n License: http://opendatacommons.org/licenses/odbl/1.0/.\n Any rights in individual contents of the database are licensed\n under the Database Contents\n License: http://opendatacommons.org/licenses/dbcl/1.0/\n ') class-attribute instance-attribute
title = models.CharField(max_length=1000, null=True, default=None, blank=True) class-attribute instance-attribute
Meta
Source code in src/georama/core/entities/models.py
189
190
class Meta:
    abstract = True
abstract = True class-attribute instance-attribute
__init_subclass__(**kwargs) classmethod
Source code in src/georama/core/entities/models.py
174
175
176
177
@classmethod
def __init_subclass__(cls, **kwargs):
    super().__init_subclass__(**kwargs)
    models.signals.pre_delete.connect(delete_publishedas_db_permissions, sender=cls)
delete(using=None, keep_parents=False)
Source code in src/georama/core/entities/models.py
183
184
185
186
187
def delete(self, using=None, keep_parents=False):
    super().delete(
        using=using,
        keep_parents=keep_parents,
    )
save(*args, **kwargs)
Source code in src/georama/core/entities/models.py
179
180
181
def save(self, *args, **kwargs):
    super().save(*args, **kwargs)
    save_publishedas_db_permissions(self)

PublishedAsRoleNameSystem

Bases: Model

PublishedAsRoleNameSystem: a published resource with CRUD operations ruled by permissions

This class does not have any database operation (save, update delete, ...), so that interactions with permissions are fast, without any database query. It should stay that way.

Source code in src/georama/core/entities/models.py
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
class PublishedAsRoleNameSystem(models.Model):
    """PublishedAsRoleNameSystem: a published resource with CRUD operations ruled by permissions

    This class does not have any database operation (save, update delete, ...),
    so that interactions with permissions are fast, without any database query.
    It should stay that way.
    """

    published_as_type = None
    identifier = models.UUIDField(
        primary_key=True, default=uuid.uuid4, editable=False, null=False
    )
    name = models.CharField(max_length=1000, null=True, default=None, blank=True)
    public = models.BooleanField(default=False)

    class Meta:
        abstract = True

    @property
    def readable_identifier(self) -> str:
        return f"{self.identifier}"

    @property
    def read_permissions(self) -> List[PermissionInterface]:
        return [
            PermissionInterface(
                published_as_type=self.published_as_type,
                action="read",
                target_identifier=f"{self.identifier}",
                target_name=self.name,
            )
        ]

    @property
    def create_permissions(self) -> List[PermissionInterface]:
        return [
            PermissionInterface(
                published_as_type=self.published_as_type,
                action="create",
                target_identifier=f"{self.identifier}",
                target_name=self.name,
            )
        ]

    @property
    def update_permissions(self) -> List[PermissionInterface]:
        return [
            PermissionInterface(
                published_as_type=self.published_as_type,
                action="update",
                target_identifier=f"{self.identifier}",
                target_name=self.name,
            )
        ]

    @property
    def delete_permissions(self) -> List[PermissionInterface]:
        return [
            PermissionInterface(
                published_as_type=self.published_as_type,
                action="delete",
                target_identifier=f"{self.identifier}",
                target_name=self.name,
            )
        ]

    @property
    def permissions(self) -> List[PermissionInterface]:
        return (
            self.read_permissions
            + self.create_permissions
            + self.update_permissions
            + self.delete_permissions
        )

    @staticmethod
    def to_string(permissions: List[PermissionInterface]) -> List[str]:
        return [permission.codename for permission in permissions]

    @property
    def permission_codenames(self) -> List[str]:
        return self.to_string(self.permissions)

    def has_general_permission(self, user: User, app_name: str) -> bool:
        """indicates the user has any kind of permission on this publication"""
        if self.public:
            return True
        return self._has_grained_permission(user, self.permission_codenames, app_name)

    @staticmethod
    def _has_grained_permission(user: User, permissions: List[str], app_name: str) -> bool:
        permissions = [f"{app_name}.{permission}" for permission in permissions]
        if user.is_superuser:
            log.debug(f"Superuser => has access")
            # superusers always have access
            return True
        else:
            matching_permissions = list(set(permissions) & user.get_all_permissions())
            if len(matching_permissions) > 0:
                log.debug(f"Access granted")
                return True
            else:
                log.debug(f"Access denied")
                return False

    def has_read_permission(self, user: User, app_name: str) -> bool:
        if self.public:
            return True
        return self._has_grained_permission(
            user, self.to_string(self.read_permissions), app_name
        )

    def has_create_permission(self, user: User, app_name: str) -> bool:
        return self._has_grained_permission(
            user, self.to_string(self.create_permissions), app_name
        )

    def has_update_permission(self, user: User, app_name: str) -> bool:
        return self._has_grained_permission(
            user, self.to_string(self.update_permissions), app_name
        )

    def has_delete_permission(self, user: User, app_name: str) -> bool:
        return self._has_grained_permission(
            user, self.to_string(self.delete_permissions), app_name
        )
create_permissions property
delete_permissions property
identifier = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, null=False) class-attribute instance-attribute
name = models.CharField(max_length=1000, null=True, default=None, blank=True) class-attribute instance-attribute
permission_codenames property
permissions property
public = models.BooleanField(default=False) class-attribute instance-attribute
published_as_type = None class-attribute instance-attribute
read_permissions property
readable_identifier property
update_permissions property
Meta
Source code in src/georama/core/entities/models.py
46
47
class Meta:
    abstract = True
abstract = True class-attribute instance-attribute
_has_grained_permission(user, permissions, app_name) staticmethod
Source code in src/georama/core/entities/models.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
@staticmethod
def _has_grained_permission(user: User, permissions: List[str], app_name: str) -> bool:
    permissions = [f"{app_name}.{permission}" for permission in permissions]
    if user.is_superuser:
        log.debug(f"Superuser => has access")
        # superusers always have access
        return True
    else:
        matching_permissions = list(set(permissions) & user.get_all_permissions())
        if len(matching_permissions) > 0:
            log.debug(f"Access granted")
            return True
        else:
            log.debug(f"Access denied")
            return False
has_create_permission(user, app_name)
Source code in src/georama/core/entities/models.py
143
144
145
146
def has_create_permission(self, user: User, app_name: str) -> bool:
    return self._has_grained_permission(
        user, self.to_string(self.create_permissions), app_name
    )
has_delete_permission(user, app_name)
Source code in src/georama/core/entities/models.py
153
154
155
156
def has_delete_permission(self, user: User, app_name: str) -> bool:
    return self._has_grained_permission(
        user, self.to_string(self.delete_permissions), app_name
    )
has_general_permission(user, app_name)

indicates the user has any kind of permission on this publication

Source code in src/georama/core/entities/models.py
114
115
116
117
118
def has_general_permission(self, user: User, app_name: str) -> bool:
    """indicates the user has any kind of permission on this publication"""
    if self.public:
        return True
    return self._has_grained_permission(user, self.permission_codenames, app_name)
has_read_permission(user, app_name)
Source code in src/georama/core/entities/models.py
136
137
138
139
140
141
def has_read_permission(self, user: User, app_name: str) -> bool:
    if self.public:
        return True
    return self._has_grained_permission(
        user, self.to_string(self.read_permissions), app_name
    )
has_update_permission(user, app_name)
Source code in src/georama/core/entities/models.py
148
149
150
151
def has_update_permission(self, user: User, app_name: str) -> bool:
    return self._has_grained_permission(
        user, self.to_string(self.update_permissions), app_name
    )
to_string(permissions) staticmethod
Source code in src/georama/core/entities/models.py
106
107
108
@staticmethod
def to_string(permissions: List[PermissionInterface]) -> List[str]:
    return [permission.codename for permission in permissions]

delete_publishedas_db_permissions(sender, instance, **kwargs)

Source code in src/georama/core/entities/models.py
193
194
def delete_publishedas_db_permissions(sender, instance, **kwargs):
    Permission.objects.filter(codename__in=instance.permission_codenames).delete()

save_group_permissions(groups_selected, permission)

Source code in src/georama/core/entities/models.py
207
208
209
210
211
212
213
def save_group_permissions(groups_selected: List[Group], permission: Permission):
    groups_all = Group.objects.all()
    for group in groups_all:
        if group in groups_selected:
            group.permissions.add(permission)
        else:
            group.permissions.remove(permission)

save_publishedas_db_permissions(published_as)

Source code in src/georama/core/entities/models.py
196
197
198
199
200
201
202
203
204
def save_publishedas_db_permissions(published_as):
    content_type = ContentType.objects.get_for_model(type(published_as))
    for permission in published_as.permissions:
        if not Permission.objects.filter(codename=permission.codename).exists():
            Permission(
                codename=permission.codename,
                name=permission.readable_name(published_as.readable_identifier),
                content_type=content_type,
            ).save()

save_user_permissions(user_selected, permission)

Source code in src/georama/core/entities/models.py
216
217
218
219
220
221
222
def save_user_permissions(user_selected: List[User], permission: Permission):
    user_all = User.objects.all()
    for user in user_all:
        if user in user_selected:
            user.user_permissions.add(permission)
        else:
            user.user_permissions.remove(permission)

settings

Django settings for core project.

Generated by 'django-admin startproject' using Django 5.0.6.

For more information on this file, see https://docs.djangoproject.com/en/5.0/topics/settings/

For the full list of settings and their values, see https://docs.djangoproject.com/en/5.0/ref/settings/

ALLOWED_HOSTS = [] + GEORAMA_ALLOWED_HOSTS module-attribute

APPEND_SLASH = False module-attribute

AUTH_PASSWORD_VALIDATORS = [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}] module-attribute

BASE_DIR = Path(__file__).resolve().parent module-attribute

CORS_ALLOWED_ORIGINS = [] + os.getenv('GEORAMA_CORS_ALLOWED_ORIGINS', 'https://localhost:9309').split(' ') module-attribute

CORS_ALLOW_CREDENTIALS = os.environ.get('GEORAMA_CORS_ALLOW_CREDENTIALS', 'false').lower() == 'true' module-attribute

CSRF_TRUSTED_ORIGINS = [] + os.getenv('GEORAMA_CSRF_TRUSTED_ORIGINS', 'http://localhost:4242').split(' ') module-attribute

DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql', 'HOST': os.environ.get('GEORAMA_DB_HOST', 'localhost'), 'PORT': os.environ.get('GEORAMA_DB_PORT', '54321'), 'USER': os.environ.get('GEORAMA_DB_USER', 'postgres'), 'PASSWORD': os.environ.get('GEORAMA_DB_PW', 'test'), 'NAME': os.environ.get('GEORAMA_DB_NAME', 'postgres')}} module-attribute

DEBUG = os.environ.get('GEORAMA_DEBUG', 'false').lower() == 'true' module-attribute

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' module-attribute

GEORAMA_ALLOWED_HOSTS = os.environ.get('GEORAMA_ALLOWED_HOSTS', '').split(' ') module-attribute

GEORAMA_AUTHENTICATION_METHODS = os.environ.get('GEORAMA_AUTHENTICATION_METHODS', 'DJANGO_CONTRIB_AUTH').split(' ') module-attribute

INSTALLED_APPS = ['jazzmin', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'georama.core.apps.CoreConfig', 'georama.features.apps.VectorparrotConfig', 'georama.maps.apps.RasteroctopusConfig', 'georama.data_integration.apps.QmeleonConfig', 'corsheaders', 'georama.webgis.apps.ClogsConfig', 'allauth', 'allauth.account', 'allauth.socialaccount', 'adminsortable2', 'treebeard', 'django_extensions'] module-attribute

LANGUAGE_CODE = 'en-us' module-attribute

LOGGING = {'version': 1, 'disable_existing_loggers': False} module-attribute

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', *get_authentication_methods_middlewares(GEORAMA_AUTHENTICATION_METHODS), 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'allauth.account.middleware.AccountMiddleware'] module-attribute

ROOT_URLCONF = 'georama.core.urls' module-attribute

SECRET_KEY = 'django-insecure-n*xqzi(i)c&4cl52a_3+^mr19o+om6u)&d(cuz1ibrvm*t)9s!' module-attribute

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') module-attribute

STATIC_ROOT = os.path.join(BASE_DIR, 'static') module-attribute

STATIC_URL = 'static/' module-attribute

TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages']}}] module-attribute

TIME_ZONE = 'UTC' module-attribute

USE_I18N = True module-attribute

USE_TZ = True module-attribute

WSGI_APPLICATION = 'georama.core.wsgi.application' module-attribute

urls

URL configuration for core project.

The urlpatterns list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/5.0/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))

urlpatterns = [path('', views.GeoramaLanding.as_view(), name='landing'), path('login', views.Login.as_view(), name='login'), path('logout', views.Logout.as_view(), name='logout'), path('features', include('georama.features.urls')), path('data_integration', include('georama.data_integration.urls')), path('maps', include('georama.maps.urls')), path('webgis', include('georama.webgis.urls')), path('admin/', admin.site.urls, {'extra_context': {'DEBUG': settings.DEBUG}})] module-attribute

views

GeoramaLanding

Bases: View

Source code in src/georama/core/views.py
 8
 9
10
11
class GeoramaLanding(View):
    def get(self, request, *args, **kwargs):
        logo_url = static("/core/assets/images/georama.coming_soon.png")
        return TemplateResponse(request, context={"logo_url": logo_url}, template="home.html")

get(request, *args, **kwargs)

Source code in src/georama/core/views.py
 9
10
11
def get(self, request, *args, **kwargs):
    logo_url = static("/core/assets/images/georama.coming_soon.png")
    return TemplateResponse(request, context={"logo_url": logo_url}, template="home.html")

Login

Bases: View

Source code in src/georama/core/views.py
14
15
16
17
18
19
20
21
22
23
24
25
26
class Login(View):
    def get(self, request, *args, **kwargs):
        return TemplateResponse(request, "login.html")

    def post(self, request, *args, **kwargs):
        username = request.POST["username"]
        password = request.POST["password"]
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect("landing")
        else:
            return redirect("login")

get(request, *args, **kwargs)

Source code in src/georama/core/views.py
15
16
def get(self, request, *args, **kwargs):
    return TemplateResponse(request, "login.html")

post(request, *args, **kwargs)

Source code in src/georama/core/views.py
18
19
20
21
22
23
24
25
26
def post(self, request, *args, **kwargs):
    username = request.POST["username"]
    password = request.POST["password"]
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)
        return redirect("landing")
    else:
        return redirect("login")

Logout

Bases: View

Source code in src/georama/core/views.py
29
30
31
32
class Logout(View):
    def get(self, request, *args, **kwargs):
        logout(request)
        return redirect("login")

get(request, *args, **kwargs)

Source code in src/georama/core/views.py
30
31
32
def get(self, request, *args, **kwargs):
    logout(request)
    return redirect("login")

wsgi

WSGI config for core project.

It exposes the WSGI callable as a module-level variable named application.

For more information on this file, see https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/

application = get_wsgi_application() module-attribute