badges (old rhel7 vm based one): retire

Since we moved badges into openshift, we no longer should need to have
any of the old rhel7 vm's around or the roles that were used on them
(these have been re-implemented in the openshift app role).

Thanks badges! You live on in openshift!

Signed-off-by: Kevin Fenzi <kevin@scrye.com>
This commit is contained in:
Kevin Fenzi 2024-05-06 11:32:28 -07:00
parent 93735a7d35
commit 006e32d664
53 changed files with 0 additions and 3620 deletions

View file

@ -1,10 +0,0 @@
---
ipa_client_shell_groups:
- sysadmin-badges
- sysadmin-noc
- sysadmin-veteran
ipa_client_sudo_groups:
- sysadmin-badges
ipa_host_group: badges
ipa_host_group_desc: Hosts running the Badges application
primary_auth_source: ipa

View file

@ -1,51 +0,0 @@
---
csi_primary_contact: Badges admins - sysadmin-badges-members@fedoraproject.org
csi_purpose: Run fedmsg-hub with the fedbadges plugin to award badges (+ some crons)
csi_relationship: |
fedbadges integrates many different services..
* The fedbadges fedmsg-hub plugin relies on:
* the fedmsg bus, to deliver messages
* pkgdb, for queries about who owns what packages
* fas, to lookup what irc nick corresponds to what fas user.
* db-datanommer for the fedmsg history
* db01, for storing badge awards
* badges-web01 will be expecting to display badges entered into the tahrir
db on db01. So, if badges stop showing up there, the problem is likely
here.
* Locally, of note there exists:
* a git repo of badge rules and images to be synced here by ansible
to /usr/share/badges/
* a local file cache in /var/tmp/fedbadges-cache.dbm (not memcached, atm)
* Furthermore, there are a ton of cronjobs for awarding badges in
/usr/share/badges/cronjobs/ that depends on all sorts of third parties
(flickr, google+, libravatar, etc..).
# For the MOTD
csi_security_category: Low
# These are consumed by a task in roles/fedmsg/base/main.yml
fedmsg_certs:
- can_send:
- logger.log
group: sysadmin
owner: root
service: shell
- can_send:
- fedbadges.badge.award
- fedbadges.person.rank.advance
group: fedmsg
owner: root
service: fedbadges
# These people get told when something goes wrong.
fedmsg_error_recipients:
- sysadmin-badges-members@fedoraproject.org
fedmsg_hub_auto_restart: True
fedmsg_hub_memory_limit_mb: "{{ (mem_size / 2) | int }}"
freezes: false
lvm_size: 20000
mem_size: 16384
num_cpus: 2
# for systems that do not match the above - specify the same parameter in
# the host_vars/$hostname file
tcp_ports: [3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007]

View file

@ -1,51 +0,0 @@
---
# Define resources for this group of hosts here.
csi_primary_contact: Badges admins - sysadmin-badges-members@fedoraproject.org
csi_purpose: Run fedmsg-hub with the fedbadges plugin to award badges (+ some crons)
csi_relationship: |
fedbadges integrates many different services..
* The fedbadges fedmsg-hub plugin relies on:
* the fedmsg bus, to deliver messages
* pkgdb, for queries about who owns what packages
* fas, to lookup what irc nick corresponds to what fas user.
* db-datanommer for the fedmsg history
* db01, for storing badge awards
* badges-web01 will be expecting to display badges entered into the tahrir
db on db01. So, if badges stop showing up there, the problem is likely
here.
* Locally, of note there exists:
* a git repo of badge rules and images to be synced here by ansible
to /usr/share/badges/
* a local file cache in /var/tmp/fedbadges-cache.dbm (not memcached, atm)
* Furthermore, there are a ton of cronjobs for awarding badges in
/usr/share/badges/cronjobs/ that depends on all sorts of third parties
(flickr, google+, libravatar, etc..).
# For the MOTD
csi_security_category: Low
# These are consumed by a task in roles/fedmsg/base/main.yml
fedmsg_certs:
- can_send:
- logger.log
group: sysadmin
owner: root
service: shell
- can_send:
- fedbadges.badge.award
- fedbadges.person.rank.advance
group: fedmsg
owner: root
service: fedbadges
# These people get told when something goes wrong.
fedmsg_error_recipients:
- sysadmin-badges-members@fedoraproject.org
fedmsg_hub_auto_restart: True
fedmsg_hub_memory_limit_mb: "{{ (mem_size / 2) | int }}"
lvm_size: 20000
mem_size: 8192
num_cpus: 2
# for systems that do not match the above - specify the same parameter in
# the host_vars/$hostname file
tcp_ports: [3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007]

View file

@ -1,11 +0,0 @@
---
ipa_client_shell_groups:
- sysadmin-badges
- sysadmin-noc
- sysadmin-veteran
ipa_client_sudo_groups:
- sysadmin-badges
- sysadmin-noc
- sysadmin-veteran
ipa_host_group: badges
ipa_host_group_desc: Hosts running the Badges application

View file

@ -1,52 +0,0 @@
---
csi_primary_contact: Badges admins - sysadmin-badges-members@fedoraproject.org
csi_purpose: Run the 'tahrir' mod_wsgi app to display badges.fedoraproject.org
csi_relationship: |
The apache/mod_wsgi app is the only thing really running here
* This host relies on:
* db01 for its database of badge awards (and users, etc..)
* a collection of .pngs in /usr/share/badges/pngs put there by ansible
* memcached!
* Conversely, a few things rely on this site:
* We have a mediawiki plugin that hits a JSON endpoint to display badges.
It should be resilient, but issues in the badges app may cascade into
mediawiki issues in the event of faults.
* fedora-mobile (the android app) queries the JSON api here.
* zodbot has a .badges <username> command that queries the JSON api here.
* openbadges.org may call back to this app to verify that badge assertions
are really certified by us (this will happen anytime someone exports
their fedora badges to the mozilla universe via the tahrir web
interface, but may also happen later in the future to ensure we did not
revoke such and such badge).
# For the MOTD
csi_security_category: Low
# Neeed for rsync from log01 for logs.
custom_rules: ['-A INPUT -p tcp -m tcp -s 10.3.163.39 --dport 873 -j ACCEPT', '-A INPUT -p tcp -m tcp -s 192.168.1.59 --dport 873 -j ACCEPT']
# These are consumed by a task in roles/fedmsg/base/main.yml
fedmsg_certs:
- can_send:
- logger.log
group: sysadmin
owner: root
service: shell
- can_send:
- fedbadges.badge.award
- fedbadges.person.rank.advance
- fedbadges.person.login.first
group: tahrir
owner: root
service: tahrir
freezes: false
lvm_size: 20000
mem_size: 6144
num_cpus: 2
tcp_ports: [80]
# Definining these vars has a number of effects
# 1) mod_wsgi is configured to use the vars for its own setup
# 2) iptables opens enough ports for all threads for fedmsg
# 3) roles/fedmsg/base/ declares enough fedmsg endpoints for all threads
wsgi_fedmsg_service: tahrir
wsgi_procs: 2
wsgi_threads: 2

View file

@ -1,52 +0,0 @@
---
# Define resources for this group of hosts here.
csi_primary_contact: Badges admins - sysadmin-badges-members@fedoraproject.org
csi_purpose: Run the 'tahrir' mod_wsgi app to display badges.fedoraproject.org
csi_relationship: |
The apache/mod_wsgi app is the only thing really running here
* This host relies on:
* db01 for its database of badge awards (and users, etc..)
* a collection of .pngs in /usr/share/badges/pngs put there by ansible
* memcached!
* Conversely, a few things rely on this site:
* We have a mediawiki plugin that hits a JSON endpoint to display badges.
It should be resilient, but issues in the badges app may cascade into
mediawiki issues in the event of faults.
* fedora-mobile (the android app) queries the JSON api here.
* zodbot has a .badges <username> command that queries the JSON api here.
* openbadges.org may call back to this app to verify that badge assertions
are really certified by us (this will happen anytime someone exports
their fedora badges to the mozilla universe via the tahrir web
interface, but may also happen later in the future to ensure we did not
revoke such and such badge).
# For the MOTD
csi_security_category: Low
# Neeed for rsync from log01 for logs.
custom_rules: ['-A INPUT -p tcp -m tcp -s 10.3.163.39 --dport 873 -j ACCEPT', '-A INPUT -p tcp -m tcp -s 192.168.1.59 --dport 873 -j ACCEPT']
# These are consumed by a task in roles/fedmsg/base/main.yml
fedmsg_certs:
- can_send:
- logger.log
group: sysadmin
owner: root
service: shell
- can_send:
- fedbadges.badge.award
- fedbadges.person.rank.advance
- fedbadges.person.login.first
group: tahrir
owner: root
service: tahrir
lvm_size: 20000
mem_size: 2048
num_cpus: 2
tcp_ports: [80]
# Definining these vars has a number of effects
# 1) mod_wsgi is configured to use the vars for its own setup
# 2) iptables opens enough ports for all threads for fedmsg
# 3) roles/fedmsg/base/ declares enough fedmsg endpoints for all threads
wsgi_fedmsg_service: tahrir
wsgi_procs: 2
wsgi_threads: 2

View file

@ -1,12 +0,0 @@
---
datacenter: iad2
eth0_ipv4_gw: 10.3.163.254
eth0_ipv4_ip: 10.3.163.94
ks_repo: http://10.3.163.35/repo/rhel/RHEL7-x86_64/
ks_url: http://10.3.163.35/repo/rhel/ks/kvm-rhel-7-iad2
sar_output_file: badges.json
# GDPR SAR variables
sar_script: /usr/local/bin/get-sar-person-details
sar_script_user: fedmsg
vmhost: vmhost-x86-04.iad2.fedoraproject.org
volgroup: /dev/vg_guests

View file

@ -1,12 +0,0 @@
---
datacenter: iad2
eth0_ipv4_gw: 10.3.166.254
eth0_ipv4_ip: 10.3.166.44
ks_repo: http://10.3.163.35/repo/rhel/RHEL7-x86_64/
ks_url: http://10.3.163.35/repo/rhel/ks/kvm-rhel-7-iad2
sar_output_file: badges.json
# GDPR SAR variables
sar_script: /usr/local/bin/get-sar-person-details
sar_script_user: fedmsg
vmhost: vmhost-x86-11.stg.iad2.fedoraproject.org
volgroup: /dev/vg_guests

View file

@ -1,8 +0,0 @@
---
datacenter: iad2
eth0_ipv4_gw: 10.3.163.254
eth0_ipv4_ip: 10.3.163.95
ks_repo: http://10.3.163.35/repo/rhel/RHEL7-x86_64/
ks_url: http://10.3.163.35/repo/rhel/ks/kvm-rhel-7-iad2
vmhost: vmhost-x86-04.iad2.fedoraproject.org
volgroup: /dev/vg_guests

View file

@ -1,8 +0,0 @@
---
datacenter: iad2
eth0_ipv4_gw: 10.3.166.254
eth0_ipv4_ip: 10.3.166.65
ks_repo: http://10.3.163.35/repo/rhel/RHEL7-x86_64/
ks_url: http://10.3.163.35/repo/rhel/ks/kvm-rhel-7-iad2
vmhost: vmhost-x86-11.stg.iad2.fedoraproject.org
volgroup: /dev/vg_guests

