Remove old member registration

This commit is contained in:
Tanner Collin 2021-11-15 05:57:18 +00:00
parent fc70bbca00
commit 04fa121fe9
5 changed files with 23 additions and 109 deletions

View File

@ -563,7 +563,6 @@ class UserSerializer(serializers.ModelSerializer):
class MyRegisterSerializer(RegisterSerializer): class MyRegisterSerializer(RegisterSerializer):
first_name = serializers.CharField(max_length=32) first_name = serializers.CharField(max_length=32)
last_name = serializers.CharField(max_length=32) last_name = serializers.CharField(max_length=32)
existing_member = serializers.ChoiceField(['true', 'false'])
request_id = serializers.CharField(required=False) request_id = serializers.CharField(required=False)
def validate_username(self, username): def validate_username(self, username):
@ -578,13 +577,7 @@ class MyRegisterSerializer(RegisterSerializer):
def custom_signup(self, request, user): def custom_signup(self, request, user):
data = request.data data = request.data
if secrets.REGISTRATION_BYPASS: if not utils.is_request_from_protospace(request):
bypass_code = data.get('bypass_code', None)
allow_bypass = secrets.REGISTRATION_BYPASS == bypass_code
else:
allow_bypass = False
if not allow_bypass and not utils.is_request_from_protospace(request):
logger.info('Request not from protospace') logger.info('Request not from protospace')
user.delete() user.delete()
raise ValidationError(dict(non_field_errors='Can only register from Protospace.')) raise ValidationError(dict(non_field_errors='Can only register from Protospace.'))

View File

@ -20,6 +20,7 @@ from django.core.cache import cache
from django.utils.timezone import now, pytz from django.utils.timezone import now, pytz
from . import models, serializers, utils_ldap, utils_stats, utils_auth, utils from . import models, serializers, utils_ldap, utils_stats, utils_auth, utils
from .. import settings
STATIC_FOLDER = 'data/static/' STATIC_FOLDER = 'data/static/'
@ -280,71 +281,14 @@ clean = Cleaner(tags=ALLOWED_TAGS).clean
def is_request_from_protospace(request): def is_request_from_protospace(request):
whitelist = ['24.66.110.96', '205.233.15.76', '205.233.15.69'] whitelist = ['24.66.110.96', '205.233.15.76', '205.233.15.69']
if settings.DEBUG:
return True
# set (not appended) directly by nginx so we can trust it # set (not appended) directly by nginx so we can trust it
real_ip = request.META.get('HTTP_X_REAL_IP', False) real_ip = request.META.get('HTTP_X_REAL_IP', False)
return real_ip in whitelist return real_ip in whitelist
def link_old_member(data, user):
'''
If a member claims they have an account on the old protospace portal,
go through and link their objects to their new user using the member_id
found with their email as a hint
Since this runs AFTER registration, we need to delete the user on any
failures or else the username will be taken when they try again
'''
try:
member = models.Member.objects.get(old_email__iexact=data['email'])
except models.Member.DoesNotExist:
msg = 'Unable to find email in old portal. Try a different one or ask a director to look up which one you used.'
logger.info(msg)
raise ValidationError(dict(email=msg))
except models.Member.MultipleObjectsReturned:
msg = 'Duplicate emails found. Talk to Tanner.'
logger.info(msg)
raise ValidationError(dict(email=msg))
if member.user:
msg = 'Old member already claimed.'
logger.info(msg)
raise ValidationError(dict(email=msg))
if utils_ldap.is_configured():
if data['request_id']: utils_stats.set_progress(data['request_id'], 'Finding LDAP account...')
result = utils_ldap.find_user(user.username)
if result == 200:
if utils_ldap.set_password(data) != 200:
msg = 'Problem connecting to LDAP server: set.'
alert_tanner(msg)
logger.info(msg)
raise ValidationError(dict(non_field_errors=msg))
elif result == 404:
if utils_ldap.create_user(data) != 200:
msg = 'Problem connecting to LDAP server: create.'
alert_tanner(msg)
logger.info(msg)
raise ValidationError(dict(non_field_errors=msg))
else:
msg = 'Problem connecting to LDAP server: find.'
alert_tanner(msg)
logger.info(msg)
raise ValidationError(dict(non_field_errors=msg))
if data['request_id']: utils_stats.set_progress(data['request_id'], 'Linking old member data...')
member.user = user
member.first_name = data['first_name'].title()
member.last_name = data['last_name'].title()
member.preferred_name = data['first_name'].title()
member.save()
models.Transaction.objects.filter(member_id=member.id).update(user=user)
models.Card.objects.filter(member_id=member.id).update(user=user)
models.Training.objects.filter(member_id=member.id).update(user=user)
def create_new_member(data, user): def create_new_member(data, user):
members = models.Member.objects members = models.Member.objects
if members.filter(old_email__iexact=data['email']).exists(): if members.filter(old_email__iexact=data['email']).exists():
@ -384,12 +328,8 @@ def create_new_member(data, user):
def register_user(data, user): def register_user(data, user):
try: try:
if data['existing_member'] == 'true': logger.info('Creating new member...')
logger.info('Linking old member...') create_new_member(data, user)
link_old_member(data, user)
else:
logger.info('Creating new member...')
create_new_member(data, user)
except: except:
user.delete() user.delete()
raise raise

View File

@ -12,13 +12,6 @@ ADMIN_RANDOM = ''
# head /dev/urandom | base32 | head -c 16 # head /dev/urandom | base32 | head -c 16
IPN_RANDOM = '' IPN_RANDOM = ''
# Registration bypass code
# Allows people to register outside of protospace
# Set this to random characters
# For example, use the output of this:
# head /dev/urandom | base32 | head -c 16
REGISTRATION_BYPASS = ''
# Django secret key # Django secret key
# Set this to random characters # Set this to random characters
# For example, use the output of this: # For example, use the output of this:

View File

@ -144,8 +144,6 @@ export function Home(props) {
const [refreshCount, refreshStats] = useReducer(x => x + 1, 0); const [refreshCount, refreshStats] = useReducer(x => x + 1, 0);
const location = useLocation(); const location = useLocation();
const bypass_code = location.hash.replace('#', '');
useEffect(() => { useEffect(() => {
requester('/stats/', 'GET', token) requester('/stats/', 'GET', token)
.then(res => { .then(res => {
@ -174,7 +172,7 @@ export function Home(props) {
const doorOpenStat = () => alarmStat() == 'Disarmed' && stats.alarm['data'] > 360 ? ', door open' : ''; const doorOpenStat = () => alarmStat() == 'Disarmed' && stats.alarm['data'] > 360 ? ', door open' : '';
const show_signup = stats?.at_protospace || bypass_code; const show_signup = stats?.at_protospace;
return ( return (
<Container> <Container>
@ -194,18 +192,9 @@ export function Home(props) {
</div> </div>
: :
<div> <div>
{bypass_code ? <LoginForm {...props} />
<Message warning>
<Message.Header>Outside Registration</Message.Header>
<p>This page allows you to sign up from outside of Protospace.</p>
</Message>
:
<>
<LoginForm {...props} />
<Divider section horizontal>Or</Divider> <Divider section horizontal>Or</Divider>
</>
}
<SignupForm {...props} show_signup={show_signup} /> <SignupForm {...props} show_signup={show_signup} />
</div> </div>

View File

@ -74,8 +74,6 @@ export function SignupForm(props) {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const location = useLocation(); const location = useLocation();
const bypass_code = location.hash.replace('#', '');
const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value }); const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value });
const handleChange = (e) => handleValues(e, e.currentTarget); const handleChange = (e) => handleValues(e, e.currentTarget);
@ -103,11 +101,7 @@ export function SignupForm(props) {
}; };
const interval = setInterval(getStatus, 500); const interval = setInterval(getStatus, 500);
const data = { ...input, email: input.email.toLowerCase(), bypass_code: bypass_code, request_id: request_id }; const data = { ...input, email: input.email.toLowerCase(), request_id: request_id };
if (bypass_code) {
data.existing_member = true;
}
requester('/registration/', 'POST', '', data) requester('/registration/', 'POST', '', data)
.then(res => { .then(res => {
@ -161,24 +155,29 @@ export function SignupForm(props) {
error={error.email} error={error.email}
/> />
{!!bypass_code || <Form.Group grouped> <Form.Group grouped>
<Form.Radio <Form.Radio
label='I have an account on the old portal' label='I have an account on the old portal'
name='existing_member' name='existing_member'
value={'true'} value={true}
checked={input.existing_member === 'true'} checked={input.existing_member === true}
onChange={handleValues} onChange={handleValues}
error={!!error.existing_member} error={!!error.existing_member}
/> />
<Form.Radio <Form.Radio
label='I am new to Protospace' label='I am new to Protospace'
name='existing_member' name='existing_member'
value={'false'} value={false}
checked={input.existing_member === 'false'} checked={input.existing_member === false}
onChange={handleValues} onChange={handleValues}
error={!!error.existing_member} error={!!error.existing_member}
/> />
</Form.Group>} </Form.Group>
{input.existing_member && <Message info>
<Message.Header>Welcome back!</Message.Header>
<p>Please do a <Link to='/password/reset'>password reset</Link> instead.</p>
</Message>}
<Form.Input <Form.Input
label='Password' label='Password'
@ -199,7 +198,7 @@ export function SignupForm(props) {
{progress.map(x => <>{x}<br /></>)} {progress.map(x => <>{x}<br /></>)}
</p> </p>
<Form.Button loading={loading} error={error.non_field_errors}> <Form.Button loading={loading} error={error.non_field_errors} disabled={input.existing_member !== false}>
Sign Up Sign Up
</Form.Button> </Form.Button>
</> </>