Compare commits

...

8 Commits

18 changed files with 58 additions and 44 deletions

View File

@ -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>.*)

View File

@ -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

View File

@ -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:

View File

@ -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.

View File

@ -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: ""

View File

@ -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

View File

@ -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: ""

View File

@ -1,2 +1,2 @@
"""passbook""" """passbook"""
__version__ = "0.10.4-stable" __version__ = "0.10.5-stable"

View File

@ -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">

View File

@ -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

View File

@ -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"

View File

@ -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")

View File

@ -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

View File

@ -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:

View File

@ -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"""

View File

@ -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;

View File

@ -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{
{ {

View File

@ -1,3 +1,3 @@
package pkg package pkg
const VERSION = "0.10.4-stable" const VERSION = "0.10.5-stable"