Compare commits
8 Commits
version/0.
...
version/0.
Author | SHA1 | Date | |
---|---|---|---|
c7ca95ff2b | |||
9f403a71ed | |||
2f4139df65 | |||
f3ee8f7d9c | |||
5fa3729702 | |||
87f44fada4 | |||
c0026f3e16 | |||
c1051059f4 |
@ -1,5 +1,5 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 0.10.4-stable
|
current_version = 0.10.5-stable
|
||||||
tag = True
|
tag = True
|
||||||
commit = True
|
commit = True
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)
|
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)
|
||||||
|
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
@ -18,11 +18,11 @@ jobs:
|
|||||||
- name: Building Docker Image
|
- name: Building Docker Image
|
||||||
run: docker build
|
run: docker build
|
||||||
--no-cache
|
--no-cache
|
||||||
-t beryju/passbook:0.10.4-stable
|
-t beryju/passbook:0.10.5-stable
|
||||||
-t beryju/passbook:latest
|
-t beryju/passbook:latest
|
||||||
-f Dockerfile .
|
-f Dockerfile .
|
||||||
- name: Push Docker Container to Registry (versioned)
|
- name: Push Docker Container to Registry (versioned)
|
||||||
run: docker push beryju/passbook:0.10.4-stable
|
run: docker push beryju/passbook:0.10.5-stable
|
||||||
- name: Push Docker Container to Registry (latest)
|
- name: Push Docker Container to Registry (latest)
|
||||||
run: docker push beryju/passbook:latest
|
run: docker push beryju/passbook:latest
|
||||||
build-proxy:
|
build-proxy:
|
||||||
@ -48,11 +48,11 @@ jobs:
|
|||||||
cd proxy
|
cd proxy
|
||||||
docker build \
|
docker build \
|
||||||
--no-cache \
|
--no-cache \
|
||||||
-t beryju/passbook-proxy:0.10.4-stable \
|
-t beryju/passbook-proxy:0.10.5-stable \
|
||||||
-t beryju/passbook-proxy:latest \
|
-t beryju/passbook-proxy:latest \
|
||||||
-f Dockerfile .
|
-f Dockerfile .
|
||||||
- name: Push Docker Container to Registry (versioned)
|
- name: Push Docker Container to Registry (versioned)
|
||||||
run: docker push beryju/passbook-proxy:0.10.4-stable
|
run: docker push beryju/passbook-proxy:0.10.5-stable
|
||||||
- name: Push Docker Container to Registry (latest)
|
- name: Push Docker Container to Registry (latest)
|
||||||
run: docker push beryju/passbook-proxy:latest
|
run: docker push beryju/passbook-proxy:latest
|
||||||
build-static:
|
build-static:
|
||||||
@ -77,11 +77,11 @@ jobs:
|
|||||||
run: docker build
|
run: docker build
|
||||||
--no-cache
|
--no-cache
|
||||||
--network=$(docker network ls | grep github | awk '{print $1}')
|
--network=$(docker network ls | grep github | awk '{print $1}')
|
||||||
-t beryju/passbook-static:0.10.4-stable
|
-t beryju/passbook-static:0.10.5-stable
|
||||||
-t beryju/passbook-static:latest
|
-t beryju/passbook-static:latest
|
||||||
-f static.Dockerfile .
|
-f static.Dockerfile .
|
||||||
- name: Push Docker Container to Registry (versioned)
|
- name: Push Docker Container to Registry (versioned)
|
||||||
run: docker push beryju/passbook-static:0.10.4-stable
|
run: docker push beryju/passbook-static:0.10.5-stable
|
||||||
- name: Push Docker Container to Registry (latest)
|
- name: Push Docker Container to Registry (latest)
|
||||||
run: docker push beryju/passbook-static:latest
|
run: docker push beryju/passbook-static:latest
|
||||||
test-release:
|
test-release:
|
||||||
@ -114,5 +114,5 @@ jobs:
|
|||||||
SENTRY_PROJECT: passbook
|
SENTRY_PROJECT: passbook
|
||||||
SENTRY_URL: https://sentry.beryju.org
|
SENTRY_URL: https://sentry.beryju.org
|
||||||
with:
|
with:
|
||||||
tagName: 0.10.4-stable
|
tagName: 0.10.5-stable
|
||||||
environment: beryjuorg-prod
|
environment: beryjuorg-prod
|
||||||
|
@ -23,7 +23,7 @@ services:
|
|||||||
labels:
|
labels:
|
||||||
- traefik.enable=false
|
- traefik.enable=false
|
||||||
server:
|
server:
|
||||||
image: beryju/passbook:${PASSBOOK_TAG:-0.10.4-stable}
|
image: beryju/passbook:${PASSBOOK_TAG:-0.10.5-stable}
|
||||||
command: server
|
command: server
|
||||||
environment:
|
environment:
|
||||||
PASSBOOK_REDIS__HOST: redis
|
PASSBOOK_REDIS__HOST: redis
|
||||||
@ -41,7 +41,7 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
worker:
|
worker:
|
||||||
image: beryju/passbook:${PASSBOOK_TAG:-0.10.4-stable}
|
image: beryju/passbook:${PASSBOOK_TAG:-0.10.5-stable}
|
||||||
command: worker
|
command: worker
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
@ -55,7 +55,7 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
static:
|
static:
|
||||||
image: beryju/passbook-static:${PASSBOOK_TAG:-0.10.4-stable}
|
image: beryju/passbook-static:${PASSBOOK_TAG:-0.10.5-stable}
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
labels:
|
labels:
|
||||||
|
@ -13,7 +13,7 @@ Download the latest `docker-compose.yml` from [here](https://raw.githubuserconte
|
|||||||
|
|
||||||
To optionally enable error-reporting, run `echo PASSBOOK_ERROR_REPORTING__ENABLED=true >> .env`
|
To optionally enable error-reporting, run `echo PASSBOOK_ERROR_REPORTING__ENABLED=true >> .env`
|
||||||
|
|
||||||
To optionally deploy a different version run `echo PASSBOOK_TAG=0.10.4-stable >> .env`
|
To optionally deploy a different version run `echo PASSBOOK_TAG=0.10.5-stable >> .env`
|
||||||
|
|
||||||
If this is a fresh passbook install run the following commands to generate a password:
|
If this is a fresh passbook install run the following commands to generate a password:
|
||||||
|
|
||||||
@ -39,4 +39,6 @@ Now you can pull the Docker images needed by running `docker-compose pull`. Afte
|
|||||||
|
|
||||||
passbook will then be reachable via HTTP on port 80, and HTTPS on port 443. You can optionally configure the packaged traefik to use Let's Encrypt certificates for TLS Encryption.
|
passbook will then be reachable via HTTP on port 80, and HTTPS on port 443. You can optionally configure the packaged traefik to use Let's Encrypt certificates for TLS Encryption.
|
||||||
|
|
||||||
|
If you plan to access passbook via a reverse proxy which does SSL Termination, make sure you use the HTTPS port, so passbook is aware of the SSL connection.
|
||||||
|
|
||||||
The initial setup process also creates a default admin user, the username and password for which is `pbadmin`. It is highly recommended to change this password as soon as you log in.
|
The initial setup process also creates a default admin user, the username and password for which is `pbadmin`. It is highly recommended to change this password as soon as you log in.
|
||||||
|
@ -11,7 +11,7 @@ This installation automatically applies database migrations on startup. After th
|
|||||||
image:
|
image:
|
||||||
name: beryju/passbook
|
name: beryju/passbook
|
||||||
name_static: beryju/passbook-static
|
name_static: beryju/passbook-static
|
||||||
tag: 0.10.4-stable
|
tag: 0.10.5-stable
|
||||||
|
|
||||||
nameOverride: ""
|
nameOverride: ""
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
appVersion: "0.10.4-stable"
|
appVersion: "0.10.5-stable"
|
||||||
description: A Helm chart for passbook.
|
description: A Helm chart for passbook.
|
||||||
name: passbook
|
name: passbook
|
||||||
version: "0.10.4-stable"
|
version: "0.10.5-stable"
|
||||||
icon: https://github.com/BeryJu/passbook/blob/master/docs/images/logo.svg
|
icon: https://github.com/BeryJu/passbook/blob/master/docs/images/logo.svg
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: postgresql
|
- name: postgresql
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
image:
|
image:
|
||||||
name: beryju/passbook
|
name: beryju/passbook
|
||||||
name_static: beryju/passbook-static
|
name_static: beryju/passbook-static
|
||||||
tag: 0.10.4-stable
|
tag: 0.10.5-stable
|
||||||
|
|
||||||
nameOverride: ""
|
nameOverride: ""
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
"""passbook"""
|
"""passbook"""
|
||||||
__version__ = "0.10.4-stable"
|
__version__ = "0.10.5-stable"
|
||||||
|
@ -5,18 +5,6 @@
|
|||||||
{% load passbook_utils %}
|
{% load passbook_utils %}
|
||||||
{% load admin_reflection %}
|
{% load admin_reflection %}
|
||||||
|
|
||||||
{% block head %}
|
|
||||||
{{ block.super }}
|
|
||||||
<style>
|
|
||||||
.pf-m-success {
|
|
||||||
color: var(--pf-global--success-color--100);
|
|
||||||
}
|
|
||||||
.pf-m-danger {
|
|
||||||
color: var(--pf-global--danger-color--100);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="pf-c-page__main-section pf-m-light">
|
<section class="pf-c-page__main-section pf-m-light">
|
||||||
<div class="pf-c-content">
|
<div class="pf-c-content">
|
||||||
|
@ -9,11 +9,12 @@ from django.urls import reverse_lazy
|
|||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views.generic import ListView, UpdateView
|
from django.views.generic import ListView, UpdateView
|
||||||
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
|
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
|
||||||
|
from guardian.shortcuts import get_objects_for_user
|
||||||
|
|
||||||
from passbook.admin.views.utils import DeleteMessageView
|
from passbook.admin.views.utils import DeleteMessageView
|
||||||
from passbook.lib.views import CreateAssignPermView
|
from passbook.lib.views import CreateAssignPermView
|
||||||
from passbook.policies.forms import PolicyBindingForm
|
from passbook.policies.forms import PolicyBindingForm
|
||||||
from passbook.policies.models import PolicyBinding, PolicyBindingModel
|
from passbook.policies.models import PolicyBinding
|
||||||
|
|
||||||
|
|
||||||
class PolicyBindingListView(LoginRequiredMixin, PermissionListMixin, ListView):
|
class PolicyBindingListView(LoginRequiredMixin, PermissionListMixin, ListView):
|
||||||
@ -29,13 +30,18 @@ class PolicyBindingListView(LoginRequiredMixin, PermissionListMixin, ListView):
|
|||||||
# Since `select_subclasses` does not work with a foreign key, we have to do two queries here
|
# Since `select_subclasses` does not work with a foreign key, we have to do two queries here
|
||||||
# First, get all pbm objects that have bindings attached
|
# First, get all pbm objects that have bindings attached
|
||||||
objects = (
|
objects = (
|
||||||
PolicyBindingModel.objects.filter(policies__isnull=False)
|
get_objects_for_user(
|
||||||
|
self.request.user, "passbook_policies.view_policybindingmodel"
|
||||||
|
)
|
||||||
|
.filter(policies__isnull=False)
|
||||||
.select_subclasses()
|
.select_subclasses()
|
||||||
.select_related()
|
.select_related()
|
||||||
.order_by("pk")
|
.order_by("pk")
|
||||||
)
|
)
|
||||||
for pbm in objects:
|
for pbm in objects:
|
||||||
pbm.bindings = PolicyBinding.objects.filter(target__pk=pbm.pbm_uuid)
|
pbm.bindings = get_objects_for_user(
|
||||||
|
self.request.user, self.permission_required
|
||||||
|
).filter(target__pk=pbm.pbm_uuid)
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,10 @@ from django.views.debug import SafeExceptionReporterFilter
|
|||||||
from guardian.shortcuts import get_anonymous_user
|
from guardian.shortcuts import get_anonymous_user
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.core.middleware import SESSION_IMPERSONATE_ORIGINAL_USER
|
from passbook.core.middleware import (
|
||||||
|
SESSION_IMPERSONATE_ORIGINAL_USER,
|
||||||
|
SESSION_IMPERSONATE_USER,
|
||||||
|
)
|
||||||
from passbook.lib.utils.http import get_client_ip
|
from passbook.lib.utils.http import get_client_ip
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
@ -148,8 +151,9 @@ class Event(models.Model):
|
|||||||
# Check if we're currently impersonating, and add that user
|
# Check if we're currently impersonating, and add that user
|
||||||
if hasattr(request, "session"):
|
if hasattr(request, "session"):
|
||||||
if SESSION_IMPERSONATE_ORIGINAL_USER in request.session:
|
if SESSION_IMPERSONATE_ORIGINAL_USER in request.session:
|
||||||
|
self.user = request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
|
||||||
self.context["on_behalf_of"] = model_to_dict(
|
self.context["on_behalf_of"] = model_to_dict(
|
||||||
request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
|
request.session[SESSION_IMPERSONATE_USER]
|
||||||
)
|
)
|
||||||
# User 255.255.255.255 as fallback if IP cannot be determined
|
# User 255.255.255.255 as fallback if IP cannot be determined
|
||||||
self.client_ip = get_client_ip(request) or "255.255.255.255"
|
self.client_ip = get_client_ip(request) or "255.255.255.255"
|
||||||
|
@ -31,7 +31,7 @@ class ImpersonateInitView(View):
|
|||||||
request.session[SESSION_IMPERSONATE_ORIGINAL_USER] = request.user
|
request.session[SESSION_IMPERSONATE_ORIGINAL_USER] = request.user
|
||||||
request.session[SESSION_IMPERSONATE_USER] = user_to_be
|
request.session[SESSION_IMPERSONATE_USER] = user_to_be
|
||||||
|
|
||||||
Event.new(EventAction.IMPERSONATION_STARTED).from_http(request)
|
Event.new(EventAction.IMPERSONATION_STARTED).from_http(request, user_to_be)
|
||||||
|
|
||||||
return redirect("passbook_core:overview")
|
return redirect("passbook_core:overview")
|
||||||
|
|
||||||
@ -48,9 +48,11 @@ class ImpersonateEndView(View):
|
|||||||
LOGGER.debug("Can't end impersonation", user=request.user)
|
LOGGER.debug("Can't end impersonation", user=request.user)
|
||||||
return redirect("passbook_core:overview")
|
return redirect("passbook_core:overview")
|
||||||
|
|
||||||
|
original_user = request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
|
||||||
|
|
||||||
del request.session[SESSION_IMPERSONATE_USER]
|
del request.session[SESSION_IMPERSONATE_USER]
|
||||||
del request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
|
del request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
|
||||||
|
|
||||||
Event.new(EventAction.IMPERSONATION_ENDED).from_http(request)
|
Event.new(EventAction.IMPERSONATION_ENDED).from_http(request, original_user)
|
||||||
|
|
||||||
return redirect("passbook_core:overview")
|
return redirect("passbook_core:overview")
|
||||||
|
@ -14,7 +14,7 @@ def _get_client_ip_from_meta(meta: Dict[str, Any]) -> Optional[str]:
|
|||||||
)
|
)
|
||||||
for _header in headers:
|
for _header in headers:
|
||||||
if _header in meta:
|
if _header in meta:
|
||||||
return meta.get(_header)
|
return meta.get(_header).split(", ")[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ class TokenParams:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.refresh_token = RefreshToken.objects.get(
|
self.refresh_token = RefreshToken.objects.get(
|
||||||
refresh_token=raw_token, client=self.provider
|
refresh_token=raw_token, provider=self.provider
|
||||||
)
|
)
|
||||||
|
|
||||||
except RefreshToken.DoesNotExist:
|
except RefreshToken.DoesNotExist:
|
||||||
|
@ -102,11 +102,14 @@ class ASGILogger:
|
|||||||
await self.app(scope, receive, send_hooked)
|
await self.app(scope, receive, send_hooked)
|
||||||
|
|
||||||
def _get_ip(self) -> str:
|
def _get_ip(self) -> str:
|
||||||
|
client_ip = None
|
||||||
for header in ASGI_IP_HEADERS:
|
for header in ASGI_IP_HEADERS:
|
||||||
if header in self.headers:
|
if header in self.headers:
|
||||||
return self.headers[header].decode()
|
client_ip = self.headers[header].decode()
|
||||||
|
if not client_ip:
|
||||||
client_ip, _ = self.scope.get("client", ("", 0))
|
client_ip, _ = self.scope.get("client", ("", 0))
|
||||||
return client_ip
|
# Check if header has multiple values, and use the first one
|
||||||
|
return client_ip.split(", ")[0]
|
||||||
|
|
||||||
def log(self, runtime: float):
|
def log(self, runtime: float):
|
||||||
"""Outpot access logs in a structured format"""
|
"""Outpot access logs in a structured format"""
|
||||||
|
@ -49,6 +49,13 @@
|
|||||||
max-height: var(--pf-c-login__main-footer-links-item-link-svg--Height);
|
max-height: var(--pf-c-login__main-footer-links-item-link-svg--Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pf-m-success {
|
||||||
|
color: var(--pf-global--success-color--100);
|
||||||
|
}
|
||||||
|
.pf-m-danger {
|
||||||
|
color: var(--pf-global--danger-color--100);
|
||||||
|
}
|
||||||
|
|
||||||
/* fix multiple selects height */
|
/* fix multiple selects height */
|
||||||
select[multiple] {
|
select[multiple] {
|
||||||
height: initial;
|
height: initial;
|
||||||
|
@ -51,8 +51,10 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti
|
|||||||
providerOpts.OIDCJwksURL = *provider.OidcConfiguration.JwksURI
|
providerOpts.OIDCJwksURL = *provider.OidcConfiguration.JwksURI
|
||||||
providerOpts.ProfileURL = *provider.OidcConfiguration.UserinfoEndpoint
|
providerOpts.ProfileURL = *provider.OidcConfiguration.UserinfoEndpoint
|
||||||
|
|
||||||
|
if provider.SkipPathRegex != "" {
|
||||||
skipRegexes := strings.Split(provider.SkipPathRegex, "\n")
|
skipRegexes := strings.Split(provider.SkipPathRegex, "\n")
|
||||||
providerOpts.SkipAuthRegex = skipRegexes
|
providerOpts.SkipAuthRegex = skipRegexes
|
||||||
|
}
|
||||||
|
|
||||||
providerOpts.UpstreamServers = []options.Upstream{
|
providerOpts.UpstreamServers = []options.Upstream{
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
const VERSION = "0.10.4-stable"
|
const VERSION = "0.10.5-stable"
|
||||||
|
Reference in New Issue
Block a user