You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.5 KiB
PHP

<?php
namespace Eater\Glim\Service;
use Eater\Glim\Core;
use Eater\Glim\Model\UserQuery;
use Eater\Glim\Model\EmailAddress;
use Eater\Glim\Model\InviteQuery;
use Eater\Glim\Model\Invite;
use Eater\Glim\Model\User as UserModel;
class User extends Main
{
/**
* @param string $invite
* @param string $username
* @param string $email
* @param string $password
* @return UserModel
* @throws \Exception
*/
public function register($invite, $username, $email, $password)
{
$invite = InviteQuery::create()->findOneByInvite($invite);
if ($invite === null) {
throw new \Exception("Invalid invite code");
}
$this->validateUserParams($username, $email, $password);
$inviteUser = $invite->getUser();
$user = new UserModel();
$user->setUsername($username);
$emailAddress = new EmailAddress();
$emailAddress->setAddress($email);
$emailAddress->fillVerification();
$user->setEmailAddressRelatedByEmail($emailAddress);
$user->setPassword(\password_hash($password, PASSWORD_DEFAULT));
if ($inviteUser === null || $inviteUser->getMaxInvites() === -1) {
$user->setMaxInvites(5);
} elseif ($inviteUser->getMaxInvites() > 0) {
$user->setMaxInvites($inviteUser->getMaxInvites() - 1);
} else {
$user->setMaxInvites(0);
}
$user->save();
$emailAddress->setUserRelatedByOwner($user);
$emailAddress->save();
$this->sendVerifyMail($user);
$invite->delete();
return $user;
}
public function validateUserParams($username, $email, $password) {
if ($username === "") {
throw new \Exception("No username given");
}
if (!preg_match('~^[a-z0-9\-]+$~', $username)) {
throw new \Exception("Username can only consist of a-z, 0-9 and -");
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \Exception("Email is invalid");
}
if ($password === "") {
throw new \Exception("Password is nothing, though strong. we rather not have you use that");
}
if (strlen($password) < 9) {
throw new \Exception("Please pick a password with more then 8 characters");
}
if ($this->exists($username)) {
throw new \Exception("User already exists");
}
}
public function createSuperuser($username, $email, $password) {
$this->validateUserParams($username, $email, $password);
$user = new UserModel();
$user->setUsername($username);
$user->setPassword(\password_hash($password, PASSWORD_DEFAULT));
$user->setSuperuser(true);
$user->setMaxInvites(-1);
$emailAddress = new EmailAddress();
$emailAddress->setAddress($email);
$emailAddress->fillVerification();
$user->setEmailAddressRelatedByEmail($emailAddress);
$user->save();
$emailAddress->setUserRelatedByOwner($user);
$emailAddress->save();
$this->sendVerifyMail($user);
return $user;
}
/**
* @param string $username
* @return bool
*/
public function exists($username)
{
$amount = UserQuery::create()->findByUsername($username)->count();
return $amount > 0;
}
public function login($username, $password)
{
$user = UserQuery::create()->findOneByUsername($username);
if ($user === null || !password_verify($password, $user->getPassword())) {
return null;
}
return $user;
}
/**
* @param UserModel $user
* @return string
*/
public function createInvite(UserModel $user)
{
$invite = new Invite();
$invite->setInvite(bin2hex(openssl_random_pseudo_bytes(20)));
$invite->setUser($user);
$invite->save();
$user->setUsedInvites($user->getUsedInvites() + 1);
$user->save();
return $invite->getInvite();
}
/**
* @param UserModel $user
*/
private function sendVerifyMail(UserModel $user)
{
/** @var Mail $mail */
$mail = $this->get('mail');
$address = $user->getEmailAddressRelatedByEmail();
$mail->sendFromSystem($user, 'mails/verify_email.txt.twig', [
'username' => $user->getUsername(),
'verificationLink' => $this->get('base-url') . '/verify/' . $address->getId() . '-' . $address->getVerification()
]);
}
}