View file

@ -28,26 +28,6 @@ certgetter01.iad2.fedoraproject.org
[backup]
backup01.iad2.fedoraproject.org
[badges:children]
badges_backend
badges_web
[badges_stg:children]
badges_backend_stg
badges_web_stg
[badges_backend]
badges-backend01.iad2.fedoraproject.org
[badges_backend_stg]
badges-backend01.stg.iad2.fedoraproject.org
[badges_web]
badges-web01.iad2.fedoraproject.org
[badges_web_stg]
badges-web01.stg.iad2.fedoraproject.org
[basset]
[basset_stg]
@ -203,8 +183,6 @@ db-datanommer01.stg.iad2.fedoraproject.org
# clients that talk to the main postgres stg servers
[postgres_clients_stg]
badges-backend01.stg.iad2.fedoraproject.org
badges-web01.stg.iad2.fedoraproject.org
bodhi-backend01.stg.iad2.fedoraproject.org
busgateway01.stg.iad2.fedoraproject.org
koji01.stg.iad2.fedoraproject.org
@ -611,8 +589,6 @@ zabbix01.stg.iad2.fedoraproject.org
#
[staging]
autosign01.stg.iad2.fedoraproject.org
badges-backend01.stg.iad2.fedoraproject.org
badges-web01.stg.iad2.fedoraproject.org
# basset01.stg.iad2.fedoraproject.org
bodhi-backend01.stg.iad2.fedoraproject.org
bvmhost-x86-01.stg.iad2.fedoraproject.org
@ -778,14 +754,12 @@ wiki02.iad2.fedoraproject.org
# assorted categories of fedmsg services, for convenience
[fedmsg_hubs:children]
badges_backend
busgateway
fedimg
mbs_backend
pkgs
[fedmsg_hubs_stg:children]
badges_backend_stg
busgateway_stg
fedimg_stg
mbs_backend_stg
@ -1074,7 +1048,6 @@ batcave01.iad2.fedoraproject.org
bodhi-backend01.iad2.fedoraproject.org
[sar]
badges-backend01.iad2.fedoraproject.org
bodhi-backend01.iad2.fedoraproject.org
mailman01.iad2.fedoraproject.org
people02.fedoraproject.org
@ -1119,7 +1092,6 @@ iad2_staging
[iad2_production:children]
backup
badges
bastion_iad2
batcave_iad2
bodhi_backend
@ -1168,7 +1140,6 @@ virthost
wiki
[iad2_staging:children]
badges_stg
bastion_stg
bodhi_backend_stg
buildvm_stg

View file

@ -13,8 +13,6 @@
## group playbooks
##
- import_playbook: /srv/web/infra/ansible/playbooks/groups/backup-server.yml
- import_playbook: /srv/web/infra/ansible/playbooks/groups/badges-backend.yml
- import_playbook: /srv/web/infra/ansible/playbooks/groups/badges-web.yml
- import_playbook: /srv/web/infra/ansible/playbooks/groups/bastion.yml
- import_playbook: /srv/web/infra/ansible/playbooks/groups/batcave.yml
- import_playbook: /srv/web/infra/ansible/playbooks/groups/bodhi-backend.yml

View file

@ -1,63 +0,0 @@
# create a new badges-backend server
# NOTE: should be used with --limit most of the time
# NOTE: make sure there is room/space for this server on the vmhost
# NOTE: most of these vars_path come from group_vars/mirrorlist or from hostvars
- import_playbook: "/srv/web/infra/ansible/playbooks/include/virt-create.yml"
vars:
myhosts: "badges_backend:badges_backend_stg"
- name: dole out the generic configuration
hosts: badges_backend:badges_backend_stg
user: root
gather_facts: True
vars_files:
- /srv/web/infra/ansible/vars/global.yml
- "/srv/private/ansible/vars.yml"
- /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml
roles:
- base
- rkhunter
- nagios_client
- zabbix/zabbix_agent
- hosts
- {role: openvpn/client,
when: env != "staging"}
- ipa/client
- {role: keytab/service,
owner_user: fedmsg,
owner_group: fedmsg,
service: badges-backend}
- collectd/base
- fedmsg/base
- sudo
pre_tasks:
- import_tasks: "{{ tasks_path }}/yumrepos.yml"
tasks:
- import_tasks: "{{ tasks_path }}/motd.yml"
handlers:
- import_tasks: "{{ handlers_path }}/restart_services.yml"
- name: dole out the service-specific config
hosts: badges_backend:badges_backend_stg
user: root
gather_facts: True
roles:
- fedmsg/hub
- badges/backend
- role: collectd/fedmsg-service
process: fedmsg-hub
vars_files:
- /srv/web/infra/ansible/vars/global.yml
- "/srv/private/ansible/vars.yml"
- "{{ vars_path }}/{{ ansible_distribution }}.yml"
handlers:
- import_tasks: "{{ handlers_path }}/restart_services.yml"

View file

@ -1,51 +0,0 @@
# create a new badges-web server
# NOTE: should be used with --limit most of the time
# NOTE: make sure there is room/space for this server on the vmhost
# NOTE: most of these vars_path come from group_vars/badges-web* or from hostvars
- import_playbook: "/srv/web/infra/ansible/playbooks/include/virt-create.yml"
vars:
myhosts: "badges_web:badges_web_stg"
- name: make the box be real
hosts: badges_web:badges_web_stg
user: root
gather_facts: True
vars_files:
- /srv/web/infra/ansible/vars/global.yml
- "/srv/private/ansible/vars.yml"
- /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml
roles:
- base
- rkhunter
- nagios_client
- zabbix/zabbix_agent
- hosts
- {role: openvpn/client,
when: env != "staging"}
- ipa/client
- collectd/base
- badges/frontend
- fedmsg/base
- rsyncd
- sudo
- mod_wsgi
- role: collectd/web-service
site: frontpage
url: "http://localhost/"
interval: 10
- role: collectd/web-service
site: leaderboard
url: "http://localhost/leaderboard"
interval: 10
pre_tasks:
- import_tasks: "{{ tasks_path }}/yumrepos.yml"
tasks:
- import_tasks: "{{ tasks_path }}/motd.yml"
handlers:
- import_tasks: "{{ handlers_path }}/restart_services.yml"

View file

