badges-stg: patch badges-backend to use fasjson

Signed-off-by: Ryan Lerch <rlerch@redhat.com>
This commit is contained in:
Ryan Lercho 2021-09-14 16:56:04 +10:00
parent 372f845509
commit fbb5ce4367
4 changed files with 167 additions and 6 deletions

View file

@ -0,0 +1,154 @@
""" Utilities for fedbadges that don't quite fit anywhere else. """
import types
import logging
log = logging.getLogger("moksha.hub")
import fedmsg
import fedora.client
import requests
# These are here just so they're available in globals()
# for compiling lambda expressions
import json
import re
import fedmsg.config
import fedmsg.encoding
import fedmsg.meta
# Imports for fasjson support
import os
import requests
import requests.exceptions
from gssapi import Credentials, exceptions
from requests_gssapi import HTTPSPNEGOAuth
def construct_substitutions(msg):
""" Convert a fedmsg message into a dict of substitutions. """
subs = {}
for key1 in msg:
if isinstance(msg[key1], dict):
subs.update(dict([
('.'.join([key1, key2]), val2)
for key2, val2 in construct_substitutions(msg[key1]).items()
]))
subs[key1] = msg[key1]
elif isinstance(msg[key1], basestring):
subs[key1] = msg[key1].lower()
else:
subs[key1] = msg[key1]
return subs
def format_args(obj, subs):
""" Recursively apply a substitutions dict to a given criteria subtree """
if isinstance(obj, dict):
for key in obj:
obj[key] = format_args(obj[key], subs)
elif isinstance(obj, list):
return [format_args(item, subs) for item in obj]
elif isinstance(obj, basestring) and obj[2:-2] in subs:
obj = subs[obj[2:-2]]
elif isinstance(obj, (int, float)):
pass
else:
obj = obj % subs
return obj
def single_argument_lambda_factory(expression, argument, name='value'):
""" Compile and execute a lambda expression with a single argument """
code = compile("lambda %s: %s" % (name, expression), __file__, "eval")
func = types.LambdaType(code, globals())()
return func(argument)
def recursive_lambda_factory(obj, arg, name='value'):
""" Given a dict, find any lambdas, compile, and execute them. """
if isinstance(obj, dict):
for key in obj:
if key == 'lambda':
# If so, *replace* the parent dict with the result of the expr
obj = single_argument_lambda_factory(obj[key], arg, name)
break
else:
obj[key] = recursive_lambda_factory(obj[key], arg, name)
elif isinstance(obj, list):
return [recursive_lambda_factory(e, arg, name) for e in obj]
else:
pass
return obj
def graceful(default_return_value):
""" A decorator that gracefully handles exceptions. """
def decorate(method):
def inner(self, *args, **kwargs):
try:
return method(self, *args, **kwargs)
except Exception as e:
log.exception(e)
log.error("From method: %r self: %r args: %r kwargs: %r" % (
method, self, args, kwargs))
return default_return_value
return inner
return decorate
def notification_callback(topic, msg):
""" This is a callback called by tahrir_api whenever something
it deems important has happened.
It is just used to publish fedmsg messages.
"""
fedmsg.publish(
topic=topic,
msg=msg,
)
def user_exists_in_fas(config, user):
""" Return true if the user exists in FAS. """
if config.get("fasjson_base_url", False):
# fasjson_client not available in python2, so just use requests
os.environ["KRB5_CLIENT_KTNAME"] = config.get("keytab")
try:
creds = Credentials(usage="initiate")
except exceptions.GSSError as e:
log.error("GSSError trying to authenticate to fasjson", e)
gssapi_auth = HTTPSPNEGOAuth(opportunistic_auth=True, creds=creds)
session = requests.Session()
session.auth = gssapi_auth
return session.get(config['fasjson_base_url']+"users/"+user+"/").ok
else:
default_url = 'https://admin.fedoraproject.org/accounts/'
fas2 = fedora.client.AccountSystem(
base_url=config['fas_credentials'].get('base_url', default_url),
username=config['fas_credentials']['username'],
password=config['fas_credentials']['password'],
)
return bool(fas2.person_by_username(user))
def get_pagure_authors(authors):
""" Extract the name of pagure authors from
a dictionary
Args:
authors (list): A list of dict that contains fullname and name key.
"""
authors_name = []
for item in authors:
if isinstance(item, dict):
try:
authors_name.append(item["name"])
except KeyError:
raise Exception("Multiple recipients : name not found in the message")
return authors_name

View file

@ -229,3 +229,13 @@
tags:
- badges
- badges/backend
# https://raw.githubusercontent.com/fedora-infra/fedbadges/fasjson/fedbadges/utils.py
- name: hotfix fedbadges with version from fasjson branch
copy:
src: fedbadges_utils.py
dest: /usr/lib/python2.7/site-packages/fedbadges/utils.py
when: env == "staging"
tags:
- badges
- badges/backend

View file

@ -35,16 +35,13 @@ config = {
# The badges backend (fedmsg-hub) uses this to build a fas cache of ircnicks
# to fas usernames so it can act appropriately on certain message types.
"fas_credentials": {
{% if env == 'staging' %}
"base_url": "https://accounts.stg.fedoraproject.org/",
{% endif %}
"username": "{{fedoraDummyUser}}",
"password": "{{fedoraDummyUserPassword}}",
},
{% if env == 'staging' %}
"fasjson_base_url": "https://fasjson.stg.fedoraproject.org/v1/"
"keytab": "/etc/krb5.badges-backend_badges-backend01.stg.iad2.fedoraproject.org.keytab"
"fasjson_base_url": "https://fasjson.stg.fedoraproject.org/v1/",
"keytab": "/etc/krb5.badges-backend_badges-backend01.stg.iad2.fedoraproject.org.keytab",
{% endif %}

View file

@ -1,6 +1,6 @@
config = {
{% if env == "staging" %}
'datanommer.sqlalchemy.url': 'postgresql://{{datanommerDBUser}}:{{datanommerDBPassword}}@db-datanommer.stg.iad2.fedoraproject.org/datanommer2',
'datanommer.sqlalchemy.url': 'postgresql://{{datanommerDBUser}}:{{datanommerDBPassword}}@db-datanommer01.stg.iad2.fedoraproject.org/datanommer2',
{% else %}
'datanommer.sqlalchemy.url': 'postgresql://{{datanommerDBUser}}:{{datanommerDBPassword}}@db-datanommer/datanommer',
{% endif %}