Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [EDXOLDMNG-236] certificate config for old courses is taken fro… #2466

Conversation

NiedielnitsevIvan
Copy link

@NiedielnitsevIvan NiedielnitsevIvan commented Dec 9, 2022

Description: Use external signatures from credentials on WEB/PDF certificate rendering

Youtrack: Link to Youtrack ticket

Reviewers:

Merge checklist:

  • All reviewers approved
  • CI build is green
  • Documentation in source code updated
  • All related Confluence documentation is updated (including deployment documentation)
  • Commits are squashed

Post merge:

  • Delete working branch (if not needed anymore)

import logging

from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please tell me what's wrong with the import that you need the # lint-amnesty, pylint: disable=imported-auth-user. Very looks like a regular django's import.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's all about OedX linters. It crashes with such imports, but it is widely used.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird but fine.

@@ -250,3 +253,24 @@ def get_preferred_certificate_name(user):
name_to_use = ''

return name_to_use


def get_certificate_configuration_from_credentials(course_id, mode):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some typing here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added


def get_certificate_configuration_from_credentials(course_id, mode):
"""
Makes a request to the credentials service to get the certificate configuration.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get a certificate configuration of the course

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

credentials_client = get_credentials_api_client(User.objects.get(username=settings.CREDENTIALS_SERVICE_USERNAME))
course_certificates_api_url = urljoin(f'{get_credentials_api_base_url()}/', 'course_certificates/')
api_url = urljoin(course_certificates_api_url, f'?course_id={course_id}&certificate_type={mode}')
response = None

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to have it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

mode
)

return response

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else:
    return response

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Comment on lines 51 to 53
get_preferred_certificate_name
get_preferred_certificate_name,
get_certificate_configuration_from_credentials,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabet order please.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -669,6 +678,29 @@ def render_html_view(request, course_id, certificate=None): # pylint: disable=t
return response


def _populate_certificate_configuration_from_credentials(configuration, course, mode):
Copy link

@NikolayBorovenskiy NikolayBorovenskiy Dec 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Have you noticed that major part of the modules' functions have names def _update_? Please, track the style and follow it.
  2. Need some typing?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name fixed and typing added.

"""
Populates certificate configuration from credentials service.

If config not found in credentials returns received.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not understand what you want to say.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected.

Comment on lines 687 to 688
response = get_certificate_configuration_from_credentials(course.id, mode)
if response and response.status_code == status.HTTP_200_OK:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad approach. Please try to use try/except here. Make a log if you need and make a decision after.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done✅

Comment on lines 691 to 692
configuration['course_title'] = data.get('title') or configuration['course_title']
configuration['is_active'] = data.get('is_active') or configuration['is_active']

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if data.get('title'):
        configuration['course_title'] = data['title']
if data.get('is_active'):
        configuration['is_active'] = data['is_active']

?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it looked better this way. Fixed

response = credentials_client.get(api_url)
except Exception: # pylint: disable=broad-except
log.warning(
'There is no certificate configuration in credentials for a course [%s] with a mod [%s]',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't say that at all. After all, you do not understand whether there is a certificate or not. Maybe the network is down or the service is not responding. Everything is much more complicated here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the second important question. What will you do when there are problems with the network? You then return NONE. Is this normal for your logic?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored.
If the response is None, the current configuration will remain from mongo.

Comment on lines 260 to 279
def get_certificate_configuration_from_credentials(course_id: CourseKey, mode: str) -> Optional[Response]:
"""
Makes a request to the credentials service to get a certificate configuration of the course.
"""
course_certificates_api_url = urljoin(f'{get_credentials_api_base_url()}/', 'course_certificates/')
api_url = urljoin(course_certificates_api_url, f'?course_id={course_id}&certificate_type={mode}')

try:
credentials_client = get_credentials_api_client(
User.objects.get(username=settings.CREDENTIALS_SERVICE_USERNAME)
)
response = credentials_client.get(api_url)
except Exception: # pylint: disable=broad-except
log.warning(
'There is no certificate configuration in credentials for a course [%s] with a mod [%s]',
course_id,
mode
)
else:
return response

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please answer me why u do not use the function get_api_data?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I didn't know it existed.

@@ -669,6 +679,37 @@ def render_html_view(request, course_id, certificate=None): # pylint: disable=t
return response


def _update_certificate_configuration_from_credentials(
configuration: Dict[str, Union[str, List[Dict[str, str]]]],
course: 'CourseBlockWithMixins', mode: str

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

course: 'CourseBlockWithMixins', 
mode: str

response = get_certificate_configuration_from_credentials(course.id, mode)
response.raise_for_status()
except Exception as err: # pylint: disable=broad-except
log.warning(f'Failed to get course certificate config for course {course.id} from Credentials. {err}')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you already have the log

log.warning(
            'There is no certificate configuration in credentials for a course [%s] with a mod [%s]',

Why do we need this log?
Maybe in that function, the log is not needed and there is no need to intercept anything. Let it throw an exception. But in this place, you will intercept, if that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed after using get_api_data.

log.warning(f'Failed to get course certificate config for course {course.id} from Credentials. {err}')
else:
data = response.json()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra line.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Comment on lines 269 to 270
except User.DoesNotExist:
log.warning(f'Credentials service user [{settings.CREDENTIALS_SERVICE_USERNAME}] does not exist')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe why we need this and why we can return nothing?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because in this way you can find out why it is not possible to make a request to Credentials. I had a case on another project, when it was precisely because of the absence of this user that certificates for programs were not generated and there were no logs about this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NikolayBorovenskiy NikolayBorovenskiy merged commit 7039eb1 into master Dec 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants