New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vgrange/peamu #126
vgrange/peamu #126
Changes from all commits
ac72b7a
1ea0ec5
7e3455d
3bc3bfa
d8a84d1
4db8954
26bc8a3
7aa010d
3f46157
828a12f
4ea0d45
efb9ed1
6d90746
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ | |
|
||
Vous pouvez personnaliser la configuration Compose en créant [un fichier `.env`](https://docs.docker.com/compose/env-file/) au même niveau que le fichier `README.md`, puis y configurer les variables d'environnement suivantes : | ||
|
||
DJANGO_PORT_ON_DOCKER_HOST=8000 | ||
DJANGO_PORT_ON_DOCKER_HOST=8080 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, pas de problème avec la modification de ce port car il concerne un port sur la machine de dev et pas dans le conteneur Docker. |
||
POSTGRES_PORT_ON_DOCKER_HOST=5433 | ||
|
||
### Lancer le serveur de développement | ||
|
@@ -26,6 +26,8 @@ Ou pour utiliser [un débogueur interactif](https://github.com/docker/compose/is | |
|
||
$ docker-compose -f docker-compose-dev.yml run --service-ports django | ||
|
||
Une fois votre serveur de développement lancé, vous pouvez accéder au frontend à l'adresse http://localhost:8080/ | ||
|
||
### Peupler la base de données | ||
|
||
$ make populate_db | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -313,12 +313,32 @@ | |
API_INSEE_KEY = os.environ["API_INSEE_KEY"] | ||
API_INSEE_SECRET = os.environ["API_INSEE_SECRET"] | ||
|
||
# Pôle emploi. | ||
# Pôle emploi's Emploi Store Dev aka ESD. | ||
# https://www.emploi-store-dev.fr/portail-developpeur/catalogueapi | ||
API_EMPLOI_STORE_KEY = os.environ["API_EMPLOI_STORE_KEY"] | ||
API_EMPLOI_STORE_SECRET = os.environ["API_EMPLOI_STORE_SECRET"] | ||
API_EMPLOI_STORE_AUTH_BASE_URL = "https://entreprise.pole-emploi.fr" | ||
API_EMPLOI_STORE_BASE_URL = "https://api.emploi-store.fr/partenaire" | ||
API_ESD_KEY = os.environ["API_ESD_KEY"] | ||
API_ESD_SECRET = os.environ["API_ESD_SECRET"] | ||
API_ESD_AUTH_BASE_URL = "https://entreprise.pole-emploi.fr" | ||
API_ESD_BASE_URL = "https://api.emploi-store.fr/partenaire" | ||
|
||
# PE Connect aka PEAMU - technically one of ESD's APIs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. En fait je vois Perso je connais Je suppose que le There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nouveau commentaire :
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pour mémoire j'ai pris cette habitude suite à une grosse galère avec le support ESD pour un souci PE Connect LBB. Après m'avoir baladé d'interlocuteur en interlocuteur, je me suis pris un "Ah bon c'est pas PEAM Entreprise que vous utilisez?". Never again. PEAMU. |
||
# PEAM stands for Pôle Emploi Access Management. | ||
# Technically there are two PEAM distinct systems: | ||
# - PEAM "Entreprise", PEAM-E or PEAME for short. | ||
# - PEAM "Utilisateur", PEAM-U or PEAMU for short. | ||
# To avoid confusion between the two when contacting ESD support, | ||
# we get the habit to always explicitely state that we are using PEAM*U*. | ||
PEAMU_AUTH_BASE_URL = 'https://authentification-candidat.pole-emploi.fr' | ||
SOCIALACCOUNT_PROVIDERS={ | ||
"peamu": { | ||
"APP": { | ||
"key": "peamu", | ||
"client_id": API_ESD_KEY, | ||
"secret": API_ESD_SECRET | ||
}, | ||
}, | ||
} | ||
SOCIALACCOUNT_EMAIL_VERIFICATION = "none" | ||
SOCIALACCOUNT_ADAPTER = "itou.allauth.peamu.adapter.PEAMUSocialAccountAdapter" | ||
|
||
# PDFShift | ||
PDFSHIFT_API_KEY = os.environ["PDFSHIFT_API_KEY"] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,3 +42,21 @@ DEBUG_TOOLBAR_CONFIG = { | |
], | ||
"SHOW_TEMPLATE_CONTEXT": True, | ||
} | ||
|
||
# PEAMU. | ||
# ------------------------------------------------------------------------------ | ||
|
||
|
||
# This trick | ||
# https://github.com/pennersr/django-allauth/issues/749#issuecomment-70402595 | ||
# fixes the following issue | ||
# https://github.com/pennersr/django-allauth/issues/749 | ||
# Without this trick, python manage.py makemigrations | ||
# would want to create a migration in django-allauth dependency | ||
# /usr/local/lib/python3.7/site-packages/allauth/socialaccount/migrations/0004_auto_20200415_1510.py | ||
# - Alter field provider on socialaccount | ||
# - Alter field provider on socialapp | ||
MIGRATION_MODULES = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Si je comprends bien, la migration générée ne concerne pas spécifiquement PEAMU connect mais plutôt aullauth. Je suppose que si demain nous ajoutons un nouveau provider non existant par défaut dans la lib, sans ce réglage, Django voudra générer de nouveau une migration dans la lib. C'est certainement un peu overkill, mais étant donné que There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
'socialaccount': 'itou.allauth.migrations', | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
This empty folder is necessary for the MIGRATION_MODULES trick. | ||
See dev.py.template for more information. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import requests | ||
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter | ||
from allauth.socialaccount.providers.oauth2.views import OAuth2Adapter | ||
from django.conf import settings | ||
|
||
from itou.allauth.peamu.provider import PEAMUProvider | ||
|
||
|
||
class PEAMUSocialAccountAdapter(DefaultSocialAccountAdapter): | ||
def populate_user(self, request, sociallogin, data): | ||
user = super().populate_user(request, sociallogin, data) | ||
setattr(user, "is_job_seeker", True) | ||
return user | ||
|
||
|
||
class PEAMUOAuth2Adapter(OAuth2Adapter): | ||
provider_id = PEAMUProvider.id | ||
|
||
authorize_url = f"{settings.PEAMU_AUTH_BASE_URL}/connexion/oauth2/authorize" | ||
access_token_url = f"{settings.PEAMU_AUTH_BASE_URL}/connexion/oauth2/access_token" | ||
profile_url = f"{settings.API_ESD_BASE_URL}/peconnect-individu/v1/userinfo" | ||
headers = {"Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded"} | ||
|
||
def complete_login(self, request, app, token, **kwargs): | ||
id_token = token.token | ||
headers = {"Authorization": f"Bearer {id_token}"} | ||
resp = requests.get(self.profile_url, params=None, headers=headers) | ||
resp.raise_for_status() | ||
extra_data = resp.json() | ||
extra_data["id_token"] = id_token | ||
login = self.get_provider().sociallogin_from_response(request, extra_data) | ||
return login |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from urllib.parse import parse_qsl | ||
|
||
import requests | ||
from allauth.socialaccount.providers.oauth2.client import OAuth2Client, OAuth2Error | ||
|
||
|
||
class PEAMUOAuth2Client(OAuth2Client): | ||
""" | ||
Required exclusively for injecting realm=/individu | ||
when requesting access token. | ||
(╯°□°)╯︵ ┻━┻ | ||
""" | ||
|
||
def get_access_token(self, code): | ||
""" | ||
This whole method is unchanged except for the | ||
`params = {"realm": "/individu"}` hack. | ||
Original code: | ||
https://github.com/pennersr/django-allauth/blob/6a6d3c618ab018234dde8701173093274710ee0a/allauth/socialaccount/providers/oauth2/client.py#L44 | ||
""" | ||
data = {"redirect_uri": self.callback_url, "grant_type": "authorization_code", "code": code} | ||
if self.basic_auth: | ||
auth = requests.auth.HTTPBasicAuth(self.consumer_key, self.consumer_secret) | ||
else: | ||
auth = None | ||
data.update({"client_id": self.consumer_key, "client_secret": self.consumer_secret}) | ||
params = {"realm": "/individu"} | ||
self._strip_empty_keys(data) | ||
url = self.access_token_url | ||
if self.access_token_method == "GET": | ||
params = data | ||
data = None | ||
resp = requests.request( | ||
self.access_token_method, url, params=params, data=data, headers=self.headers, auth=auth | ||
) | ||
|
||
access_token = None | ||
if resp.status_code in [200, 201]: | ||
# Weibo sends json via 'text/plain;charset=UTF-8' | ||
if resp.headers["content-type"].split(";")[0] == "application/json" or resp.text[:2] == '{"': | ||
access_token = resp.json() | ||
else: | ||
access_token = dict(parse_qsl(resp.text)) | ||
if not access_token or "access_token" not in access_token: | ||
raise OAuth2Error("Error retrieving access token: %s" % resp.content) | ||
return access_token |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from allauth.socialaccount import providers | ||
from allauth.socialaccount.providers.base import ProviderAccount | ||
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider | ||
from django.conf import settings | ||
|
||
|
||
# We do not use the extra 8 APIs yet, even though they are prepared below, | ||
# because the ESD staff has not validated our 8 contracts yet. | ||
USE_ALL_APIS = False | ||
|
||
BASIC_SCOPES = [ | ||
# API Se connecter avec Pôle emploi (individu) v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-peconnect-individu-v1.html | ||
"openid", | ||
"api_peconnect-individuv1", | ||
"email", | ||
"profile", | ||
] | ||
|
||
EXTRA_SCOPES = [ | ||
# API Coordonnées v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-peconnect-coordonnees-v1.html | ||
"api_peconnect-coordonneesv1", | ||
"coordonnees", | ||
# API Statut v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-peconnect-statut-v1.html | ||
"api_peconnect-statutv1", | ||
"statut", | ||
# API Date de naissance v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-peconnect-datenaissance-v1.html | ||
"api_peconnect-datenaissancev1", | ||
"datenaissance", | ||
# API Indemnisations v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-indemnisations-v1.html | ||
"api_peconnect-indemnisationsv1", | ||
"indemnisation", | ||
# API Expériences professionnelles v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-experiences-professionnelles.html | ||
"api_peconnect-experiencesv1", | ||
"pfcexperiences", | ||
# API Expériences déclarées par l’Employeur v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-peconnect-exp-declarees-v1.html | ||
"api_peconnect-experiencesprofessionellesdeclareesparlemployeurv1", | ||
"passeprofessionnel", | ||
# API Formations professionnelles v1 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-formations-professionnelles.html | ||
"api_peconnect-formationsv1", | ||
"pfcformations", | ||
"pfcpermis", | ||
# API Compétences professionnelles v2 | ||
# https://www.emploi-store-dev.fr/portail-developpeur-cms/home/catalogue-des-api/documentation-des-api/api/api-pole-emploi-connect/api-peconnect-competence-v2-1.html | ||
"api_peconnect-competencesv2", | ||
"pfccompetences", | ||
"pfclangues", | ||
"pfccentresinteret", | ||
] | ||
|
||
|
||
class PEAMUProvider(OAuth2Provider): | ||
id = "peamu" | ||
name = "PEAMU" | ||
account_class = ProviderAccount | ||
|
||
def get_default_scope(self): | ||
client_id = settings.SOCIALACCOUNT_PROVIDERS["peamu"]["APP"]["client_id"] | ||
scope = [f"application_{client_id}"] + BASIC_SCOPES | ||
if USE_ALL_APIS: | ||
scope += EXTRA_SCOPES | ||
return scope | ||
|
||
def get_auth_params(self, request, action): | ||
ret = super().get_auth_params(request, action) | ||
ret["realm"] = "/individu" | ||
return ret | ||
|
||
def extract_uid(self, data): | ||
return str(data["sub"]) | ||
|
||
def extract_common_fields(self, data): | ||
return dict(email=data.get("email"), last_name=data.get("family_name"), first_name=data.get("given_name")) | ||
|
||
|
||
providers.registry.register(PEAMUProvider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je suggère de mettre à jour
.envs/dev.env.template
avec cette variable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Euh je peux me tromper, mais je crois que
envs/dev.env.template
est un template pourenvs/dev.env
et non pour.env
qui n'a pas de template pour le coup, seulement les 2 lignes dans le README.Peut-être que tu veux que je créé un
.env.template
versionné à la racine et simplifie le README en justecp .env.template .env
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, j'avais mal compris !
Cela étant, je n'ai pas créé de
.env
mais plutôt modifié ledev.env
pour y inclure cette variable. Je trouve ça plus pratique car cela évite d'avoir deux fichiers qui sourcent les variables d'environnement à utiliser en dev (ce qui constitue une source d'erreur potentielle).Le site devrait fonctionner pleinement grâce au
docker-compose-dev.yml
, or ce n'est plus le cas car le port par défaut est 8000 et que cela fait planter PEAMU. Voici donc deux propositions :dev.env.template
pour bien y indiquer le port à prendre en compte.Qu'en penses-tu ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
J'ai du mal à te suivre, pour moi ta suggestion "on change le port par défaut du conteneur Django" est déjà implémentée en fait. Cf dans
docker-compose-dev.yml
lepar ailleurs j'ai tenté de virer le
.env
et mettre ses deux lignes dans leenvs/dev.env
mais ça ne se passe pas bien. Le container tente d'utiliser le port 5432 de mon host (et du coup conflicte avec un autre de mes projets) au lieu d'utiliser le 5433 comme il devrait.AFAIU le
.env
est le seul moyen pour injecter les variables dans ledocker-compose-dev.yml
@celine-m-s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Autant pour moi, j'avais pas vu que tu avais modifié le
docker-compose-dev.yml
!