@ -1,83 +0,0 @@
#!/usr/bin/env python
""" This is a CLI script for awarding a single badge to a single person.
The intent is to use it to batch award a badge to a list of people.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--user', default=None, help="A FAS username")
parser.add_argument('--badge', default=None, help="A badge id")
args = parser.parse_args()
if not args.user:
print "You must specify a FAS username."
sys.exit(1)
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, nickname, badge_id):
person = tahrir.get_person(nickname=nickname)
badge = tahrir.get_badge(badge_id)
if not person:
print "No such person %r" % nickname
sys.exit(1)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
already_has_it = [assertion.person for assertion in badge.assertions]
if person in already_has_it:
print "%r already has the %r badge..." % (nickname, badge_id)
return
print person.nickname, "totally gets the %r badge." % badge_id
try:
transaction.begin()
tahrir.add_assertion(badge.id, person.email, None)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.user, args.badge)

View file

@ -1,141 +0,0 @@
#!/usr/bin/env python
import __main__
# This is going to require sqlalchemy 0.8 sooner than later.
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"]
import pkg_resources
pkg_resources.require(__requires__)
import tempfile
import time
import os
import subprocess
import shutil
from gssapi import Credentials
from gssapi.exceptions import GSSError
from requests_gssapi import HTTPSPNEGOAuth
from tahrir_api.dbapi import TahrirDatabase
import fedbadges.utils
import transaction
import requests
import fedora.client
import socket
import logging
log = logging.getLogger()
logging.basicConfig()
import fedmsg
import fedmsg.config
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
badge = None
http_client = None
def get_http_client():
os.environ["KRB5_CLIENT_KTNAME"] = fm_config.get("keytab")
try:
creds = Credentials(usage="initiate")
except GSSError as e:
log.error("GSSError trying to authenticate with Kerberos", e)
gssapi_auth = HTTPSPNEGOAuth(opportunistic_auth=True, creds=creds)
session = requests.Session()
session.auth = gssapi_auth
return session
def clone_repo(repo):
pwd = os.getcwd()
command = 'git clone https://github.com/fedora-infra/%s.git %s'
try:
location = tempfile.mkdtemp()
os.chdir(location)
os.system(command % (repo, location))
finally:
os.chdir(pwd)
return location
def gather_authors(location):
pwd = os.getcwd()
command = 'git log --raw | grep "^Author: " | sort | uniq -c'
try:
os.chdir(location)
proc = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE)
out, err = proc.communicate()
lines = out.split('\n')
authors = [line.split('<')[-1].split('>')[0] for line in lines]
finally:
os.chdir(pwd)
return authors
def emails_to_fas_accounts(emails):
usernames = []
for email in emails:
result = http_client.get(
"{}search/users/".format(fm_config['fasjson_base_url']),
params={"email": email}
)
if not result.ok:
continue
response = result.json()
if response["page"]["total_results"] != 1:
continue
usernames.append(response["result"][0]["username"])
return usernames
def main():
repos = ['tahrir', 'tahrir-api', 'fedbadges']
for repo in repos:
print "Trying %r" % repo
location = clone_repo(repo)
try:
emails = gather_authors(location)
print "Considering emails %r" % emails
usernames = emails_to_fas_accounts(emails)
print "Considering users %r" % usernames
award_badges(usernames)
finally:
shutil.rmtree(location)
def award_badges(usernames):
for username in usernames:
email = username + "@fedoraproject.org"
if tahrir.assertion_exists(badge.id, email):
print email, "already has", badge.id, "skipping."
continue
time.sleep(1)
print "awarding", badge.id, "to", email
try:
transaction.begin()
tahrir.add_assertion(badge.id, email, None)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
badge = tahrir.get_badge(badge_id='badge-off!')
if not badge:
raise ValueError("badge does not exist")
http_client = get_http_client()
main()

View file

@ -1 +0,0 @@
# 40 2 * * 4 fedmsg /usr/share/badges/cronjobs/award-badges-dev-badge >> /var/log/fedmsg/cron-award-badges-dev-badge.log 2>&1

View file

@ -1,239 +0,0 @@
#!/usr/bin/env python
""" Script to award the flock paparazzi badge.
We scrape g+ and flickr for photos tagged Flock and Fedora,
with the people we find who posted those, we try our best to match them with
a FAS username. If we can, then we award them the badge.
Author: Ralph Bean <rbean@redhat.com>
"""
from __future__ import print_function
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"]
import pkg_resources
pkg_resources.require(__requires__)
import time
import os
import ConfigParser
import requests
import transaction
import tahrir_api.dbapi
from gssapi import Credentials
from gssapi.exceptions import GSSError
from requests_gssapi import HTTPSPNEGOAuth
import fedmsg
import fedmsg.config
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
import fedbadges.utils
# Get config secrets from a file
config = ConfigParser.ConfigParser()
config.read(['flock-paparazzi.ini', '/etc/flock-paparazzi.ini'])
flickr_api_key = config.get('general', 'flickr_api_key')
g_plus_key = config.get('general', 'g_plus_key')
userIP = config.get('general', 'userIP')
# API urls
flickr_url = 'https://api.flickr.com/services/rest/'
g_plus_url = 'https://www.googleapis.com/plus/v1/activities'
badge_id = 'flock-paparazzi'
http_client = None
def get_http_client():
os.environ["KRB5_CLIENT_KTNAME"] = fm_config.get("keytab")
try:
creds = Credentials(usage="initiate")
except GSSError as e:
print("GSSError trying to authenticate with Kerberos", e)
gssapi_auth = HTTPSPNEGOAuth(opportunistic_auth=True, creds=creds)
session = requests.Session()
session.auth = gssapi_auth
return session
def get_g_plus_persons(query):
token = None
while True:
params = dict(query=query, key=g_plus_key, userIP=userIP)
if token:
params['pageToken'] = token
response = requests.get(g_plus_url, params=params)
body = response.json()
token = body.get('nextPageToken', None)
# No more results
if not body.get('items', None):
break
# Otherwise, we have a page to process
for item in body['items']:
for attach in item['object'].get('attachments', []):
if attach['objectType'] == 'album':
yield item['actor']['displayName']
time.sleep(0.5) # So as to not get rate-limit banned.
def flickr_request(**kwargs):
response = requests.get(flickr_url, params=dict(
api_key=flickr_api_key,
format='json',
nojsoncallback=1,
**kwargs))
return response.json()
def get_flickr_page(tags, page=1):
return flickr_request(
method='flickr.photos.search',
content_type=1,
tags=tags,
tag_mode='all',
page=page,
)
def get_flickr_persons(tags):
pages = get_flickr_page(tags)['photos']['pages']
seen = {}
for i in range(1, pages + 1):
d = get_flickr_page(tags, i)
for photo in d['photos']['photo']:
user_id = photo['owner']
if user_id in seen:
continue
seen[user_id] = {}
# https://secure.flickr.com/services/api/flickr.people.getInfo.html
user = flickr_request(
method='flickr.people.getInfo',
user_id=user_id,
)
seen[user_id]['username1'] = user['person']['username']['_content']
seen[user_id]['username2'] = user['person']['path_alias']
if 'realname' in user['person']:
seen[user_id]['realname1'] = \
user['person']['realname']['_content']
if not seen[user_id]['realname1']:
continue
try:
seen[user_id]['realname2'] = ' '.join([
seen[user_id]['realname1'].split()[0],
seen[user_id]['realname1'].split()[-1],
])
except Exception:
import traceback
traceback.print_exc()
if "'" in seen[user_id]['realname1']:
seen[user_id]['username3'] = \
seen[user_id]['realname1'].split("'")[1]
if '"' in seen[user_id]['realname1']:
seen[user_id]['username4'] = \
seen[user_id]['realname1'].split('"')[1]
for user_id, d in seen.items():
for key, value in d.items():
yield value
def get_username(name):
# First, check if the same username exists:
response = http_client.get(
"%susers/%s/" % (fm_config['fasjson_base_url'], name)
)
if response.ok:
return name
# Now try with the human name
response = http_client.get(
"%ssearch/users/" % fm_config['fasjson_base_url'],
params={"human_name": name}
)
if not response.ok:
return None
response = response.json()
if response["page"]["total_results"] != 1:
return None
return response["result"][0]["username"]
def get_persons():
for person in get_g_plus_persons('Fedora FLOCK'):
yield person
for person in get_g_plus_persons('flocktofedora'):
yield person
for person in get_flickr_persons('fedora,flock'):
yield person
for person in get_flickr_persons('flocktofedora'):
yield person
def main():
global http_client
# First, initialize the tahrir db connection
uri = fm_config['badges_global']['database_uri']
tahrir = tahrir_api.dbapi.TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
http_client = get_http_client()
badge = tahrir.get_badge(badge_id)
already_has_it = [a.person.nickname for a in badge.assertions]
# Finally, query the two services and award as we can.
for person in get_persons():
# Try to gracefully handle non-ascii names if we can
try:
person = person.encode('utf-8')
except Exception:
import traceback
traceback.print_exc()
continue
print("* Considering", person)
username = get_username(person)
if username is not None:
if username in already_has_it:
print("Skipping %r" % username)
continue
print(" *", username, "gets the badge")
already_has_it.append(username)
email = username + "@fedoraproject.org"
try:
transaction.begin()
tahrir.add_assertion(badge_id, email, None)
transaction.commit()
time.sleep(1)
except Exception as e:
transaction.abort()
print("Failure:", e)
if __name__ == '__main__':
main()

View file

@ -1 +0,0 @@
# 40 9 * * 1 fedmsg /usr/share/badges/cronjobs/award-flock-paparazzi-badge >> /var/log/fedmsg/cron-award-flock-paparazzi-badge.log 2>&1

View file

@ -1,80 +0,0 @@
#!/usr/bin/env python
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import hashlib
import requests
import time
import transaction
from tahrir_api.dbapi import TahrirDatabase
from tahrir_api.model import Person
import fedmsg
import fedmsg.config
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
import fedbadges.utils
def main():
persons = tahrir.session.query(Person)\
.filter(Person.opt_out==False).all()
badge = tahrir.get_badge('mugshot')
already_has_it = [assertion.person for assertion in badge.assertions]
good, bad = [], []
for person in persons:
if person in already_has_it:
good.append(person)
print "Skipping %r" % person
continue
openid = "http://%s.id.fedoraproject.org/" % person.nickname
hash = hashlib.sha256(openid.encode('utf-8')).hexdigest()
url = "https://seccdn.libravatar.org/avatar/%s?d=404" % hash
response = None
for i in range(10):
print 'Try', i, 'on', url
try:
response = requests.get(url)
break
except requests.exceptions.SSLError as e:
print " * failed, trying again", str(e)
if response is None:
raise
if response.status_code == 200:
print person.nickname, "totally gets the mugshot badge."
good.append(person)
try:
transaction.begin()
tahrir.add_assertion(badge.id, person.email, None)
transaction.commit()
time.sleep(1)
except Exception as e:
transaction.abort()
print "Failure:", e
else:
bad.append(person)
print len(good), "good peoples"
print len(bad), "bad peoples"
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
main()

View file

@ -1 +0,0 @@
# 40 14 */2 * * fedmsg /usr/share/badges/cronjobs/award-libravatar-badge >> /var/log/fedmsg/cron-award-libravatar-badge.log 2>&1

View file

@ -1,165 +0,0 @@
#!/usr/bin/env python
import __main__
# This is going to require sqlalchemy 0.8 sooner than later.
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import os
import datetime
import time
import urllib
import socket
import logging
import re
from tahrir_api.dbapi import TahrirDatabase
import transaction
log = logging.getLogger()
logging.basicConfig()
import fedmsg
import fedmsg.config
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
import fedbadges.utils
import ldap
import ldap.sasl
from ldap.controls.libldap import SimplePagedResultsControl
LDAP_CONF = "/etc/openldap/ldap.conf"
class LDAPClient(object):
def __init__(self):
self.config = {}
self.conn = None
self._read_config()
def _read_config(self):
conf_re = re.compile(r"^([A-Z_]+)\s+(.+)$")
with open(LDAP_CONF) as cf:
for line in cf:
mo = conf_re.match(line.strip())
if mo is None:
continue
variable = mo.group(1)
value = mo.group(2)
self.config[variable] = value
def connect(self):
self.conn = ldap.initialize(self.config["URI"].split(" ")[0])
self.conn.protocol_version = 3
self.conn.sasl_interactive_bind_s('', ldap.sasl.gssapi())
def search(self, base, filters, attrs):
page_size = 1000
base_dn = "{base},{main_base}".format(base=base,main_base=self.config['BASE'])
page_cookie = ""
while True:
page_control = SimplePagedResultsControl(
criticality=False, size=page_size, cookie=page_cookie
)
msgid = self.conn.search_ext(
base_dn,
ldap.SCOPE_SUBTREE,
filters,
attrlist=attrs,
serverctrls=[page_control],
)
rtype, rdata, rmsgid, serverctrls = self.conn.result3(msgid)
for dn, obj in rdata:
yield obj
for ctrl in serverctrls:
if isinstance(ctrl, SimplePagedResultsControl):
page_cookie = ctrl.cookie
break
if not page_cookie:
break
def get_fas_userlist(threshold):
os.environ["KRB5_CLIENT_KTNAME"] = fm_config.get("keytab")
ldap_client = LDAPClient()
ldap_client.connect()
filters = "(&(fasCreationTime<={})(objectclass=fasUser))".format(threshold.strftime("%Y%m%d%H%M%SZ"))
response = ldap_client.search(base="cn=users,cn=accounts", filters=filters, attrs=["uid", "memberof"])
for res in response:
groups = []
for groupdn in res.get("memberof", []):
groupdn = groupdn.decode("ascii")
if not groupdn.endswith(",cn=groups,cn=accounts,{}".format(ldap_client.config['BASE'])):
continue
groupname = groupdn.split(",")[0].split("=")[1]
if groupname == "ipausers":
continue # Assume all groups are FAS groups except this one
groups.append(groupname)
yield {"username": res["uid"][0].decode("ascii"), "groups": groups}
def main():
global http_client
now = datetime.datetime.utcnow()
year = datetime.timedelta(days=365.5)
mapping = {
'egg': year * 1,
'embryo': year * 2,
'tadpole': year * 3,
'tadpole-with-legs': year * 5,
'froglet': year * 7,
'adult-frog': year * 10,
}
# First, some validation that the badge ids actually exist.
for badge_id, delta in mapping.items():
badge = tahrir.get_badge(badge_id=badge_id)
assert(badge.id)
# Then, query IPA for users created before the threshold
for badge_id, delta in mapping.items():
badge = tahrir.get_badge(badge_id=badge_id)
threshold = now - delta
for person in get_fas_userlist(threshold):
if len(person["groups"]) < 2:
continue
hit_em_up(badge, person)
def hit_em_up(badge, fas_user):
email = fas_user["username"] + "@fedoraproject.org"
user = tahrir.get_person(email)
if not user:
return
if tahrir.assertion_exists(badge.id, email):
print email, "already has", badge.id, "skipping."
return
time.sleep(1)
print "awarding", badge.id, "to", email
try:
transaction.begin()
tahrir.add_assertion(badge.id, email, None)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
main()

View file

@ -1,131 +0,0 @@
#!/usr/bin/env python
import __main__
# This is going to require sqlalchemy 0.8 sooner than later.
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import datetime
import time
import urllib
import socket
from tahrir_api.dbapi import TahrirDatabase
import transaction
_fas_cache = {}
import logging
log = logging.getLogger()
logging.basicConfig()
import fedora.client.fas2
import fedmsg
import fedmsg.config
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
import fedbadges.utils
#a simple listcomp to generate a lists of searchterms
#allows us to break the fas userlist down to smaller chunks
#so the cron job doesn't hang
def get_fas_searchterm():
ast = "*"
alpha = map(chr, range(97, 123))
searchterms = [ term_str + ast for term_str in alpha ]
return searchterms
def get_fas_userlist(fas_credentials):
creds = fas_credentials
fasclient = fedora.client.fas2.AccountSystem(
username=creds['username'],
password=creds['password'],
)
timeout
timeout = socket.getdefaulttimeout()
socket.setdefaulttimeout(600)
searchterm = get_fas_searchterms()
for search_elem in searchterm:
try:
log.info("Downloading FAS cache")
request = fasclient.send_request('/user/list',
req_params={'search': search_elem},
auth=True)
fas_userlist.update(request)
finally:
socket.setdefaulttimeout(timeout)
# We don't actually check for CLA+1, just "2 groups"
return [p for p in fas_userlist['people'] if len(p.memberships) > 1]
def main():
now = datetime.datetime.utcnow()
year = datetime.timedelta(days=365.5)
search_terms = get_fas_searchterms()
mapping = {
'egg': year * 1,
'embryo': year * 2,
'tadpole': year * 3,
'tadpole-with-legs': year * 5,
'froglet': year * 7,
'adult-frog': year * 10,
}
# First, some validation that the badge ids actually exist.
for badge_id, delta in mapping.items():
badge = tahrir.get_badge(badge_id=badge_id)
assert(badge.id)
# Then, do a long query against FAS for our candidates.
# looping over a list of search terms allows us to work around the socket timeout
results = get_fas_userlist(fas_credentials=fm_config['fas_credentials'])
for badge_id, delta in mapping.items():
badge = tahrir.get_badge(badge_id=badge_id)
for person in results:
creation = datetime.datetime.strptime(
person.creation.split('.')[0], '%Y-%m-%d %H:%M:%S')
if now - creation > delta:
hit_em_up(badge, person)
def hit_em_up(badge, fas_user):
email = fas_user.username + "@fedoraproject.org"
user = tahrir.get_person(email)
if not user:
return
if tahrir.assertion_exists(badge.id, email):
print email, "already has", badge.id, "skipping."
return
time.sleep(1)
print "awarding", badge.id, "to", email
try:
transaction.begin()
tahrir.add_assertion(badge.id, email, None)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
main()

View file

@ -1 +0,0 @@
# 40 2 * * 3 fedmsg /usr/share/badges/cronjobs/award-lifecycle-badges >> /var/log/fedmsg/cron-award-lifecycle-badges.log 2>&1

View file

@ -1,80 +0,0 @@
#!/usr/bin/env python
import __main__
# This is going to require sqlalchemy 0.8 sooner than later.
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"]
import pkg_resources
pkg_resources.require(__requires__)
import requests
import time
from tahrir_api.dbapi import TahrirDatabase
import transaction
import logging
log = logging.getLogger()
logging.basicConfig()
import fedmsg
import fedmsg.config
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
import fedbadges.utils
def main():
url = 'https://admin.fedoraproject.org/mirrormanager/api/mirroradmins'
response = requests.get(url)
if response.status_code != 200:
raise IOError("Couldn't read the mirrormanager/mirroradmins list.")
usernames = response.json()['admins']
badge = tahrir.get_badge(badge_id='mirror,-mirror-on-the-wall')
if not badge:
raise ValueError("badge does not exist")
for username in usernames:
email = username + "@fedoraproject.org"
person = tahrir.get_person(person_email=email)
if not person:
print email, "does not exist. Creating."
try:
transaction.begin()
tahrir.add_person(email, nickname=username)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
continue
if tahrir.assertion_exists(badge.id, email):
print email, "already has", badge.id, "skipping."
continue
time.sleep(1)
print "awarding", badge.id, "to", email
try:
transaction.begin()
tahrir.add_assertion(badge.id, email, None)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
main()

View file

@ -1 +0,0 @@
# 20 */2 * * * fedmsg /usr/share/badges/cronjobs/award-mirror-badge >> /var/log/fedmsg/cron-award-mirror-badge.log 2>&1

View file

@ -1,175 +0,0 @@
#!/usr/bin/env python
import __main__
# This is going to require sqlalchemy 0.8 sooner than later.
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import os
import itertools
import string
import time
import urllib
import socket
from hashlib import md5
import getpass
import pprint
from collections import defaultdict
from gssapi import Credentials
from gssapi.exceptions import GSSError
from requests_gssapi import HTTPSPNEGOAuth
from tahrir_api.dbapi import TahrirDatabase
import transaction
import requests
import logging
log = logging.getLogger()
logging.basicConfig(level=logging.INFO)
import fedora.client.fas2
import fedmsg
import fedmsg.config
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
import fedbadges.utils
def get_http_client():
os.environ["KRB5_CLIENT_KTNAME"] = fm_config.get("keytab")
try:
creds = Credentials(usage="initiate")
except GSSError as e:
log.error("GSSError trying to authenticate with Kerberos", e)
gssapi_auth = HTTPSPNEGOAuth(opportunistic_auth=True, creds=creds)
session = requests.Session()
session.auth = gssapi_auth
return session
def get_fas_groupings(fas_credentials, lookup, **config):
results = defaultdict(list)
membership_types = ("members", "sponsors")
http_client = get_http_client()
for group_name, badge_id in lookup.iteritems():
# This is the main check.
for membership_type in membership_types:
url = "%sgroups/%s/%s/" % (
fm_config['fasjson_base_url'],
group_name,
membership_type
)
response = http_client.get(url)
if not response.ok:
continue
for user in response.json()["result"]:
username = user["username"]
results[group_name].append(username)
# Beyond the main check, here is a special check for the sponsors of the packager and ambassadors groups
if membership_type != "sponsors":
continue
if group_name == "packager":
results["sponsors"].append(username)
elif group_name == "ambassadors":
results["ambassadors_sponsors"].append(username)
return results
def main():
d = {}
print "fascache.db code is commented out -- querying fas."
# A mapping of fas groups to badge ids
mapping = {
'3d-printing-sig': '3d-printing-sig-member',
'cla_done': 'involvement',
'advocates': 'fedora-advocate',
'ambassadors': 'ambassador',
'ambassadors_sponsors': 'ambassadors-sponsor',
'commops': 'commops-superstar',
'council': 'council-member',
'designteam': 'pixel-ninja',
'dotnet-team': 'dotnet-sig-member',
'fedora-hams': 'amateur-radio-sig-member',
'fi-apprentice': 'no-longer-a-ronin',
'gitfedora-web': 'rock-the-web!',
'git-fedora-electronic-lab': 'fel-member',
'iot': 'iot-working-group-member',
'irc-support-operators':
'your-call-may-be-monitored-for-quality-assurance',
'kde-sig': 'kde-sig',
'lxqt-sig': 'lxqt-sig-member',
'marketing': 'called-to-action',
'mindshare': 'meeting-of-the-minds',
'modularity-wg': 'modularity-wg-member',
'neuro-sig': 'neurofedora-sig-member',
'provenpackager': 'proven-packager',
'proventesters': 'proven-tester',
'robotics-sig': 'domo-arigato',
'ruby-sig': 'ruby-sig-member',
'security-team': 'security-team',
'sponsors': 'packager-sponsor',
'summer-coding': 'summer-coder',
'sysadmin-main': 'trust-me,-i-know-what-i-am-doing',
'sysadmin-badges': 'inside-job',
'videos': 'videographer',
}
# First, some validation that the badge ids actually exist.
for fas_group, badge_id in mapping.items():
badge = tahrir.get_badge(badge_id=badge_id)
if not badge:
raise ValueError("%r is not a valid badge id" % badge_id)
# Then, do a long query against FAS for our candidates.
results = get_fas_groupings(fas_credentials=fm_config['fas_credentials'],
lookup=mapping)
for fas_group, members in results.iteritems():
print fas_group, "had", len(members), "members for", mapping[fas_group]
for fas_group, members in results.iteritems():
print "processing", fas_group
print "======================"
badge = tahrir.get_badge(badge_id=mapping[fas_group])
hit_em_up(badge, members)
def hit_em_up(badge, members):
for username in members:
email = username + "@fedoraproject.org"
user = tahrir.get_person(email)
if not user:
continue
if tahrir.assertion_exists(badge.id, email):
print email, "already has", badge.id, "skipping."
continue
time.sleep(1)
print "awarding", badge.id, "to", email
try:
transaction.begin()
tahrir.add_assertion(badge.id, email, None)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
main()

View file

@ -1 +0,0 @@
# 25 13 * * * root /usr/share/badges/cronjobs/award-oldschool-badges >> /var/log/fedmsg/cron-award-oldschool-badges.log 2>&1

View file

@ -1,564 +0,0 @@
# This file is a part of datanommer, a message sink for fedmsg.
# Copyright (C) 2014, Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
# This is a Python2-compatible file for the apps that are still running on Python2.
# Compatibility fixes done by pasteurize: http://python-future.org/pasteurize.html
from __future__ import absolute_import, division, print_function, unicode_literals
import datetime
import json
import logging
import math
import traceback
import uuid
from warnings import warn
import pkg_resources
from sqlalchemy import (
and_,
between,
Column,
create_engine,
DateTime,
DDL,
event,
ForeignKey,
Integer,
not_,
or_,
String,
Table,
TypeDecorator,
Unicode,
UnicodeText,
UniqueConstraint,
)
from sqlalchemy.dialects import postgresql
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, scoped_session, sessionmaker, validates
from sqlalchemy.sql import operators
try:
from psycopg2.errors import UniqueViolation
except ImportError: # pragma: no cover
from psycopg2.errorcodes import lookup as lookup_error
UniqueViolation = lookup_error("23505")
log = logging.getLogger("datanommer")
maker = sessionmaker()
session = scoped_session(maker)
DeclarativeBase = declarative_base()
DeclarativeBase.query = session.query_property()
def init(uri=None, alembic_ini=None, engine=None, create=False):
"""Initialize a connection. Create tables if requested."""
if uri and engine:
raise ValueError("uri and engine cannot both be specified")
if uri is None and not engine:
raise ValueError("One of uri or engine must be specified")
if uri and not engine:
engine = create_engine(uri)
# We need to hang our own attribute on the sqlalchemy session to stop
# ourselves from initializing twice. That is only a problem if the code
# calling us isn't consistent.
if getattr(session, "_datanommer_initialized", None):
log.warning("Session already initialized. Bailing")
return
session._datanommer_initialized = True
session.configure(bind=engine)
DeclarativeBase.query = session.query_property()
if create:
session.execute("CREATE EXTENSION IF NOT EXISTS timescaledb")
DeclarativeBase.metadata.create_all(engine)
# Loads the alembic configuration and generates the version table, with
# the most recent revision stamped as head
if alembic_ini is not None: # pragma: no cover
from alembic import command
from alembic.config import Config
alembic_cfg = Config(alembic_ini)
command.stamp(alembic_cfg, "head")
def add(message):
"""Take a the fedora-messaging Message and store in the message
table.
"""
headers = message._properties.headers
sent_at = headers.get("sent-at", None)
if sent_at:
# fromisoformat doesn't parse Z suffix (yet) see:
# https://discuss.python.org/t/parse-z-timezone-suffix-in-datetime/2220
try:
sent_at = datetime.datetime.fromisoformat(sent_at.replace("Z", "+00:00"))
except ValueError:
log.exception("Failed to parse sent-at timestamp value")
return
else:
sent_at = datetime.datetime.utcnow()
# Workaround schemas misbehaving
try:
usernames = message.usernames
except Exception:
log.exception(
"Could not get the list of users from a message on %s with id %s",
message.topic,
message.id,
)
usernames = []
try:
packages = message.packages
except Exception:
log.exception(
"Could not get the list of packages from a message on %s with id %s",
message.topic,
message.id,
)
packages = []
Message.create(
i=0,
msg_id=message.id,
topic=message.topic,
timestamp=sent_at,
msg=message.body,
headers=headers,
users=usernames,
packages=packages,
)
session.commit()
def source_version_default(context):
dist = pkg_resources.get_distribution("datanommer.models")
return dist.version
# https://docs.sqlalchemy.org/en/14/core/custom_types.html#marshal-json-strings
class JSONEncodedDict(TypeDecorator):
"""Represents an immutable structure as a json-encoded string."""
impl = UnicodeText
cache_ok = True
def process_bind_param(self, value, dialect):
if value is not None:
value = json.dumps(value)
return value
def process_result_value(self, value, dialect):
if value is not None:
value = json.loads(value)
return value
def coerce_compared_value(self, op, value):
# https://docs.sqlalchemy.org/en/14/core/custom_types.html#dealing-with-comparison-operations
if op in (operators.like_op, operators.not_like_op):
return String()
else:
return self
users_assoc_table = Table(
"users_messages",
DeclarativeBase.metadata,
Column("user_id", ForeignKey("users.id"), primary_key=True),
Column("msg_id", Integer, primary_key=True, index=True),
Column("msg_timestamp", DateTime, primary_key=True, index=True),
)
packages_assoc_table = Table(
"packages_messages",
DeclarativeBase.metadata,
Column("package_id", ForeignKey("packages.id"), primary_key=True),
Column("msg_id", Integer, primary_key=True, index=True),
Column("msg_timestamp", DateTime, primary_key=True, index=True),
)
class Message(DeclarativeBase):
__tablename__ = "messages"
__table_args__ = (UniqueConstraint("msg_id", "timestamp"),)
id = Column(Integer, primary_key=True, autoincrement=True)
msg_id = Column(Unicode, nullable=True, default=None, index=True)
i = Column(Integer, nullable=False)
topic = Column(Unicode, nullable=False, index=True)
timestamp = Column(DateTime, nullable=False, index=True, primary_key=True)
certificate = Column(UnicodeText)
signature = Column(UnicodeText)
category = Column(Unicode, nullable=False, index=True)
username = Column(Unicode)
crypto = Column(UnicodeText)
source_name = Column(Unicode, default="datanommer")
source_version = Column(Unicode, default=source_version_default)
msg = Column(JSONEncodedDict, nullable=False)
headers = Column(postgresql.JSONB(none_as_null=True))
users = relationship(
"User",
secondary=users_assoc_table,
backref="messages",
primaryjoin=lambda: and_(
Message.id == users_assoc_table.c.msg_id,
Message.timestamp == users_assoc_table.c.msg_timestamp,
),
)
packages = relationship(
"Package",
secondary=packages_assoc_table,
backref="messages",
primaryjoin=lambda: and_(
Message.id == packages_assoc_table.c.msg_id,
Message.timestamp == packages_assoc_table.c.msg_timestamp,
),
)
@validates("topic")
def get_category(self, key, topic):
"""Update the category when the topic is set.
The method seems... unnatural. But even zzzeek says it's OK to do it:
https://stackoverflow.com/a/6442201
"""
index = 2 if "VirtualTopic" in topic else 3
try:
self.category = topic.split(".")[index]
except Exception:
traceback.print_exc()
self.category = "Unclassified"
return topic
@classmethod
def create(cls, **kwargs):
users = kwargs.pop("users")
packages = kwargs.pop("packages")
if not kwargs.get("msg_id"):
log.info("Message on %s was received without a msg_id", kwargs["topic"])
kwargs["msg_id"] = str(uuid.uuid4())
obj = cls(**kwargs)
try:
session.add(obj)
session.flush()
except IntegrityError as e:
if isinstance(e.orig, UniqueViolation):
log.warning(
"Skipping message from %s with duplicate id: %s",
kwargs["topic"],
kwargs["msg_id"],
)
else:
log.exception(
"Unknown Integrity Error: message %s with id %s",
kwargs["topic"],
kwargs["msg_id"],
)
session.rollback()
return
obj._insert_list(User, users_assoc_table, users)
obj._insert_list(Package, packages_assoc_table, packages)
def _insert_list(self, rel_class, assoc_table, values):
if not values:
return
assoc_col_name = assoc_table.c[0].name
insert_values = []
for name in set(values):
attr_obj = rel_class.get_or_create(name)
# This would normally be a simple "obj.[users|packages].append(name)" kind
# of statement, but here we drop down out of sqlalchemy's ORM and into the
# sql abstraction in order to gain a little performance boost.
insert_values.append(
{
assoc_col_name: attr_obj.id,
"msg_id": self.id,
"msg_timestamp": self.timestamp,
}
)
session.execute(assoc_table.insert(), insert_values)
session.flush()
@classmethod
def from_msg_id(cls, msg_id):
return cls.query.filter(cls.msg_id == msg_id).first()
def as_dict(self, request=None):
return dict(
i=self.i,
msg_id=self.msg_id,
topic=self.topic,
timestamp=self.timestamp,
certificate=self.certificate,
signature=self.signature,
username=self.username,
crypto=self.crypto,
msg=self.msg,
headers=self.headers,
source_name=self.source_name,
source_version=self.source_version,
users=list(sorted(u.name for u in self.users)),
packages=list(sorted(p.name for p in self.packages)),
)
def as_fedora_message_dict(self):
headers = self.headers
if "sent-at" not in headers:
headers["sent-at"] = self.timestamp.astimezone(
datetime.timezone.utc
).isoformat()
return dict(
body=self.msg,
headers=headers,
id=self.msg_id,
queue=None,
topic=self.topic,
)
def __json__(self, request=None):
warn(
"The __json__() method has been renamed to as_dict(), and will be removed "
"in the next major version",
DeprecationWarning,
)
return self.as_dict(request)
@classmethod
def grep(
cls,
start=None,
end=None,
page=1,
rows_per_page=100,
order="asc",
msg_id=None,
users=None,
not_users=None,
packages=None,
not_packages=None,
categories=None,
not_categories=None,
topics=None,
not_topics=None,
contains=None,
defer=False,
):
"""Flexible query interface for messages.
Arguments are filters. start and end should be :mod:`datetime` objs.
Other filters should be lists of strings. They are applied in a
conjunctive-normal-form (CNF) kind of way
for example, the following::
users = ['ralph', 'lmacken']
categories = ['bodhi', 'wiki']
should return messages where
(user=='ralph' OR user=='lmacken') AND
(category=='bodhi' OR category=='wiki')
Furthermore, you can use a negative version of each argument.
users = ['ralph']
not_categories = ['bodhi', 'wiki']
should return messages where
(user == 'ralph') AND
NOT (category == 'bodhi' OR category == 'wiki')
----
If the `defer` argument evaluates to True, the query won't actually
be executed, but a SQLAlchemy query object returned instead.
"""
users = users or []
not_users = not_users or []
packages = packages or []
not_packs = not_packages or []
categories = categories or []
not_cats = not_categories or []
topics = topics or []
not_topics = not_topics or []
contains = contains or []
query = Message.query
# A little argument validation. We could provide some defaults in
# these mixed cases.. but instead we'll just leave it up to our caller.
if (start is not None and end is None) or (end is not None and start is None):
raise ValueError(
"Either both start and end must be specified "
"or neither must be specified"
)
if start and end:
query = query.filter(between(Message.timestamp, start, end))
if msg_id:
query = query.filter(Message.msg_id == msg_id)
# Add the four positive filters as necessary
if users:
query = query.filter(
or_(*(Message.users.any(User.name == u) for u in users))
)
if packages:
query = query.filter(
or_(*(Message.packages.any(Package.name == p) for p in packages))
)
if categories:
query = query.filter(
or_(*(Message.category == category for category in categories))
)
if topics:
query = query.filter(or_(*(Message.topic == topic for topic in topics)))
if contains:
query = query.filter(
or_(
*(Message._msg.like("%{}%".format(contain) for contain in contains))
)
)
# And then the four negative filters as necessary
if not_users:
query = query.filter(
not_(or_(*(Message.users.any(User.name == u) for u in not_users)))
)
if not_packs:
query = query.filter(
not_(or_(*(Message.packages.any(Package.name == p) for p in not_packs)))
)
if not_cats:
query = query.filter(
not_(or_(*(Message.category == category for category in not_cats)))
)
if not_topics:
query = query.filter(
not_(or_(*(Message.topic == topic for topic in not_topics)))
)
# Finally, tag on our pagination arguments
total = query.count()
query = query.order_by(getattr(Message.timestamp, order)())
if rows_per_page is None:
pages = 1
else:
pages = int(math.ceil(total / float(rows_per_page)))
query = query.offset(rows_per_page * (page - 1)).limit(rows_per_page)
if defer:
return total, page, query
else:
# Execute!
messages = query.all()
return total, pages, messages
class NamedSingleton(object):
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(UnicodeText, index=True, unique=True)
@classmethod
def get_or_create(cls, name):
"""
Return the instance of the class with the specified name. If it doesn't
already exist, create it.
"""
# Use an in-memory cache to speed things up.
if name in cls._cache:
# If we cache the instance, SQLAlchemy will run this query anyway because the instance
# will be from a different transaction. So just cache the id.
return cls.query.get(cls._cache[name])
obj = cls.query.filter_by(name=name).one_or_none()
if obj is None:
obj = cls(name=name)
session.add(obj)
session.flush()
cls._cache[name] = obj.id
return obj
@classmethod
def clear_cache(cls):
cls._cache.clear()
class User(DeclarativeBase, NamedSingleton):
__tablename__ = "users"
_cache = {}
class Package(DeclarativeBase, NamedSingleton):
__tablename__ = "packages"
_cache = {}
def _setup_hypertable(table_class):
event.listen(
table_class.__table__,
"after_create",
DDL("SELECT create_hypertable('%s', 'timestamp');" % table_class.__tablename__),
)
_setup_hypertable(Message)
# Set the version
try: # pragma: no cover
import importlib.metadata
__version__ = importlib.metadata.version("datanommer.models")
except ImportError: # pragma: no cover
try:
__version__ = pkg_resources.get_distribution("datanommer.models").version
except pkg_resources.DistributionNotFound:
# The app is not installed, but the flask dev server can run it nonetheless.
__version__ = None

View file

@ -1,81 +0,0 @@
#!/usr/bin/env python
""" This is a CLI script for delete a badge entirely.
It will fail if anyone currently holds that badge.
In the event that you really really want to delete a badge that people already
have, please first use the `revoke-badge` script on all of them first.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--badge', default=None, help="A badge id")
args = parser.parse_args()
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, badge_id):
badge = tahrir.get_badge(badge_id)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
badge_holders = [assertion.person for assertion in badge.assertions]
if badge_holders:
print "%i people have the %r badge. revoke it from them first" % (
len(badge_holders), badge_id)
for person in badge_holders:
print person.nickname
return
print "deleting", badge_id
try:
transaction.begin()
tahrir.session.delete(badge)
tahrir.session.commit()
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.badge)

