Regulatory Compliance and Data Privacy Project

Set Up the Environment

First, let’s install the necessary Python libraries:

bashCopy codepip install flask flask-sqlalchemy flask-login flask-wtf cryptography
  • Flask: Web framework.
  • Flask-SQLAlchemy: ORM for interacting with the SQLite database.
  • Flask-Login: For session-based user authentication.
  • Flask-WTF: For form handling and CSRF protection.
  • Cryptography: For encrypting sensitive user data.

Step 2: Design the Database

We’ll design a simple database that stores:

  1. User Information (e.g., name, email).
  2. User Consent for data collection and processing.
  3. Audit Logs to track actions taken on the data.

models.py – SQLAlchemy Models

pythonCopy codefrom flask_sqlalchemy import SQLAlchemy
from datetime import datetime

db = SQLAlchemy()

# User Model (store personal info)
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    password_hash = db.Column(db.String(128), nullable=False)
    consent_given = db.Column(db.Boolean, default=False)
    consent_date = db.Column(db.DateTime)
    encrypted_data = db.Column(db.LargeBinary)

    def __repr__(self):
        return f"<User {self.name}, Email: {self.email}>"

# Audit Log Model (track user actions)
class AuditLog(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    action = db.Column(db.String(200), nullable=False)
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)

    user = db.relationship('User', backref=db.backref('audit_logs', lazy=True))

    def __repr__(self):
        return f"<AuditLog {self.action} at {self.timestamp}>"

Explanation:

  • User: Stores personal data, consent information, and encrypted data.
  • AuditLog: Keeps track of actions performed on user data (such as access, modification, deletion).

Step 3: Implement User Consent Management (GDPR Compliance)

Users must explicitly consent to having their data collected and processed. We’ll include this as part of the registration form.

forms.py – User Registration Form

pythonCopy codefrom flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Email

class RegistrationForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    consent = BooleanField('I consent to having my data collected and processed', validators=[DataRequired()])
    submit = SubmitField('Register')

app.py – Flask Routes and Logic for Registration and Consent

pythonCopy codefrom flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from cryptography.fernet import Fernet
from datetime import datetime
from forms import RegistrationForm

# Initialize Flask app
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db = SQLAlchemy(app)
login_manager = LoginManager(app)

# Load user
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# User model (already defined above)
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    password_hash = db.Column(db.String(128), nullable=False)
    consent_given = db.Column(db.Boolean, default=False)
    consent_date = db.Column(db.DateTime)
    encrypted_data = db.Column(db.LargeBinary)

    def __repr__(self):
        return f"<User {self.name}, Email: {self.email}>"

# Registration route
@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        # Check if user consented
        if form.consent.data:
            # Encrypt sensitive data
            key = Fernet.generate_key()
            cipher_suite = Fernet(key)
            encrypted_data = cipher_suite.encrypt(b"Sensitive User Data")

            # Create user
            new_user = User(
                name=form.name.data,
                email=form.email.data,
                password_hash=form.password.data,
                consent_given=True,
                consent_date=datetime.utcnow(),
                encrypted_data=encrypted_data
            )

            db.session.add(new_user)
            db.session.commit()
            flash("Registration successful", "success")
            login_user(new_user)
            return redirect(url_for('dashboard'))
        else:
            flash("You must consent to data collection", "warning")
    return render_template('register.html', form=form)

# User Dashboard
@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html', name=current_user.name)

# Run the application
if __name__ == '__main__':
    app.run(debug=True)

Explanation:

  • User Consent: The registration form includes a checkbox (consent) that must be checked for the user to consent to data collection.
  • Encryption: Sensitive data is encrypted using Fernet from the cryptography library. You can later implement decryption logic when necessary.
  • Audit Log: The app doesn’t yet include logging actions to the database, but you could implement that in a similar fashion as shown in the audit log model.

Step 4: Data Access and Deletion API

GDPR and CCPA allow users to access their data and request its deletion. Let’s create the endpoints for these actions.

Data Access and Deletion

pythonCopy codefrom flask import jsonify

@app.route('/access_data', methods=['GET'])
@login_required
def access_data():
    # Decrypt the user data
    cipher_suite = Fernet(b"Your_Encryption_Key")
    decrypted_data = cipher_suite.decrypt(current_user.encrypted_data).decode()

    return jsonify({
        "name": current_user.name,
        "email": current_user.email,
        "decrypted_data": decrypted_data,
        "consent_given": current_user.consent_given,
        "consent_date": current_user.consent_date
    })

@app.route('/delete_data', methods=['DELETE'])
@login_required
def delete_data():
    # Delete user data
    db.session.delete(current_user)
    db.session.commit()

    # Log the action
    action = f"User {current_user.email} requested data deletion."
    new_log = AuditLog(user_id=current_user.id, action=action)
    db.session.add(new_log)
    db.session.commit()

    flash("Your data has been deleted", "success")
    return redirect(url_for('logout'))

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('index'))

Explanation:

  • Access Data: The /access_data endpoint allows users to view their encrypted data, after decrypting it.
  • Delete Data: The /delete_data endpoint allows users to request deletion of their account and data, and it logs this action in the AuditLog table.

Step 5: Audit Log

Whenever a user accesses or deletes their data, we log the action in an AuditLog table for compliance purposes.

Implement Audit Logging

In the /delete_data and /access_data endpoints above, actions are logged in the AuditLog table, which tracks who did what and when.

pythonCopy code# Log the action in the database
new_log = AuditLog(user_id=current_user.id, action="User requested data deletion.")
db.session.add(new_log)
db.session.commit()

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *