Skip to content

Commit

Permalink
login: restrict diacritic characters (fixes #2659) (#2661)
Browse files Browse the repository at this point in the history
Co-authored-by: dogi <[email protected]>
  • Loading branch information
Okuro3499 and dogi authored Nov 1, 2023
1 parent d0ef366 commit 510c414
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 35 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ android {
applicationId "org.ole.planet.myplanet"
minSdkVersion 21
targetSdkVersion 34
versionCode 1129
versionName "0.11.29"
versionCode 1130
versionName "0.11.30"
ndkVersion '21.3.6528147'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.drawable.AnimationDrawable;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Editable;
Expand Down Expand Up @@ -66,13 +67,16 @@
import org.ole.planet.myplanet.utilities.SharedPrefManager;
import org.ole.planet.myplanet.utilities.Utilities;

import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import io.realm.Realm;
Expand Down Expand Up @@ -338,25 +342,43 @@ private void showGuestLoginDialog() {
alertGuestLoginBinding.etUserName.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
char firstChar = s.length() > 0 ? s.charAt(0) : '\0';
String input = s.toString();
char firstChar = input.length() > 0 ? input.charAt(0) : '\0';
boolean hasInvalidCharacters = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
boolean hasSpecialCharacters = false;
boolean hasDiacriticCharacters = false;

String normalizedText = Normalizer.normalize(s, Normalizer.Form.NFD);

for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c != '_' && c != '.' && c != '-' && !Character.isDigit(c) && !Character.isLetter(c)) {
hasInvalidCharacters = true;
break;
}
}

String regex = ".*[ßäöüéèêæÆœøØ¿àìòùÀÈÌÒÙáíóúýÁÉÍÓÚÝâîôûÂÊÎÔÛãñõÃÑÕëïÿÄËÏÖÜŸåÅŒçÇðÐ].*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
hasSpecialCharacters = matcher.matches();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
hasDiacriticCharacters = !normalizedText.codePoints().allMatch(
codePoint -> Character.isLetterOrDigit(codePoint) || codePoint == '.' || codePoint == '-' || codePoint == '_'
);
}

if (!Character.isDigit(firstChar) && !Character.isLetter(firstChar)) {
alertGuestLoginBinding.etUserName.setError(getString(R.string.must_start_with_letter_or_number));
} else if (hasInvalidCharacters) {
} else if (hasInvalidCharacters || hasDiacriticCharacters || hasSpecialCharacters) {
alertGuestLoginBinding.etUserName.setError(getString(R.string.only_letters_numbers_and_are_allowed));
} else {
String lowercaseText = s.toString().toLowerCase(Locale.ROOT);
if (!s.toString().equals(lowercaseText)) {
String lowercaseText = input.toLowerCase(Locale.ROOT);
if (!input.equals(lowercaseText)) {
alertGuestLoginBinding.etUserName.setText(lowercaseText);
alertGuestLoginBinding.etUserName.setSelection(lowercaseText.length());
}
Expand Down Expand Up @@ -387,8 +409,14 @@ public void afterTextChanged(Editable s) {}
String username = alertGuestLoginBinding.etUserName.getText().toString().trim();
Character firstChar = username.isEmpty() ? null : username.charAt(0);
boolean hasInvalidCharacters = false;

boolean hasDiacriticCharacters = false;
boolean hasSpecialCharacters = false;
boolean isValid = true;
String normalizedText = Normalizer.normalize(username, Normalizer.Form.NFD);

String regex = ".*[ßäöüéèêæÆœøØ¿àìòùÀÈÌÒÙáíóúýÁÉÍÓÚÝâîôûÂÊÎÔÛãñõÃÑÕëïÿÄËÏÖÜŸåÅŒçÇðÐ].*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(username);

if (TextUtils.isEmpty(username)) {
alertGuestLoginBinding.etUserName.setError(getString(R.string.username_cannot_be_empty));
Expand All @@ -404,9 +432,16 @@ public void afterTextChanged(Editable s) {}
hasInvalidCharacters = true;
break;
}

hasSpecialCharacters = matcher.matches();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
hasDiacriticCharacters = !normalizedText.codePoints().allMatch(
codePoint -> Character.isLetterOrDigit(codePoint) || codePoint == '.' || codePoint == '-' || codePoint == '_'
);
}
}