View file

@ -1,92 +0,0 @@
#!/usr/bin/env python
""" This is a CLI script for editing the properties of a badge. """
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--badge', default=None, help="A badge id")
# XXX - Note, this script intentionally does not allow changing the badge-id
# of a badge. Some things depend on that field as a foreign key and it is
# unclear what would break if we changed that.
parser.add_argument('--name', default=None, help='Name..')
parser.add_argument('--description', default=None, help='Description..')
parser.add_argument('--criteria', default=None, help='Criteria link')
parser.add_argument('--image', default=None, help='Image link')
parser.add_argument('--tags', default=None, help='Badge Tags')
args = parser.parse_args()
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
if not args.name and not args.description and not args.criteria and not args.image and not args.tags:
print "You must specify either name, description or criteria, tags or image to edit."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, badge_id, name, description, criteria, image, tags):
badge = tahrir.get_badge(badge_id)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
transaction.begin()
if name:
badge.name = name
print "Setting name on %r to %r" % (badge_id, name)
if description:
badge.description = description
print "Setting description on %r to %r" % (badge_id, description)
if criteria:
badge.criteria = criteria
print "Setting criteria on %r to %r" % (badge_id, criteria)
if image:
badge.image = image
print "Setting image on %r to %r" % (badge_id, image)
if tags:
badge.tags = tags
print "Setting tags on %r to %r" % (badge_id, tags)
tahrir.session.commit()
transaction.commit()
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.badge, args.name, args.description, args.criteria,
args.image, args.tags)

View file

@ -1,60 +0,0 @@
#!/usr/bin/env python
""" This is a CLI script for retrieving a person's id in the badges db given
their FAS username.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--user', default=None, help="A FAS username")
args = parser.parse_args()
if not args.user:
print "You must specify a FAS username."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, nickname):
person = tahrir.get_person(nickname=nickname)
if not person:
print "No such person %r" % nickname
sys.exit(1)
print person.nickname, "has the id", person.id
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.user)

View file

@ -1,80 +0,0 @@
#!/usr/bin/env python
""" This is a CLI script for getting all the details of a person
"""
from __future__ import print_function
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"]
import pkg_resources
pkg_resources.require(__requires__)
import json
import os
import sys
from tahrir_api.dbapi import TahrirDatabase
import fedmsg.config
import fedbadges.utils
def initialize():
fm_config = fedmsg.config.load_config()
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main():
tahrir = initialize()
nickname = os.getenv('SAR_USERNAME')
if not nickname:
print('An username is required to query datagrepper')
return 1
payload = {}
person = tahrir.get_person(nickname=nickname)
if not person:
print('No such person %r' % nickname)
return 1
payload = {
'id': person.id,
'nickname': nickname,
'email': person.email,
'website': person.website,
'bio': person.bio,
'created_on': person.created_on.isoformat(),
'last_login': person.last_login.isoformat()
if person.last_login else 'unknown',
'opt_out': person.opt_out,
'rank': person.rank,
'assertions': []
}
assertions = tahrir.get_assertions_by_email(person.email)
if assertions:
assertion_list = []
for assertion in assertions:
assertion_list.append({
'badge_id': assertion.badge_id,
'issued_on': assertion.issued_on.isoformat()
})
payload['assertions'] = assertion_list
print(json.dumps(
payload, sort_keys=True, indent=4, separators=(',', ': ')
).encode('utf-8'))
if __name__ == '__main__':
sys.exit(main())

View file

@ -1,76 +0,0 @@
#!/usr/bin/env python
"""
This is a CLI script for granting authorization on a single badge to somebody.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--user', default=None, help="A FAS username")
parser.add_argument('--badge', default=None, help="A badge id")
args = parser.parse_args()
if not args.user:
print "You must specify a FAS username."
sys.exit(1)
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, nickname, badge_id):
person = tahrir.get_person(nickname=nickname)
badge = tahrir.get_badge(badge_id)
if not person:
print "No such person %r" % nickname
sys.exit(1)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
print "granting", person.nickname, "rights to %r." % badge_id
try:
transaction.begin()
tahrir.add_authorization(badge_id, person.email)
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.user, args.badge)

View file

@ -1,69 +0,0 @@
#!/usr/bin/env python
"""
This is a CLI script for listing that are authorized on a badge.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import tahrir_api.model
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--badge', default=None, help="A badge id")
args = parser.parse_args()
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, badge_id):
badge = tahrir.get_badge(badge_id)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
authz = tahrir.session.query(tahrir_api.model.Authorization)\
.filter(tahrir_api.model.Authorization.badge_id==badge.id)\
.all()
if not authz:
print "no-one is authorized for %r badge..." % (badge_id)
return
for person in [assertion.person for assertion in authz]:
print person.nickname
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.badge)

View file

@ -1,90 +0,0 @@
#!/usr/bin/env python
"""
This is a CLI script for revoking an authorization that a user has on a badge.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import tahrir_api.model
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--user', default=None, help="A FAS username")
parser.add_argument('--badge', default=None, help="A badge id")
args = parser.parse_args()
if not args.user:
print "You must specify a FAS username."
sys.exit(1)
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, nickname, badge_id):
person = tahrir.get_person(nickname=nickname)
badge = tahrir.get_badge(badge_id)
if not person:
print "No such person %r" % nickname
sys.exit(1)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
authz = tahrir.session.query(tahrir_api.model.Authorization)\
.filter(tahrir_api.model.Authorization.badge_id==badge.id)\
.filter(tahrir_api.model.Authorization.person_id==person.id)\
.all()
if not authz:
print "%r does not have authz on %r badge..." % (nickname, badge_id)
return
print "Found these pre-existing entries: %r" % authz
print "removing", person.nickname, "from authz on %r." % badge_id
try:
transaction.begin()
for item in authz:
print " deleting:", item
tahrir.session.delete(item)
tahrir.session.commit()
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.user, args.badge)

View file

@ -1,94 +0,0 @@
#!/usr/bin/env python
""" This is a CLI script for revoking a single badge from a single person.
The intent is to use it to batch revoke a badge from a list of people.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--user', default=None, help="A FAS username")
parser.add_argument('--badge', default=None, help="A badge id")
args = parser.parse_args()
if not args.user:
print "You must specify a FAS username."
sys.exit(1)
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, nickname, badge_id):
person = tahrir.get_person(nickname=nickname)
badge = tahrir.get_badge(badge_id)
if not person:
print "No such person %r" % nickname
sys.exit(1)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
already_has_it = [assertion.person for assertion in badge.assertions]
if person not in already_has_it:
print "%r does not actually have the %r badge..." % (nickname, badge_id)
return
print "removing", person.nickname, "from the %r badge." % badge_id
try:
transaction.begin()
to_delete = None
for assertion in person.assertions:
if assertion.badge == badge:
to_delete = assertion
break
if to_delete:
#person.assertions.remove(to_delete)
tahrir.session.delete(to_delete)
tahrir.session.commit()
else:
raise ValueError("no such assertion found. weird.")
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.user, args.badge)

View file

@ -1,79 +0,0 @@
#!/usr/bin/env python
"""
This is a CLI script for revoking all invitations on a badge.
"""
import __main__
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)
import argparse
import transaction
import sys
from tahrir_api.dbapi import TahrirDatabase
import tahrir_api.model
import fedmsg
import fedmsg.config
import fedbadges.utils
def parse_args():
parser = argparse.ArgumentParser(__doc__)
parser.add_argument('--badge', default=None, help="A badge id")
args = parser.parse_args()
if not args.badge:
print "You must specify a badge id."
sys.exit(1)
return args
def initialize():
fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)
uri = fm_config['badges_global']['database_uri']
tahrir = TahrirDatabase(
uri,
notification_callback=fedbadges.utils.notification_callback,
)
return tahrir
def main(tahrir, badge_id):
badge = tahrir.get_badge(badge_id)
if not badge:
print "No such badge %r" % badge_id
sys.exit(1)
invites = tahrir.session.query(tahrir_api.model.Invitation)\
.filter(tahrir_api.model.Invitation.badge_id==badge.id)\
.all()
if not invites:
print "There are no invitations on %r badge..." % badge_id
return
print "Found %r invitation(s)" % len(invites)
try:
transaction.begin()
for item in invites:
print " deleting:", item
tahrir.session.delete(item)
tahrir.session.commit()
transaction.commit()
except Exception as e:
transaction.abort()
print "Failure:", e
if __name__ == '__main__':
args = parse_args()
tahrir = initialize()
main(tahrir, args.badge)

View file

@ -1,6 +0,0 @@
#!/bin/bash
set -e
cd /srv/badges_checkout/
git pull >/dev/null 2>&1
( rsync --delete -ar --itemize-changes /srv/badges_checkout/rules/ /usr/share/badges/rules/ | grep -q '^>f' ) && /sbin/service fedmsg-hub restart

View file

@ -1,234 +0,0 @@
---
# Configuration for the fedbadges consumer
- name: install needed packages
package:
name: "{{ item }}"
state: present
with_items:
- python-fedbadges
- python-psycopg2
- git
- python-dogpile-cache
- postgresql
- python-gssapi
- python-requests-gssapi
- python-requests
tags:
- packages
- badges
- badges/backend
- name: copy database configuration
template:
src: "{{ item }}"
dest: "/etc/fedmsg.d/{{ item }}"
owner: fedmsg
group: fedmsg
mode: 0600
with_items:
- datanommer.py
- badges-awarder.py
tags:
- config
- badges
- badges/backend
notify:
- restart fedmsg-hub
- name: copy alembic configuration
template:
src: alembic.ini
dest: /usr/share/tahrir_api/alembic.ini
owner: fedmsg
group: fedmsg
mode: 0600
tags:
- config
- badges
- badges/backend
- name: make badge definition directory
file:
path: /usr/share/badges/rules
state: directory
owner: fedmsg
group: fedmsg
mode: 0755
tags:
- config
- badges
- badges/backend
- name: create checkout dir
file:
name: /srv/badges_checkout
state: directory
tags:
- badges
- badges/backend
- name: clone directory
git:
repo: https://pagure.io/fedora-badges.git
dest: /srv/badges_checkout
tags:
- badges
- badges/backend
- name: add script
copy:
dest: /usr/local/bin/update_checkout.sh
src: update_checkout.sh
mode: 0755
tags:
- badges
- badges/backend
- name: add cron for update
cron:
name: "update checkout"
job: /usr/local/bin/update_checkout.sh
minute: "*/15"
tags:
- badges
- badges/backend
- name: ensure the fedmsg user has a homedir for cron to work
file:
state: directory
path: /usr/share/fedmsg
mode: 0700
owner: fedmsg
group: fedmsg
when: env != "staging"
tags:
- config
- cron
- badges
- badges/backend
- name: ensure badges cron directories exist
file:
state: directory
path: "{{ item }}"
mode: 0755
owner: root
when: env != "staging"
with_items:
- /usr/share/badges/cronjobs/
- /etc/cron.d/
tags:
- config
- cron
- badges
- badges/backend
- name: oldschool badge award scripts
copy:
src: "cron/{{ item }}"
dest: "/usr/share/badges/cronjobs/{{ item }}"
owner: fedmsg
mode: 0744
when: env != "staging"
with_items:
- award-oldschool-badges
- award-libravatar-badge
- award-flock-paparazzi-badge
- award-mirror-badge
- award-lifecycle-badges
- award-badges-dev-badge
tags:
- config
- cron
- badges
- badges/backend
- name: oldschool badge award cronjobs
copy:
src: "cron/{{ item }}.cron"
dest: "/etc/cron.d/{{ item }}"
owner: root
mode: 0644
when: env != "staging"
with_items:
- award-oldschool-badges
- award-libravatar-badge
- award-flock-paparazzi-badge
- award-mirror-badge
- award-lifecycle-badges
- award-badges-dev-badge
tags:
- config
- cron
- badges
- badges/backend
- name: copy creds for the flock paparazzi cronjob
template:
src: flock-paparazzi.ini
dest: /etc/flock-paparazzi.ini
owner: fedmsg
group: fedmsg
mode: 0600
tags:
- config
- cron
- badges
- badges/backend
- name: remove old logrotate file we used to put in place.
file:
dest: /etc/logrotate.d/cron-badges-logrotate
state: absent
tags:
- config
- cron
- badges
- badges/backend
- name: copy over the badge-admin one-off scripts
copy:
src: "{{ item }}"
dest: "/usr/local/bin/{{ item }}"
owner: root
group: sysadmin-badges
mode: 0750
with_items:
- edit-badge
- award-badge
- revoke-badge
- delete-badge
- grant-authorization
- revoke-authorization
- get-badges-person-id
tags:
- scripts
- badges
- badges/backend
- name: copy get-sar-person-details
copy:
src: get-sar-person-details
dest: /usr/local/bin/get-sar-person-details
owner: fedmsg
group: fedmsg
mode: 0700
tags:
- scripts
- badges
- badges/backend
- sar
# Deprecated service, will be retired
- name: fedmsg-hub service
service: name=fedmsg-hub state=stopped enabled=no
# https://raw.githubusercontent.com/fedora-infra/datanommer/python2/datanommer.models/datanommer/models/__init__.py
- name: hotfix datanommer.models with version from python2 branch
copy:
src: datanommer.models__init__.py
dest: /usr/lib/python2.7/site-packages/datanommer/models/__init__.py
tags:
- badges
- badges/backend

View file

@ -1,56 +0,0 @@
# A generic, single database configuration.
[alembic]
# path to migration scripts
script_location = /usr/share/tahrir_api/alembic/
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s
# max length of characters to apply to the
# "slug" field
#truncate_slug_length = 40
# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false
{% if env == 'staging' %}
sqlalchemy.url = postgresql://{{tahrirDBUser}}:{{tahrirstgDBPassword}}@db-tahrir/tahrir
{% else %}
sqlalchemy.url = postgresql://{{tahrirDBUser}}:{{tahrirDBPassword}}@db-tahrir/tahrir
{% endif %}
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
qualname =
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

View file

@ -1,55 +0,0 @@
config = {
# We need to tell the fedmsg-hub that it should load our consumer on start.
"fedmsg.consumers.badges.enabled": True,
"moksha.workers_per_consumer": 7,
"moksha.threadpool_size": 8,
# This tells the consumer where to look for its BadgeRule definitions. It
# may be a relative or an absolute path on the file system.
"badges.yaml.directory": "/usr/share/badges/rules",
# This is a dictionary of tahrir-related configuration
"badges_global": {
# This is a sqlalchemy URI that points to the tahrir DB.
{% if env == 'staging' %}
"database_uri": "postgresql://{{tahrirDBUser}}:{{tahrirstgDBPassword}}@db01.stg.iad2.fedoraproject.org/tahrir",
{% else %}
"database_uri": "postgresql://{{tahrirDBUser}}:{{tahrirDBPassword}}@db-tahrir/tahrir",
{% endif %}
# This is a set of data that tells our consumer what Open Badges Issuer
# should be kept as the issuer of all the badges we create.
"badge_issuer": dict(
issuer_id='Fedora Project',
issuer_origin='https://apps.fedoraproject.org',
issuer_name='Fedora Project',
issuer_org='http://fedoraproject.org',
issuer_contact='badges@fedoraproject.org',
),
},
'badges.consume_delay': 1.5,
'badges.delay_limit': 25,
# 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": {
"username": "{{fedoraDummyUser}}",
"password": "{{fedoraDummyUserPassword}}",
},
"fasjson_base_url": "https://fasjson{{env_suffix}}.fedoraproject.org/v1/",
"keytab": "/etc/krb5.badges-backend_badges-backend01{{env_suffix}}.iad2.fedoraproject.org.keytab",
# Stuff used for caching packagedb relations.
"fedbadges.rules.utils.use_pkgdb2": False,
"fedbadges.rules.cache": {
"backend": "dogpile.cache.dbm",
"expiration_time": 300,
"arguments": {
"filename": "/var/tmp/fedbadges-cache.dbm",
},
},
}

View file

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

View file

@ -1,8 +0,0 @@
[general]
flickr_api_key = {{ flock_paparazzi_flickr_api_key }}
g_plus_key = {{ flock_paparazzi_g_plus_api_key }}
userIP = {{ flock_paparazzi_userip }}
fas_username = {{ fedoraDummyUser }}
fas_password = {{ fedoraDummyUserPassword }}

View file

@ -1,8 +0,0 @@
# Set PS1 based on env
#
{% if {{ env }} == 'production' %}
PS1="\e[0;31m[PROD]\e[m[\u@\h \W]\$ "
{% elif {{ env }} == 'staging' %}
PS1="[STG]\e[m[\u@\h \W]\$ "
{% endif }%

View file

@ -1,92 +0,0 @@
Fedora Badges
=============
`Fedora Badges <https://badges.fedoraproject.org>`_ is a fun website built to recognize contributors to the `Fedora Project <https://fedoraproject.org>`_, help new and existing Fedora contributors find different ways to get involved, and encourage the improvement of Fedora's infrastructure.
.. image:: https://badges.fedoraproject.org/pngs/badges_fan.png
:alt: Fedora Badges
How does Badges work?
---------------------
It's really easy! Just `sign in to Badges <https://badges.fedoraproject.org/login>`_ with your `Fedora account <https://accounts.fedoraproject.org/>`_, and you'll see you have at least one badge right away. Congratulations - you're a Badger! If you participate in Fedora in any way, you'll probably notice Badges popping up on your profile as you go about your business, though sadly we don't cover every area of Fedora yet - we're doing our best to make sure we reward as many forms of participation as we can!
Want to see how your badge collection compares with others? Check the `Leaderboard <https://badges.fedoraproject.org/leaderboard>`_. Jonesing for more badges? You can check the `Badge index <https://badges.fedoraproject.org/explore/badges>`_ to see all the badges and get to work on your collection! Click on a badge to see how to get it - but
we intentionally didn't spell it all out exactly. Part of the fun is figuring it out!
Another cool thing: the Badges site is mobile-optimized, so you can easily keep track of your badges on the go!
Why don't I have all the Badges I should?
-----------------------------------------
There are a few reasons why unfortunately you might not get some badges you would expect to receive. First of all, the infrastructure that underlies Badges has only been running since late 2012 (and some pieces since early 2013), and so for many Badges, we can't take contributions from before those dates into account. We're really sorry. We wish we could. We've filed a ticket requesting someone build us a time machine; logically speaking, though, if it was going to be closed, `it would've been closed immediately <http://boardgamegeek.com/boardgame/2297/us-patent-number-1>`_...
Secondly, in the case of some badges, you need to perform one action after signing up for Badges, to sort of 'prime the pump' (this is not really how it works. No pumps are involved. We've checked.) The `Curious Penguin (Ask Fedora II) <https://badges.fedoraproject.org/badge/curious-penguin-ask-fedora-ii>`_ Badge, for instance, requires you to ask or answer ten questions at `Ask Fedora <https://ask.fedoraproject.org>`_. When you first join Badges, even if you've already done this, you won't see the badge - but as soon as you ask or answer just one more question, you'll get it.
A special case of this problem affects Badges awarded for things you did before joining Badges, which you can't really do again - for instance, the `Proven Packager badge <https://badges.fedoraproject.org/badge/proven-packager>`_, which is awarded when you join that group. We run a script to check for and award most of these badges regularly, so just sit back and be a patient Badger and you'll see them soon!
Who made it?
------------
Lots of people have contributed to the `frontend <https://github.com/fedora-infra/tahrir/graphs/contributors>`_ and the `backend <https://github.com/fedora-infra/fedbadges/graphs/contributors>`_. Various people have also `contributed Badge ideas, art and definitions <https://fedorahosted.org/fedora-badges/report/18>`_. We hang out in ``#fedora-apps`` on `libera <https://libera.chat>`_, we have a `mailing list <https://lists.fedoraproject.org/mailman/listinfo/badges>`_, and a `wiki SIG page <https://fedoraproject.org/wiki/Open_Badges>`_.
Can I submit new badge ideas and help build badges?
---------------------------------------------------
Yes! We'd love you to! Just head over to the `new badge tracker <https://fedorahosted.org/fedora-badges>`_. If you want to submit a new badge idea, take a look at the `new badge guide <https://fedorahosted.org/fedora-badges/wiki/NewBadgeGuide>`_. If you're looking to contribute art or code to a badge, you'll find some useful links on the front page of the site.
Can I help work on the technologies that underlie Badges?
---------------------------------------------------------
Absolutely! Please join us! Starting at the bottom of the stack:
- `fedmsg`_ is the Fedora message bus that most badges ultimately rely on
- `datanommer`_ pulls every fedmsg message into a database
- `fedbadges`_ is the actual badge awarder
- `tahrir`_ is the frontend you're looking at right now
- `tahrir-api`_ is the API for tahrir
Technical Questions and Details
===============================
Once more, with feeling: How does Badges work?
----------------------------------------------
If you mean how does it WORK work, it's pretty cool! Fedora Badges takes advantage of `fedmsg`_ (Fedora Infrastructure's Message Bus) and `datanommer`_ to determine what kinds of contributions a person is making.
The badge awarding backend daemon, `fedbadges`_, wakes up when it receives a fedmsg event. It compares that message and the history in datanommer against a series of `rules <https://git.fedorahosted.org/cgit/badges.git>`_. If a contributor matches the criteria described in one of those rules, then they are **awarded a badge** in real time.
The frontend that you're looking at now is a web application called `tahrir`_. We tried as much as we could to keep Tahrir "brand agnostic", so you can install it, run it on your own platform, and issue badges to your friends! Some assembly required.
How long has the badge awarder been running?
--------------------------------------------
Since August 7th, 2013.
How long has datanommer been storing the fedmsg history?
--------------------------------------------------------
Since October 16th, 2012 `[1]
<http://threebean.org/blog/datanommer-and-fedmsg-activity/>`_.
Why exactly can't badges for events be automatically awarded retrospectively?
-----------------------------------------------------------------------------
First, remember that the badge awarding daemon wakes up in response to new `fedmsg`_ events and that it checks the `history of fedmsg <https://apps.fedoraproject.org/datagrepper>`_ in order to make determinations
about who gets what badge at that moment.
To award that Proven Packager badge, the awarder waits for `a message <http://www.fedmsg.com/en/latest/topics/#fas-group-member-sponsor>`_ from the `Fedora Account System (FAS) <https://accounts.fedoraproject.org/>`_ indicating that a user has been added to that group. When we receive it, we wake up, verify it, and award the badge.
Since you've been a member of that group for longer than the badge awarder has been running it has never had the occasion to check if you should be awarded the badge. At the time of the launch of Fedora Badges, we've been working
around this by manually running a script every few days that doles out these group-based badges to newly-logged-in users. We really should put it in a cronjob to make our lives easier.
Of course, we can't use a simple script to retroactively award badges based on large and complex pre-fedmsg activity like package builds, so many Badgers won't have as many badges for package builds and similar activity as they really ought to. The fedmsg project only started in 2012 and the history only `started being tracked in October of that year
<http://threebean.org/blog/datanommer-and-fedmsg-activity/>`_. Koji events didn't come until much later, until January 2013. So Fedora Badges only knows about your builds since then. Don't be disheartened! There's so much more to hack and do.
There's a tentative plan to write a bigger script that will go back over old Koji logs and so on, generate appropriate fedmsg messages but (of course!) not actually broadcast them, and instead feed them straight into datanommer. That should let us catch up on a lot of old activity.
.. _fedmsg: http://fedmsg.com/
.. _datanommer: https://apps.fedoraproject.org/datagrepper
.. _fedbadges: https://github.com/fedora-infra/fedbadges
.. _tahrir: https://github.com/fedora-infra/tahrir
.. _tahrir-api: https://github.com/fedora-infra/tahrir-api

View file

@ -1,8 +0,0 @@
You can submit new badge ideas on the `fedora-badges
<https://pagure.io/Fedora-Badges>`_ tracker.
Please report bugs and file issues with التحرير (Tahrir) on `the GitHub issues
tracker <https://github.com/fedora-infra/tahrir/issues>`_.
This project is free software; you can find the `source
<http://github.com/fedora-infra/tahrir>`_ on GitHub.

View file

@ -1,16 +0,0 @@
import sys
sys.stdout = sys.stderr
import __main__
__main__.__requires__ = __requires__ = ["tahrir", "sqlalchemy>=0.8"];
import pkg_resources
pkg_resources.require(__requires__)
import os
os.environ['PYTHON_EGG_CACHE'] = '/var/www/.python-eggs'
from pyramid.paster import get_app, setup_logging
ini_path = '/etc/tahrir/tahrir.ini'
setup_logging(ini_path)
application = get_app(ini_path, 'main')

View file

@ -1,8 +0,0 @@
#!/bin/bash
set -e
cd /srv/badges_checkout/
git pull >/dev/null 2>&1
for i in pngs stls ; do
rsync --delete -ar /srv/badges_checkout/$i/ /usr/share/badges/$i/
done

View file

@ -1,152 +0,0 @@
---
# Configuration for the tahrir webapp
- name: install needed packages
package:
name: "{{ item }}"
state: present
with_items:
- python-tahrir
- python-psycopg2
- python-memcached
- python-rdflib
- libsemanage-python
- git-core
tags:
- packages
- badges
- badges/frontend
- name: create tahrir user
user:
user: tahrir
shell: /sbin/nologin
home: /usr/share/tahrir
tags:
- config
- badges
- badges/frontend
- name: copy tahrir app configuration
template:
src: "{{ item }}"
dest: "/etc/tahrir/{{ item }}"
owner: tahrir
group: tahrir
mode: 0600
with_items:
- tahrir.ini
tags:
- config
- badges
- badges/frontend
notify:
- restart apache
- name: copy tahrir wsgi script
copy:
src: "{{ item }}"
dest: "/usr/share/tahrir/{{ item }}"
owner: apache
group: apache
mode: 0644
with_items:
- tahrir.wsgi
tags:
- config
- badges
- badges/frontend
notify:
- restart apache
- name: copy tahrir httpd config
template:
src: "{{ item }}"
dest: "/etc/httpd/conf.d/{{ item }}"
owner: apache
group: apache
mode: 0644
with_items:
- tahrir.conf
tags:
- config
- badges
- badges/frontend
notify:
- restart apache
- name: make badge rst directory
file:
path: /usr/share/badges/sitedocs
state: directory
owner: root
group: root
mode: 0755
tags:
- config
- assets
- badges
- badges/frontend
- name: copy over all our .rst site docs
copy:
src: "{{ item }}"
dest: /usr/share/badges/sitedocs
owner: root
group: root
mode: 0644
with_fileglob:
- fedora-sitedocs/*.rst
tags:
- config
- assets
- badges
- badges/frontend
- name: create checkout dir
file:
name: /srv/badges_checkout
state: directory
tags:
- badges
- badges/frontend
- name: clone directory
git:
repo: https://pagure.io/fedora-badges.git
dest: /srv/badges_checkout
tags:
- badges
- badges/frontend
- name: add script
copy:
dest: /usr/local/bin/update_checkout.sh
src: update_checkout.sh
mode: 0755
tags:
- badges
- badges/frontend
- name: add cron for update
cron:
name: "update checkout"
job: /usr/local/bin/update_checkout.sh
minute: "*/15"
tags:
- badges
- badges/frontend
- name: ensure selinux lets httpd talk to postgres, memcached, and fedmsg
seboolean:
name: "{{item}}"
persistent: yes
state: yes
with_items:
- httpd_can_network_connect_db
- httpd_can_network_memcache
- httpd_can_network_connect
tags:
- selinux
- badges
- badges/frontend

View file

@ -1,17 +0,0 @@
Alias /static /usr/lib/python2.7/site-packages/tahrir/static
Alias /pngs /usr/share/badges/pngs
Alias /stls /usr/share/badges/stls
WSGIDaemonProcess tahrir user=tahrir group=tahrir maximum-requests=1000 display-name=tahrir processes={{ wsgi_procs }} threads={{ wsgi_threads }}
WSGISocketPrefix run/wsgi
WSGIRestrictStdout On
WSGIRestrictSignal Off
WSGIPythonOptimize 1
WSGIScriptAlias / /usr/share/tahrir/tahrir.wsgi
<Location />
WSGIProcessGroup tahrir
Require all granted
</Location>

View file

@ -1,156 +0,0 @@
[pipeline:main]
pipeline =
moksha
tw2
tahrir
[filter:proxy-prefix]
use = egg:PasteDeploy#prefix
prefix = /
scheme = https
[filter:tw2]
use = egg:tw2.core#middleware
script_name =
[filter:moksha]
use = egg:moksha.wsgi#middleware
[app:tahrir]
use = egg:tahrir
filter-with = proxy-prefix
#pyramid.reload_templates = true
pyramid.default_locale_name = en
pyramid.includes =
pyramid_tm
{% if env == 'staging' %}
sqlalchemy.url = postgresql://{{tahrirDBUser}}:{{tahrirstgDBPassword}}@db01.stg.iad2.fedoraproject.org/tahrir
{% else %}
sqlalchemy.url = postgresql://{{tahrirDBUser}}:{{tahrirDBPassword}}@db-tahrir/tahrir
{% endif %}
mako.directories=tahrir:templates
tahrir.admin = nb@fedoraproject.org, siddharthvipul1@fedoraproject.org, sayanchowdhury@fedoraproject.org, kevin@fedoraproject.org, jflory7@fedoraproject.org, codeblock@fedoraproject.org, churchyard@fedoraproject.org, misc@fedoraproject.org, computerkid@fedoraproject.org, dustymabe@fedoraproject.org, gui1ty@fedoraproject.org, riecatnor@fedoraproject.org, smeragoel@fedoraproject.org, sumantrom@fedoraproject.org, ekidney@fedoraproject.org, t0xic0der@fedoraproject.org
tahrir.pngs.uri = /usr/share/badges/pngs
# disabled, trying to see if this fix this bug
# https://pagure.io/fedora-infrastructure/issue/8689
dogpile.cache.backend = dogpile.cache.null
dogpile.cache.expiration_time = 100
dogpile.cache.arguments.url = memcached01:11211
dogpile.cache.arguments.distributed_lock = True
dogpile.cache.arguments.lock_timeout = 5
{% if env == 'staging' %}
tahrir.title = Fedora Badges (staging!)
tahrir.base_url = https://badges.stg.fedoraproject.org
tahrir.openid_identifier = http://id.stg.fedoraproject.org/
tahrir.trusted_openid = ^http(s)?:\/\/([a-zA-Z0-9-]+\.)?id\.stg\.fedoraproject\.org\/?$
tahrir.openid_realm = https://badges.stg.fedoraproject.org
tahrir.websocket.topic = org.fedoraproject.stg.fedbadges.badge.award
fedmenu.url = https://apps.stg.fedoraproject.org/fedmenu
fedmenu.data_url = https://apps.stg.fedoraproject.org/js/data.js
{% else %}
tahrir.title = Fedora Badges
tahrir.base_url = https://badges.fedoraproject.org
tahrir.openid_identifier = http://id.fedoraproject.org/
tahrir.trusted_openid = ^http(s)?:\/\/([a-zA-Z0-9-]+\.)?id\.fedoraproject\.org(/)?$
tahrir.openid_realm = https://badges.fedoraproject.org
tahrir.websocket.topic = org.fedoraproject.prod.fedbadges.badge.award
fedmenu.url = https://apps.fedoraproject.org/fedmenu
fedmenu.data_url = https://apps.fedoraproject.org/js/data.js
{% endif %}
tahrir.secure_cookies = True
tahrir.httponly_cookies = True
tahrir.allow_changenick = False
# Only allow @fedoraproject.org emails
tahrir.use_openid_email = False
# For auto-updating the frontpage.
tahrir.use_websockets = True
# For emitting messages when users claim badge invitations.
tahrir.use_fedmsg = True
tahrir.default_issuer = fedora-project
tahrir.sitedocs_dir = /usr/share/badges/sitedocs/
tahrir.display_tags = content,development,community,quality,event,miscellaneous
tahrir.social.twitter = True
tahrir.social.twitter_user_text = Check out all these #fedorabadges :trophy:
tahrir.social.twitter_user_hash = #fedora
tahrir.social.gplus = True
{% if env == 'staging' %}
session.secret="{{tahrirstgSessionSecret}}"
authnsecret="{{tahrirstgAuthnSecret}}"
{% else %}
session.secret="{{tahrirSessionSecret}}"
authnsecret="{{tahrirAuthnSecret}}"
{% endif %}
moksha.domain = fedoraproject.org
moksha.notifications = False
moksha.socket.notify = False
moksha.livesocket = True
moksha.livesocket.backend = websocket
moksha.livesocket.reconnect_interval = 5000
moksha.livesocket.websocket.scheme = wss
moksha.livesocket.websocket.port = 9939
{% if env == 'staging' %}
moksha.livesocket.websocket.host = stg.fedoraproject.org
{% else %}
moksha.livesocket.websocket.host = hub.fedoraproject.org
{% endif %}
# Begin logging configuration
[loggers]
keys = root, tahrir, sqlalchemy
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[logger_tahrir]
level = DEBUG
handlers =
qualname = tahrir
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
# "level = INFO" logs SQL queries.
# "level = DEBUG" logs SQL queries and results.
# "level = WARN" logs neither. (Recommended for production systems.)
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
# End logging configuration