Skip to content

Commit

Permalink
Merge pull request #19 from Mahesh-Binayak/mbupdates
Browse files Browse the repository at this point in the history
Mbupdates
  • Loading branch information
Mahesh-Binayak authored May 3, 2024
2 parents 68abf74 + f6c28d0 commit 5903356
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/push_trigger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
include:
- SERVICE_LOCATION: 'databreachdetector'
SERVICE_NAME: 'databreachdetector'
- SERVICE_LOCATION: 'certmanager'
SERVICE_NAME: 'certmanager'
fail-fast: false
name: ${{ matrix.SERVICE_NAME }}
uses: mosip/kattu/.github/workflows/docker-build.yml@master
Expand Down
39 changes: 39 additions & 0 deletions certmanager/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM python:3.9

ARG SOURCE
ARG COMMIT_HASH
ARG COMMIT_ID
ARG BUILD_TIME
LABEL source=${SOURCE}
LABEL commit_hash=${COMMIT_HASH}
LABEL commit_id=${COMMIT_ID}
LABEL build_time=${BUILD_TIME}

ARG container_user=mosip
ARG container_user_group=mosip
ARG container_user_uid=1001
ARG container_user_gid=1001

# Create user group
RUN groupadd -r ${container_user_group} && useradd -u ${container_user_uid} -r -g ${container_user_group} -s /bin/bash -m -d /home/${container_user} ${container_user}
RUN chown -R ${container_user}:${container_user} /home/${container_user}
WORKDIR /home/${container_user}
USER ${container_user}

ENV MYDIR=`pwd`
ENV DATE="$(date --utc +%FT%T.%3NZ)"
ENV ENABLE_INSECURE=false
ENV MODULE=


ENV db-server=
ENV db-port=
ENV db-su-user=
ENV postgres-password=

COPY partner.properties .
COPY requirements.txt .
COPY checkupdate.py .
COPY bootstrap.properties .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "checkupdate.py"]
9 changes: 9 additions & 0 deletions certmanager/bootstrap.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Database]
db-host = postgres.soil-security.mosip.net
db-port = 5432
db-su-user = postgres
postgres-password = cUZ5DLgLqz
[API]
mosip-api-internal-host=api-internal.soil-security.mosip.net
mosip_pms_client_secret=kxDGFoBJRsa9BprI
pre-expiry-days=400
225 changes: 225 additions & 0 deletions certmanager/checkupdate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
import os
import json
import psycopg2
import requests
from urllib.request import Request, urlopen
from urllib.error import HTTPError
from datetime import datetime, timedelta
from configparser import ConfigParser

# Function to read value from bootstrap.properties
def read_bootstrap_properties(key):
with open('bootstrap.properties', 'r') as file:
for line in file:
if line.startswith(key):
return line.split('=')[1].strip()
return None

# Function to check if certificate is expired
def is_certificate_expired(expiration_date):
# Parse expiration date string
expiration_date = datetime.strptime(expiration_date, "%b %d %H:%M:%S %Y %Z")
# Get current date
current_date = datetime.utcnow()
# Compare expiration date with current date
return current_date > expiration_date

# Function to write expired certificates to a text file
def write_to_expired_txt(cert_name):
with open('expired.txt', 'a') as file:
file.write(cert_name + '\n')

# Function to format certificate data
def format_certificate(cert_data):
# Replace line breaks with "\\n"
formatted_cert_data = cert_data.replace("\n", "\\n")
return formatted_cert_data

# Function to retrieve certificate data from the database
def retrieve_certificate_data(partner_id, db_host, db_port, db_user, db_password):
try:
# Connect to the PMS database
pms_conn = psycopg2.connect(
host=db_host,
port=db_port,
database="mosip_pms",
user=db_user,
password=db_password
)
pms_cursor = pms_conn.cursor()

# Query to retrieve the certificate alias
sql_query_cert_alias = f"SELECT certificate_alias FROM pms.partner WHERE id = '{partner_id}';"
pms_cursor.execute(sql_query_cert_alias)
certificate_alias = pms_cursor.fetchone()[0]

# Query to retrieve cert_data using the certificate alias
sql_query_cert_data = f"SELECT cert_data FROM keymgr.partner_cert_store WHERE cert_id = '{certificate_alias}';"

# Connect to the Keymgr database
keymgr_conn = psycopg2.connect(
host=db_host,
port=db_port,
database="mosip_keymgr",
user=db_user,
password=db_password
)
keymgr_cursor = keymgr_conn.cursor()
keymgr_cursor.execute(sql_query_cert_data)
cert_data = keymgr_cursor.fetchone()[0]

# Format the certificate data
formatted_cert_data = format_certificate(cert_data)

# Close connections
pms_cursor.close()
pms_conn.close()
keymgr_cursor.close()
keymgr_conn.close()

return formatted_cert_data

except Exception as e:
print(f"Error retrieving certificate data for Partner ID '{partner_id}', Check partner name in expired.txt: {str(e)}")
return None

# Function to authenticate and retrieve the token
def authenticate_and_get_token(base_url, client_secret):
auth_url = f"https://{base_url}/v1/authmanager/authenticate/clientidsecretkey"
headers = {"Content-Type": "application/json"}