if (hasInvalidCharacters) {
if (hasInvalidCharacters || hasDiacriticCharacters || hasSpecialCharacters) {
alertGuestLoginBinding.etUserName.setError(getString(R.string.only_letters_numbers_and_are_allowed));
isValid = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import android.app.DatePickerDialog
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.view.View
import android.widget.ArrayAdapter
import android.widget.RadioButton
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import io.realm.Realm
Expand All @@ -27,8 +27,10 @@ import org.ole.planet.myplanet.ui.sync.SyncActivity
import org.ole.planet.myplanet.utilities.NetworkUtils
import org.ole.planet.myplanet.utilities.Utilities
import org.ole.planet.myplanet.utilities.VersionUtils
import java.text.Normalizer
import java.util.Calendar
import java.util.Locale
import java.util.regex.Pattern

class BecomeMemberActivity : BaseActivity() {
private lateinit var activityBecomeMemberBinding: ActivityBecomeMemberBinding
Expand Down Expand Up @@ -76,26 +78,45 @@ class BecomeMemberActivity : BaseActivity() {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
s?.let {
val firstChar = if (it.isNotEmpty()) it[0] else null
val input = s.toString()

val hasInvalidCharacters = it.any { char ->
char != '_' && char != '.' && char != '-' &&
!Character.isDigit(char) && !Character.isLetter(char)
val firstChar = if (input.isNotEmpty()) input[0] else '\u0000'
var hasInvalidCharacters = false
var hasSpecialCharacters = false
var hasDiacriticCharacters = false

val normalizedText = Normalizer.normalize(s, Normalizer.Form.NFD)

for (element in input) {
if (element != '_' && element != '.' && element != '-'
&& !Character.isDigit(element) && !Character.isLetter(element)) {
hasInvalidCharacters = true
break
}
}

val regex = ".*[ßäöüéèêæÆœøØ¿àìòùÀÈÌÒÙáíóúýÁÉÍÓÚÝâîôûÂÊÎÔÛãñõÃÑÕëïÿÄËÏÖÜŸåÅŒçÇðÐ].*"
val pattern = Pattern.compile(regex)
val matcher = pattern.matcher(input)

hasSpecialCharacters = matcher.matches()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
hasDiacriticCharacters = !normalizedText.codePoints().allMatch { codePoint: Int ->
Character.isLetterOrDigit(codePoint) || codePoint == '.'.code || codePoint == '-'.code || codePoint == '_'.code
}
}

if (firstChar != null && !Character.isDigit(firstChar) && !Character.isLetter(firstChar)) {
activityBecomeMemberBinding.etUsername.error = getString(R.string.must_start_with_letter_or_number)
} else if (hasInvalidCharacters) {
if (!Character.isDigit(firstChar) && !Character.isLetter(firstChar)) {
activityBecomeMemberBinding.etUsername.error = getString(R.string.must_start_with_letter_or_number)
} else if (hasInvalidCharacters || hasDiacriticCharacters || hasSpecialCharacters) {
activityBecomeMemberBinding.etUsername.error = getString(R.string.only_letters_numbers_and_are_allowed)
} else {
val lowercaseText = it.toString().toLowerCase(Locale.ROOT)
if (it.toString() != lowercaseText) {
activityBecomeMemberBinding.etUsername.setText(lowercaseText)
activityBecomeMemberBinding.etUsername.setSelection(lowercaseText.length)
}
activityBecomeMemberBinding.etUsername.error = null
} else {
val lowercaseText = input.lowercase()
if (input != lowercaseText) {
activityBecomeMemberBinding.etUsername.setText(lowercaseText)
activityBecomeMemberBinding.etUsername.setSelection(lowercaseText.length)
}
activityBecomeMemberBinding.etUsername.error = null
}
}

Expand All @@ -122,18 +143,27 @@ class BecomeMemberActivity : BaseActivity() {

val firstChar = if (username!!.isNotEmpty()) username[0] else null
val hasInvalidCharacters = username.any { char ->
char != '_' && char != '.' && char != '-' &&
!Character.isDigit(char) && !Character.isLetter(char)
char != '_' && char != '.' && char != '-' && !Character.isDigit(char) && !Character.isLetter(char)
}

val normalizedText = Normalizer.normalize(username, Normalizer.Form.NFD)

val regex = ".*[ßäöüéèêæÆœøØ¿àìòùÀÈÌÒÙáíóúýÁÉÍÓÚÝâîôûÂÊÎÔÛãñõÃÑÕëïÿÄËÏÖÜŸåÅŒçÇðÐ].*"
val pattern = Pattern.compile(regex)
val matcher = pattern.matcher(username)

val hasSpecialCharacters = matcher.matches()
val hasDiacriticCharacters = !normalizedText.codePoints().allMatch { codePoint: Int ->
Character.isLetterOrDigit(codePoint) || codePoint == '.'.code || codePoint == '-'.code || codePoint == '_'.code
}

if (TextUtils.isEmpty(username)) {
activityBecomeMemberBinding.etUsername.error = getString(R.string.please_enter_a_username)
} else if (username.contains(" ")) {
activityBecomeMemberBinding.etUsername.error = getString(R.string.invalid_username)
} else if (firstChar != null && !Character.isDigit(firstChar) && !Character.isLetter(firstChar)) {
activityBecomeMemberBinding.etUsername.error = getString(R.string.must_start_with_letter_or_number)
} else if (hasInvalidCharacters) {
} else if (hasInvalidCharacters || hasSpecialCharacters || hasDiacriticCharacters) {
activityBecomeMemberBinding.etUsername.error = getString(R.string.only_letters_numbers_and_are_allowed)
} else if (TextUtils.isEmpty(password)) {
activityBecomeMemberBinding.etPassword.error = getString(R.string.please_enter_a_password)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@
<string name="ai_chat">AI Chat</string>
<string name="kindly_give_a_rating">يرجى التقييم</string>
<string name="must_start_with_letter_or_number">يجب أن تبدأ بحرف أو رقم</string>
<string name="only_letters_numbers_and_are_allowed">يُسمح فقط بالحروف والأرقام و "_" و "." و "-"</string>
<string name="only_letters_numbers_and_are_allowed">فقط الأحرف من a إلى z والأرقام و "_" و "." و "-" مسموح بها</string>
<string name="unselect_all">إلغاء تحديد الكل</string>
<string name="select_all">تحديد الكل</string>
<string name="request_failed_please_retry">الطلب فشل، يرجى إعادة المحاولة</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@
<string name="ai_chat">AI Chat</string>
<string name="kindly_give_a_rating">Por favor, dé una calificación</string>
<string name="must_start_with_letter_or_number">Debe comenzar con una letra o número</string>
<string name="only_letters_numbers_and_are_allowed">Solo se permiten letras, números, "_" , ".", y "-"</string>
<string name="only_letters_numbers_and_are_allowed">Solo se permiten letras de la a a la z, números y "_", ".", y "-"</string>
<string name="unselect_all">Deseleccionar todo</string>
<string name="select_all">Seleccionar todo</string>
<string name="request_failed_please_retry">La solicitud ha fallado, por favor inténtelo de nuevo</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@
<string name="ai_chat">AI Chat</string>
<string name="kindly_give_a_rating">Veuillez donner une note</string>
<string name="must_start_with_letter_or_number">Doit commencer par une lettre ou un chiffre</string>
<string name="only_letters_numbers_and_are_allowed">Seules les lettres, les chiffres, "_" , ".", et "-" sont autorisés</string>
<string name="only_letters_numbers_and_are_allowed">Seules les lettres de a à z, les chiffres, le "_", ".", et "-" sont autorisés</string>
<string name="unselect_all">Désélectionner tout</string>
<string name="select_all">Sélectionner tout</string>
<string name="request_failed_please_retry">La demande a échoué, veuillez réessayer</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-ne/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@
<string name="ai_chat">AI Chat</string>
<string name="kindly_give_a_rating">कृपया मूल्याङ्कन दिनुहोस्</string>
<string name="must_start_with_letter_or_number">पात्र वा नम्बरसँग सुरु गर्नु पर्दछ</string>
<string name="only_letters_numbers_and_are_allowed">केवल अक्षर, नम्बर, "_" , ".", र "-" पाएको छ</string>
<string name="only_letters_numbers_and_are_allowed">केवल अक्षरहरू a- z, नम्बर"_" , "." , "-" पार्स्याद छ</string>
<string name="unselect_all">सबै चयन गर्दिन</string>
<string name="select_all">सबै चयन गर्नुहोस्</string>
<string name="request_failed_please_retry">अनुरोध असफल भयो, कृपया पुन: प्रयास गर्नुहोस्</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-so/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@
<string name="ai_chat">AI Chat</string>
<string name="kindly_give_a_rating">si naxariis leh u bixi rating</string>
<string name="must_start_with_letter_or_number">Waa in la bilaabo lambarka ama tirada</string>
<string name="only_letters_numbers_and_are_allowed">Waxaad ka ogolaan kartaa lambarka, tirada, "_", ".", iyo "-"</string>
<string name="only_letters_numbers_and_are_allowed">Waa kaliya luuqadaha a-z, lambarka, "_", ".", iyo "-" ayaa la oggolaaday</string>
<string name="unselect_all">Dhammaad Maareey</string>
<string name="select_all">Dhammaad Dhammaadee</string>
<string name="request_failed_please_retry">Codka lama yimaado, fadlan dib ugu ciyaar</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@
<string name="ai_chat">AI Chat</string>
<string name="kindly_give_a_rating">Kindly give a rating</string>
<string name="must_start_with_letter_or_number">Must start with letter or number</string>
<string name="only_letters_numbers_and_are_allowed">Only letters, numbers and "_" , ".", "-" are allowed</string>
<string name="only_letters_numbers_and_are_allowed">Only letters a-z, numbers and "_" , ".", "-" are allowed</string>
<string name="config_not_available" translatable="false">Config not available.</string>
<string name="unselect_all">Unselect All</string>
<string name="select_all">Select All</string>
Expand Down

0 comments on commit 510c414

Please sign in to comment.