diff --git a/protected/controllers/RegistrationController.php b/protected/controllers/RegistrationController.php
index d2a8bbdb..39725790 100644
--- a/protected/controllers/RegistrationController.php
+++ b/protected/controllers/RegistrationController.php
@@ -1,398 +1,395 @@
array('index', 'enterDetails', 'confirm'),
'users' => array('@'),
),
array('allow', // Allow users not yet logged in to register accounts
'actions' => array('index', 'enterDetails', 'confirm'),
'users' => array('*'),
),
array('allow', // Allow sysadmins to see pending registrations, and view or delete them
'actions' => array('list', 'view', 'update', 'delete'),
'roles' => array('sysadmins'),
),
array('deny', // Any other action is denied
'users' => array('*'),
),
);
}
public function actionIndex()
{
// If they have confirmed they accept our terms, mark them as accepted
if( isset($_POST['confirmAcceptance']) && isset($_POST['continue']) ) {
Yii::app()->user->setState('registerTermsAccepted', 'confirmed');
}
// If they have already accepted our terms, do not reprompt them
if( Yii::app()->user->getState('registerTermsAccepted') == 'confirmed' ) {
$this->redirect( array('enterDetails') );
}
// Make sure they are not an attempted spammer
if( $this->performSpamCheck() ) {
throw new CHttpException(403, "Client rejected by automatic spammer detection system");
}
if( $this->performIpBlacklistCheck() ) {
throw new CHttpException(403, "Access Denied: Internet Service Provider blacklisted due to abuse. Please email sysadmin@kde.org to register an account.");
}
/**
* Check referer during the registration process to be able to show the user
* the page he is coming from and be able to redirect him at the end of the
* registration process.
*/
$refererHelper = new SiteReferer();
$refererHelper->checkReferer();
$this->render('index');
}
public function actionEnterDetails()
{
// Make sure they have accepted our terms....
if( Yii::app()->user->getState('registerTermsAccepted') != 'confirmed' ) {
$this->redirect( array('index') );
}
// Have they tried to register before?
if( Yii::app()->user->getState('sentRegistration') == 'yes' ) {
throw new CHttpException(403,
- "Access Denied: Attempt to perform multiple registrations detected. Spamming on KDE.org infrastructure is strictly prohibited under German, European and International Law.
" .
- "Spamming includes, without limitation, the posting of content which is intended to advertise services outside of KDE.org without the express written consent of the KDE e.V.
" .
- "WARNING: Abusive use of KDE Identity accounts is considered a violation of KDE Identity Terms of Service, and exposes you to civil and/or criminal liability." .
- "This unauthorised registration attempt has been logged for administrative attention, and may result in civil or criminal action being pursued against you.
" .
+ "Access Denied: Attempt to perform multiple registrations detected.
" .
"If you have received this notice and have not previously attempted to register, please email sysadmin@kde.org for further assistance."
);
}
$model = new Token('register');
// Maybe they have provided the needed information, in which case we need to act on it...
if( isset($_POST['Token']) ) {
$model->type = Token::TypeRegisterAccount;
$model->attributes = $_POST['Token'];
if( $this->performSpamCheck($model->mail) ) {
throw new CHttpException(403, "Client rejected by automatic spammer detection system");
}
if( $this->performCaptchaCheck() ) {
throw new CHttpException(403, "CAPTCHA Incorrect. Please go back and try again. If the CAPTCHA is not visible please disable all privacy and adblocker browser addons.");
}
if( $this->performIpBlacklistCheck() ) {
throw new CHttpException(403, "Access Denied: Internet Service Provider blacklisted due to abuse. Please email sysadmin@kde.org to register an account.");
}
if( $model->save() ) {
$this->sendEmail($model->mail, '/mail/confirmRegistration', array('model' => $model));
$this->render('confirmationSent', array('model' => $model));
Yii::app()->user->setState('sentRegistration', 'yes');
Yii::app()->end();
}
}
$this->render('enterDetails', array(
'model' => $model,
));
}
public function actionConfirm($id, $token)
{
// Ensure the provided registration confirmation is valid
$tokenModel = Token::model()->findByAttributes( array('id' => $id, 'type' => Token::TypeRegisterAccount, 'token' => $token) );
if( !$tokenModel instanceof CActiveRecord ) {
throw new CHttpException(404, 'The given validation could not be confirmed, please contact the site administrator.');
}
// Prepare the user which we will be finalising
$model = new User('register');
$knownData = $tokenModel->getAttributes( array('uid', 'givenName', 'sn', 'mail') );
$model->setAttributes( $knownData, false ); // Copy unsafe values as well as this is internally stored
// Maybe we have a submission to handle?
if( isset($_POST['User']) ) {
// Assign the inbound data
$model->attributes = $_POST['User'];
// Set the DN the new user will be created in
$model->setDnByParent( Yii::app()->params['registrationUnit'] );
// Try to create the user now. If the username/password is bad then it will fail
if( $model->save() ) {
// Creation succeeded, so cleanup....
$tokenModel->delete();
// Inform the site administrator of the account creation
//$this->sendEmail(Yii::app()->params['registerNotify'], '/mail/notifyRegistration', array('model' => $model));
// Give the user a page informing them of their account details
$this->render('complete', array('model' => $model));
Yii::app()->end();
}
}
$this->render('confirm', array(
'model' => $model,
));
}
public function actionList()
{
$model = new Token('search');
if( isset($_GET['Token']) ) {
$model->attributes = $_GET['Token'];
}
$dataProvider = new CActiveDataProvider($model, array(
'criteria' => array('condition' => 'type = ' . Token::TypeRegisterAccount),
'pagination' => array('pageSize' => 20),
));
$this->render('list', array(
'model' => $model,
'dataProvider' => $dataProvider,
));
}
public function actionView($id)
{
$model = $this->loadModel($id);
if( isset($_POST['resendConfirmation']) ) {
$this->sendEmail($model->mail, '/mail/confirmRegistration', array('model' => $model));
Yii::app()->user->setFlash('success', 'Registration confirmation has been resent.');
}
$this->render('view', array(
'model' => $model,
));
}
public function actionUpdate($id)
{
$model = $this->loadModel($id);
$model->setScenario('register');
if( isset($_POST['Token']) ) {
$model->attributes = $_POST['Token'];
if( $model->save() ) {
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('update', array(
'model' => $model,
));
}
public function actionDelete($id)
{
$model = $this->loadModel($id);
if( isset($_POST['confirmDeletion']) && isset($_POST['deleteAccount']) ) {
if( $model->delete() ) {
$this->redirect( array('list') );
}
}
$this->render('delete', array(
'model' => $model,
));
}
protected function performSpamCheck($email = "")
{
// Address of the API we are using
$query = "http://www.stopforumspam.com/api";
// We want php serialized data
$query .= "?f=serial";
// Add email address and ip address parameters if we have them...
if( $email != "" ) {
$query .= "&email=" . trim($email);
}
// Add the ip address
$query .= "&ip=" . Yii::app()->request->userHostAddress;
// Perform the query...
$result = @file_get_contents($query);
// if we have network issues, let him through.
if( $result === false ) {
return false;
}
// Decode the data we recieved
$result = unserialize($result);
// if the query failed, permit the request
if( $result["success"] != 1 ) {
return false;
}
// If there is a greater than 80% the ip address is used by spammers, reject the request
if( isset($result["ip"]["confidence"] ) && $result["ip"]["confidence"] > 80 ) {
return true;
}
// If the email address has been used to spam anywhere, reject the request
if( $email != "" && isset($result["email"]["confidence"]) && $result["email"]["confidence"] > 0 ) {
return true;
}
// let everyone through.
return false;
}
protected function performCaptchaCheck()
{
$secret = Yii::app()->params['recaptcha-secret'];
$recaptcha = new ReCaptcha($secret);
$resp = $recaptcha->verify(
Yii::app()->request->getPost('g-recaptcha-response'),
Yii::app()->request->userHostAddress
);
if( !$resp->isSuccess() ) {
return true;
}
return false;
}
protected function performIpBlacklistCheck()
{
$userIp = Yii::app()->request->userHostAddress;
$blacklistedRanges = array(
// Shenzhen Tinmok Information Network Co (Chinese Network Provider)
'103.56.218.0/23',
// Moomu (Unknown)
'103.27.220.0/25',
// Bharti Airtel Ltd (Indian ISP)
'122.177.0.0/16',
'182.64.0.0/12',
'122.180.0.0/16',
// Nextra Televentures (Indian ISP)
'103.30.252.0/24',
'103.225.43.0/24',
// Odeon Infrastructure (Indian ISP)
'45.120.58.0/24',
// Tata Teleservices (Indian ISP)
'14.96.0.0/14',
'61.12.64.0/19',
'14.98.96.0/20',
'14.98.128.0/20',
'121.245.126.0/24',
// Precious Netcom Pvt Ltd (Indian ISP)
'43.230.198.0/24',
// Anjani Broadband Solutions (Indian ISP)
'43.225.193.0/24',
// Den Digital Entertainment Networks (Indian ISP)
'112.196.128.0/18',
// Hathway Cable (Indian ISP)
'116.72.0.0/14',
// Speednet (Indian ISP)
'110.172.140.0/24',
// Spectranet (Indian ISP)
'180.151.0.0/16',
// Citycom Networks (Indian ISP)
'125.63.64.0/18',
// BSNL (Indian ISP)
'117.220.0.0/15',
// Dabas IT (Indian VPS)
'103.199.120.0/22',
// City Reservations Private Limited (Indian Corporate)
'45.115.141.0/24',
'45.115.142.0/24',
// Neo SunCity Private Limited (Indian Corporate)
'45.121.191.0/24',
// Quadranet (American VPS)
'104.223.0.0/17',
// DigitalOcean (American VPS)
'46.101.0.0/17',
'162.243.0.0/16',
'104.131.0.0/16',
'104.236.0.0/16',
'107.170.0.0/16',
// Choopa LLC (American VPS)
'108.61.0.0/16',
// EGI Hosting (American VPS)
'72.13.80.0/20',
// Lunanode Hosting (American VPS)
'170.75.160.0/20',
// Secured Servers LLC (American VPS)
'66.85.128.0/18',
// Atlantic.net Inc (American ??)
'69.28.64.0/19',
// Xponent LLC (American / Australian Corporate)
'103.251.64.0/24',
'103.251.65.0/24',
// Unus, Inc (American Corporate)
'128.90.0.0/16',
// UK2 Infrastructure (Unknown)
'185.80.220.0/23',
'159.253.145.128/26',
'37.130.224.0/21',
// Falco Networks B.V (French ?)
'85.203.17.0/24',
'85.203.18.0/24',
// NForce Entertainment B.V
// Offending sub-block delegated to Alanna Investment Limited in the British Virgin Islands
// Due to it's reputation - we're blaming the parent owner of the IP block and banning the entire thing
'46.166.136.0/21',
// GleSYS Internet Services AB (Swedish VPS)
'46.21.96.0/20',
// Comvive Servidores S.L. (Spanish VPS)
'93.93.64.0/21',
// Linode (Japan)
'106.187.48.0/21',
);
foreach( $blacklistedRanges as $ipRange ) {
// Compute the necessary details for this IP range
list ($net, $mask) = split("/", $ipRange);
$ip_net = ip2long($net);
$ip_mask = ~((1 << (32 - $mask)) - 1);
// Breakdown the information about our user's IP address
$ip_ip = ip2long($userIp);
$ip_ip_net = $ip_ip & $ip_mask;
if( $ip_ip_net == $ip_net ) {
return true;
}
}
return false;
}
protected function loadModel($id)
{
$model = Token::model()->findByAttributes( array('id' => $id, 'type' => Token::TypeRegisterAccount) );
if( $model === null ) {
throw new CHttpException(404, 'The requested page does not exist.');
}
return $model;
}
}