Skip to content

Commit

Permalink
Degreed replacing encrypted fields with non encrypted (#2063)
Browse files Browse the repository at this point in the history
* feat: replacing non encrypted fields of degreed config model with encrypted ones
  • Loading branch information
MueezKhan246 authored Apr 17, 2024
1 parent 4738bab commit 43ac63e
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Change Log
Unreleased
----------
[4.15.3]
--------
* feat: replacing non encrypted fields of degreed config model with encrypted ones

[4.15.2]
--------
* feat: save cornerstone learner's information received from frontend.
Expand Down
2 changes: 1 addition & 1 deletion enterprise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Your project description goes here.
"""

__version__ = "4.15.2"
__version__ = "4.15.3"
6 changes: 6 additions & 0 deletions integrated_channels/api/v1/degreed2/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""
Serializer for Degreed2 configuration.
"""
from rest_framework import serializers

from integrated_channels.api.serializers import EnterpriseCustomerPluginConfigSerializer
from integrated_channels.degreed2.models import Degreed2EnterpriseCustomerConfiguration

Expand All @@ -11,7 +13,11 @@ class Meta:
extra_fields = (
'client_id',
'client_secret',
'encrypted_client_id',
'encrypted_client_secret',
'degreed_base_url',
'degreed_token_fetch_base_url',
)
fields = EnterpriseCustomerPluginConfigSerializer.Meta.fields + extra_fields
encrypted_client_id = serializers.CharField(required=False, allow_blank=False, read_only=False)
encrypted_client_secret = serializers.CharField(required=False, allow_blank=False, read_only=False)
5 changes: 3 additions & 2 deletions integrated_channels/degreed2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,11 +674,12 @@ def _get_oauth_access_token(self, scope):
"""
config = self.enterprise_configuration
url = self.get_oauth_url()
use_encrypted_user_data = getattr(settings, 'FEATURES', {}).get('USE_ENCRYPTED_USER_DATA', False)
data = {
'grant_type': 'client_credentials',
'scope': scope,
'client_id': config.client_id,
'client_secret': config.client_secret,
'client_id': config.decrypted_client_id if use_encrypted_user_data else config.client_id,
'client_secret': config.decrypted_client_secret if use_encrypted_user_data else config.client_secret,
}
start_time = time.time()
response = requests.post(
Expand Down
69 changes: 69 additions & 0 deletions integrated_channels/degreed2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from fernet_fields import EncryptedCharField

from django.db import models
from django.utils.encoding import force_bytes, force_str

from integrated_channels.degreed2.exporters.content_metadata import Degreed2ContentMetadataExporter
from integrated_channels.degreed2.exporters.learner_data import Degreed2LearnerExporter
Expand Down Expand Up @@ -53,6 +54,40 @@ class Degreed2EnterpriseCustomerConfiguration(EnterpriseCustomerPluginConfigurat
null=True
)

decrypted_client_id = EncryptedCharField(
max_length=255,
blank=True,
default='',
verbose_name="Encrypted API Client ID",
help_text=(
"The encrypted API Client ID provided to edX by the enterprise customer to be used to make API "
"calls to Degreed on behalf of the customer."
),
null=True
)

@property
def encrypted_client_id(self):
"""
Return encrypted client_id as a string.
The data is encrypted in the DB at rest, but is unencrypted in the app when retrieved through the
decrypted_client_id field. This method will encrypt the client_id again before sending.
"""
if self.decrypted_client_id:
return force_str(
self._meta.get_field('decrypted_client_id').fernet.encrypt(
force_bytes(self.decrypted_client_id)
)
)
return self.decrypted_client_id

@encrypted_client_id.setter
def encrypted_client_id(self, value):
"""
Set the encrypted client_id.
"""
self.decrypted_client_id = value

client_secret = models.CharField(
max_length=255,
blank=True,
Expand All @@ -76,6 +111,40 @@ class Degreed2EnterpriseCustomerConfiguration(EnterpriseCustomerPluginConfigurat
null=True
)

decrypted_client_secret = EncryptedCharField(
max_length=255,
blank=True,
default='',
verbose_name="Encrypted API Client Secret",
help_text=(
"The encrypted API Client Secret provided to edX by the enterprise customer to be used to make API "
"calls to Degreed on behalf of the customer."
),
null=True
)

@property
def encrypted_client_secret(self):
"""
Return encrypted client_secret as a string.
The data is encrypted in the DB at rest, but is unencrypted in the app when retrieved through the
decrypted_client_secret field. This method will encrypt the client_secret again before sending.
"""
if self.decrypted_client_secret:
return force_str(
self._meta.get_field('decrypted_client_secret').fernet.encrypt(
force_bytes(self.decrypted_client_secret)
)
)
return self.decrypted_client_secret

@encrypted_client_secret.setter
def encrypted_client_secret(self, value):
"""
Set the encrypted client_secret.
"""
self.decrypted_client_secret = value

degreed_base_url = models.CharField(
max_length=255,
blank=True,
Expand Down

0 comments on commit 43ac63e

Please sign in to comment.