Added user_registered signal (#5007)

main
Andrey Zhavoronkov 3 years ago committed by GitHub
parent 59c0cd4562
commit 570bc3880f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -291,14 +291,20 @@ class ServerProxy {
const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/restrictions/user-agreements`, {
response = await Axios.get(`${backendAPI}/user-agreements`, {
proxy: config.proxy,
validateStatus: (status) => status === 200 || status === 404,
});
if (response.status === 200) {
return response.data;
}
return [];
} catch (errorData) {
throw generateError(errorData);
}
return response.data;
}
async function register(username, firstName, lastName, email, password1, password2, confirmations) {

@ -90,7 +90,7 @@ const validateAgreement: ((userAgreements: UserAgreement[]) => RuleRender) = (
const [agreement] = userAgreements
.filter((userAgreement: UserAgreement): boolean => userAgreement.name === name);
if (agreement.required && !value) {
return Promise.reject(new Error(`You must accept ${agreement.displayText} to continue!`));
return Promise.reject(new Error(`You must accept ${agreement.urlDisplayText} to continue!`));
}
return Promise.resolve();
@ -252,10 +252,12 @@ function RegisterFormComponent(props: Props): JSX.Element {
]}
>
<Checkbox>
I read and accept the
<a rel='noopener noreferrer' target='_blank' href={userAgreement.url}>
{` ${userAgreement.displayText}`}
</a>
{userAgreement.textPrefix}
{!!userAgreement.url &&
<a rel='noopener noreferrer' target='_blank' href={userAgreement.url}>
{` ${userAgreement.urlDisplayText}`}
</a>
}
</Checkbox>
</Form.Item>
))}

@ -277,8 +277,9 @@ export interface AboutState {
export interface UserAgreement {
name: string;
displayText: string;
urlDisplayText: string;
url: string;
textPrefix: string;
required: boolean;
}

@ -9,7 +9,6 @@ from rest_framework import routers
from django.views.generic import RedirectView
from django.conf import settings
from cvat.apps.restrictions.views import RestrictionsViewSet
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
@ -21,7 +20,6 @@ router.register('users', views.UserViewSet)
router.register('server', views.ServerViewSet, basename='server')
router.register('issues', views.IssueViewSet)
router.register('comments', views.CommentViewSet)
router.register('restrictions', RestrictionsViewSet, basename='restrictions')
router.register('cloudstorages', views.CloudStorageViewSet)
urlpatterns = [

@ -1,3 +0,0 @@
Scope,Resource,Context,Ownership,Limit,Method,URL,Privilege,Membership
view:user-agreements,N/A,N/A,N/A,,POST,/restrictions/user-agreements,N/A,N/A
view:terms-of-use,N/A,N/A,N/A,,GET,/restrictions/terms-of-use,N/A,N/A
1 Scope Resource Context Ownership Limit Method URL Privilege Membership
2 view:user-agreements N/A N/A N/A POST /restrictions/user-agreements N/A N/A
3 view:terms-of-use N/A N/A N/A GET /restrictions/terms-of-use N/A N/A

@ -1,3 +0,0 @@
# Copyright (C) 2020-2022 Intel Corporation
#
# SPDX-License-Identifier: MIT

@ -1,10 +0,0 @@
# Copyright (C) 2020-2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
from django.apps import AppConfig
class RestrictionsConfig(AppConfig):
name = 'cvat.apps.restrictions'

@ -1,43 +0,0 @@
# Copyright (C) 2020-2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
from rest_framework import serializers
from django.conf import settings
from cvat.apps.iam.serializers import RegisterSerializerEx
class UserAgreementSerializer(serializers.Serializer):
name = serializers.CharField(max_length=256)
display_text = serializers.CharField(max_length=2048, default='')
url = serializers.CharField(max_length=2048, default='')
required = serializers.BooleanField(default=False)
value = serializers.BooleanField(default=False)
# pylint: disable=no-self-use
def to_representation(self, instance):
instance_ = instance.copy()
instance_['displayText'] = instance_.pop('display_text')
return instance_
class RestrictedRegisterSerializer(RegisterSerializerEx):
confirmations = UserAgreementSerializer(many=True, required=False)
def validate(self, data):
validated_data = super().validate(data)
server_user_agreements = settings.RESTRICTIONS['user_agreements']
for server_agreement in server_user_agreements:
if server_agreement['required']:
is_confirmed = False
for confirmation in validated_data['confirmations']:
if confirmation['name'] == server_agreement['name'] \
and confirmation['value']:
is_confirmed = True
if not is_confirmed:
raise serializers.ValidationError(
'Agreement {} must be accepted'.format(server_agreement['name'])
)
return validated_data

@ -1,19 +0,0 @@
<!DOCTYPE html>
<body>
<h1>CVAT terms of use</h1>
<p>
PLEASE READ THE FOLLOWING TERMS CAREFULLY. IF YOU CLICK TO ACCEPT THIS AGREEMENT, DOWNLOAD,
OR INSTALL THE CVAT SOFTWARE, YOU ARE AGREEING TO BE LEGALLY BOUND BY THIS AGREEMENT
IN ADDITION TO ANY OTHER TERMS PROVIDED. IF YOU DO NOT AGREE TO THESE TERMS, DO NOT USE
THE CVAT SOFTWARE AND DESTROY ALL COPIES IN YOUR POSSESSION.
</p>
<p>
You understand and acknowledge that you are responsible for your use of the CVAT Software
and any content which you may alter with use of the CVAT Software.
</p>
<p>
You further understand and acknowledge that any content you may elect to use may be subject to privacy,
data and intellectual property rights and that you are responsible to your compliance with such laws and regulations.
</p>
</body>
</html>

@ -1,108 +0,0 @@
# Copyright (C) 2020-2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
from rest_framework.test import APITestCase, APIClient
from rest_framework import status
from django.conf import settings
class UserAgreementsTest(APITestCase):
def setUp(self):
self.client = APIClient()
self.user_agreements = settings.RESTRICTIONS['user_agreements']
settings.RESTRICTIONS['user_agreements'] = [
{
'name': 'agreement_1',
'display_text': 'some display text 1',
'url': 'https://example.com',
'required': True,
},
{
'name': 'agreement_2',
'display_text': 'some display text 2',
'url': 'https://example2.com',
'required': True,
},
{
'name': 'agreement_3',
'display_text': 'some display text 3',
'url': 'https://example3.com',
'required': False,
},
]
def tearDown(self):
settings.RESTRICTIONS['user_agreements'] = self.user_agreements
def _get_user_agreements(self):
response = self.client.get('/api/restrictions/user-agreements')
assert response.status_code == status.HTTP_200_OK
for agreements in response.data:
assert 'name' in agreements, agreements['name']
assert 'displayText' in agreements
assert 'required' in agreements
return response.data
def _register_user(self, data):
response = self.client.post('/api/auth/register', data=data, format="json")
return response
def test_user_agreements(self):
self._get_user_agreements()
def test_register_user_with_required_confirmations(self):
agreements = self._get_user_agreements()
data = {
'username': 'some_username1',
'first_name': 'some first name 1',
'last_name': 'some last name 1',
'email': 'user1@example.com',
'password1': 'FnvL4YdF24NAmnQ8',
'password2': 'FnvL4YdF24NAmnQ8',
'confirmations':[],
}
for agreement in agreements:
if agreement['required']:
data['confirmations'].append({
'name': agreement['name'],
'value': True,
})
response = self._register_user(data)
assert response.status_code == status.HTTP_201_CREATED
def test_register_user_without_confirmations(self):
data = {
'username': 'some_username2',
'first_name': 'some first name 2',
'last_name': 'some last name 2',
'email': 'user2@example.com',
'password1': 'FnvL4YdF24NAmnQ8',
'password2': 'FnvL4YdF24NAmnQ8',
'confirmations':[],
}
response = self._register_user(data)
assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_register_user_with_all_confirmations(self):
agreements = self._get_user_agreements()
data = {
'username': 'some_username3',
'first_name': 'some first name 3',
'last_name': 'some last name 3',
'email': 'user3@example.com',
'password1': 'FnvL4YdF24NAmnQ8',
'password2': 'FnvL4YdF24NAmnQ8',
'confirmations':[],
}
for agreement in agreements:
data['confirmations'].append({
'name': agreement['name'],
'value': True,
})
response = self._register_user(data)
assert response.status_code == status.HTTP_201_CREATED

@ -1,4 +0,0 @@
# Copyright (C) 2021-2022 Intel Corporation
#
# SPDX-License-Identifier: MIT

@ -1,44 +0,0 @@
# Copyright (C) 2020-2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
from django.conf import settings
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework import viewsets
from rest_framework.permissions import AllowAny
from rest_framework.renderers import TemplateHTMLRenderer
from drf_spectacular.utils import OpenApiResponse, extend_schema
from cvat.apps.restrictions.serializers import UserAgreementSerializer
@extend_schema(tags=['restrictions'])
class RestrictionsViewSet(viewsets.ViewSet):
serializer_class = None
permission_classes = [AllowAny]
authentication_classes = []
iam_organization_field = None
# To get nice documentation about ServerViewSet actions it is necessary
# to implement the method. By default, ViewSet doesn't provide it.
def get_serializer(self, *args, **kwargs):
pass
@staticmethod
@extend_schema(summary='Method provides user agreements that the user must accept to register',
responses={'200': UserAgreementSerializer})
@action(detail=False, methods=['GET'], serializer_class=UserAgreementSerializer, url_path='user-agreements')
def user_agreements(request):
user_agreements = settings.RESTRICTIONS['user_agreements']
serializer = UserAgreementSerializer(data=user_agreements, many=True)
serializer.is_valid(raise_exception=True)
return Response(data=serializer.data)
@staticmethod
@extend_schema(summary='Method provides CVAT terms of use',
responses={'200': OpenApiResponse(description='CVAT terms of use')})
@action(detail=False, methods=['GET'], renderer_classes=(TemplateHTMLRenderer,),
url_path='terms-of-use')
def terms_of_use(request):
return Response(template_name='restrictions/terms_of_use.html')

@ -126,7 +126,6 @@ INSTALLED_APPS = [
'cvat.apps.organizations',
'cvat.apps.engine',
'cvat.apps.dataset_repo',
'cvat.apps.restrictions',
'cvat.apps.lambda_manager',
'cvat.apps.opencv',
'cvat.apps.webhooks',
@ -184,7 +183,7 @@ REST_FRAMEWORK = {
}
REST_AUTH_REGISTER_SERIALIZERS = {
'REGISTER_SERIALIZER': 'cvat.apps.restrictions.serializers.RestrictedRegisterSerializer',
'REGISTER_SERIALIZER': 'cvat.apps.iam.serializers.RegisterSerializerEx',
}
REST_AUTH_SERIALIZERS = {
@ -460,11 +459,6 @@ LOCAL_LOAD_MAX_FILES_COUNT = 500
LOCAL_LOAD_MAX_FILES_SIZE = 512 * 1024 * 1024 # 512 MB
RESTRICTIONS = {
'user_agreements': [],
# this setting reduces task visibility to owner and assignee only
'reduce_task_visibility': False,
# allow access to analytics component to users with business role
# otherwise, only the administrator has access
'analytics_visibility': True,

@ -87,9 +87,8 @@ weight = 1
section = ["HTML", "print"]
[params]
intel_terms_of_use = "https://www.intel.com/content/www/us/en/legal/terms-of-use.html"
intel_privacy_notice = "https://www.intel.com/content/www/us/en/privacy/intel-privacy-notice.html"
cvat_terms_of_use = "https://cvat.org/api/restrictions/terms-of-use"
cvat_ai_terms_of_use = "https://www.cvat.ai/terms-of-use"
cvat_privacy_notice = "https://www.cvat.ai/privacy"
# First one is picked as the Twitter card image if not set on page.
# images = ["images/project-illustration.png"]

@ -24,7 +24,6 @@ Requests are divided into groups:
- `jobs` -requests to manage the job
- `lambda` - requests to work with lambda function
- `projects` - project management queries
- `restrictions` - requests for restrictions
- `reviews` -adding and removing the review of the job
- `server` - server information requests
- `tasks` - requests to manage tasks

@ -1,15 +1,6 @@
# Footer text
[footer_intel_privacy_notice]
[footer_cvat_ai_privacy_notice]
other = "Privacy Policy"
[footer_intel_terms_of_use]
[footer_cvat_ai_terms_of_use]
other = "Terms of Use"
[footer_cvat_terms_of_use]
other = "CVAT terms of Use"
[footer_notices_and_disclaimers]
other = "Notices and Disclaimers"
[footer_human_rights_principles]
other = "Human Rights Principles"

@ -17,14 +17,9 @@
{{ end }}
</div>
<div class="col-12 col-sm-8 text-center order-sm-2">
{{ with .Site.Params.intel_privacy_notice }}<small class="mr-1"><a href="{{ . }}">{{ T "footer_intel_privacy_notice" }}</a></small>{{ end }}
{{ with .Site.Params.cvat_ai_privacy_notice }}<small class="mr-1"><a href="{{ . }}">{{ T "footer_cvat_ai_privacy_notice" }}</a></small>{{ end }}
|
{{ with .Site.Params.intel_terms_of_use }}<small class="mx-1"><a href="{{ . }}">{{ T "footer_intel_terms_of_use" }}</a></small>{{ end }}
|
{{ with .Site.Params.cvat_terms_of_use }}<small class="ml-1"><a href="{{ . }}">{{ T "footer_cvat_terms_of_use" }}</a></small>{{ end }}
<br/>
<div class="footer-disclaimer text-white ">
<small>Intel technologies may require enabled hardware, software or service activation. // No product or component can be absolutely secure. // Your costs and results may vary. // Performance varies by use, configuration and other factors. // See our complete legal <u><a href="https://edc.intel.com/content/www/us/en/products/performance/benchmarks/overview/?r=219444055">Notices and Disclaimers</a></u>. // Intel is committed to respecting human rights and avoiding complicity in human rights abuses. See Intels <a href="https://www.intel.com/content/www/us/en/policy/policy-human-rights.html"><u>Global Human Rights Principles</u></a>. Intels products and software are intended only to be used in applications that do not cause or contribute to a violation of an internationally recognized human right.</small>
{{ with .Site.Params.cvat_ai_terms_of_use }}<small class="mx-1"><a href="{{ . }}">{{ T "footer_cvat_ai_terms_of_use" }}</a></small>{{ end }}
</div>
{{ if not .Site.Params.ui.footer_about_disable }}
{{ with .Site.GetPage "about" }}<p class="mt-2"><a href="{{ .RelPermalink }}">{{ .Title }}</a></p>{{ end }}

@ -94,7 +94,7 @@ class TestCredentialsManagement:
email = "123@456.com"
with ApiClient(Configuration(host=BASE_URL)) as api_client:
(user, response) = api_client.auth_api.create_register(
models.RestrictedRegisterRequest(
models.RegisterSerializerExRequest(
username=username, password1=USER_PASS, password2=USER_PASS, email=email
)
)

Loading…
Cancel
Save