auth_data = {
"id": "string",
"metadata": {},
"request": {
"appId": "ida",
"clientId": "mosip-pms-client",
"secretKey": client_secret
},
"requesttime": "", # Generate timestamp in desired format
"version": "string"
}

response = requests.post(auth_url, headers=headers, json=auth_data)
if response.status_code == 200:
token = response.headers.get("authorization")
return token
else:
print("Authentication failed.")
print("Auth API Response:", response.text)
return None

# Function to upload certificate with authentication token
def upload_certificate_with_token(token, cert_data, partner_id, base_url):
upload_url = f"https://{base_url}/v1/partnermanager/partners/certificate/upload"
headers = {
"Content-Type": "application/json",
"Cookie": f"Authorization={token}"
}

# Format certificate data
formatted_cert_data = cert_data.replace("\\n", "\n")

upload_data = {
"id": "string",
"metadata": {},
"request": {
"certificateData": formatted_cert_data,
"partnerDomain": "AUTH",
"partnerId": partner_id
},
"requesttime": "", # Generate timestamp in desired format
"version": "string"
}

response = requests.post(upload_url, headers=headers, json=upload_data)

if "certificateId" not in response.text:
print("Certificate renewal failed.")
print("Upload API Response:", response.text)
else:
print("Certificate renewed successfully.")

# Fetching environment variables or values from bootstrap.properties
postgres_host = os.environ.get('db-host')
postgres_port = os.environ.get('db-port')
postgres_user = os.environ.get('db-su-user')
postgres_password = os.environ.get('postgres-password')
base_url = os.environ.get('mosip-api-internal-host')
client_secret = os.environ.get('mosip_pms_client_secret')

# If environment variables are not set, read from bootstrap.properties file
if not all([postgres_host, postgres_port, postgres_user, postgres_password, base_url, client_secret]):
config = ConfigParser()
config.read('bootstrap.properties')
postgres_host = config.get('Database', 'db-host', fallback='')
postgres_port = config.get('Database', 'db-port', fallback='')
postgres_user = config.get('Database', 'db-su-user', fallback='')
postgres_password = config.get('Database', 'postgres-password', fallback='')
base_url = config.get('API', 'mosip-api-internal-host', fallback='')
client_secret = config.get('API', 'mosip_pms_client_secret', fallback='')

# Authenticate and get the token
TOKEN = authenticate_and_get_token(base_url, client_secret)

# Check if token is obtained successfully
if TOKEN:
# Read pre-expiry days from bootstrap.properties
PRE_EXPIRY_DAYS = read_bootstrap_properties("pre-expiry-days")

# PARTNER_IDS read from partner.properties
with open('partner.properties', 'r') as file:
for line in file:
if line.startswith('PARTNER_ID'):
partner_ids = line.strip().split('=')[1].split(',')
for PARTNER_ID in partner_ids:
print(f"\nProcessing partner ID: {PARTNER_ID.strip()}")
# Request certificate information
try:
req = Request(f"https://{base_url}/v1/partnermanager/partners/{PARTNER_ID.strip()}/certificate",
headers={
"Content-Type": "application/json",
"Cookie": f"Authorization={TOKEN}"
},
method="GET")
response = urlopen(req)
response_data = json.loads(response.read().decode('utf-8'))
CERTIFICATE_DATA = response_data.get('response', {}).get('certificateData')
print(CERTIFICATE_DATA)
# Run openssl command to print certificate details
openssl_command = f"echo '{CERTIFICATE_DATA}' | openssl x509 -noout -enddate"
expiration_date = os.popen(openssl_command).read().split('=')[1].strip()
print("Certificate expiration date:", expiration_date)
# Check if certificate is expired or pre-expiry
if is_certificate_expired(expiration_date) or \
(datetime.strptime(expiration_date, "%b %d %H:%M:%S %Y %Z") - datetime.utcnow()) <= timedelta(days=int(PRE_EXPIRY_DAYS)):
write_to_expired_txt(PARTNER_ID.strip())
except HTTPError as e:
print(f"Error occurred while fetching certificate information for {PARTNER_ID}: {e}")
continue

if not CERTIFICATE_DATA:
print(f"No data available for {PARTNER_ID} in keymanager.")
continue

# Check if expired.txt exists before trying to read from it
if os.path.exists("expired.txt"):
with open("expired.txt", "r") as file:
expired_partner_ids = [line.strip() for line in file if line.strip()]
else:
expired_partner_ids = []

# Check if any certificates were found to be expired
if not expired_partner_ids:
print("None of the certs have expired.")
exit(0)

for partner_id in expired_partner_ids:
print(f"Certificate renewal started for Partner ID: {partner_id}")
cert_data = retrieve_certificate_data(partner_id, postgres_host, postgres_port, postgres_user, postgres_password)
if cert_data is not None:
upload_certificate_with_token(TOKEN, cert_data, partner_id, base_url)

print("Certificate check and renewal process completed.")
else:
print("Failed while trying to get auth-token")
1 change: 1 addition & 0 deletions certmanager/partner.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PARTNER_ID=mpartner-default-auth
2 changes: 2 additions & 0 deletions certmanager/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
psycopg2-binary==2.9.1
requests==2.26.0

0 comments on commit 5903356

Please sign in to comment.