Esempio n. 1
0
 /**
  * Method to add a note to a ticket.
  *
  * @param int    $ticketID
  * @param string $token
  *
  * @return \Illuminate\Http\Response
  */
 public function addNote($ticketID, $token)
 {
     $submittor = false;
     $ticket = Ticket::find($ticketID);
     $AshAuthorisedBy = Request::get('AshAuthorisedBy');
     if ($AshAuthorisedBy == 'TokenIP') {
         $account = Account::find($ticket->ip_contact_account_ip);
         $submittor = trans('ash.basic.ip') . ' ' . trans('ash.communication.contact');
     }
     if ($AshAuthorisedBy == 'TokenDomain') {
         $account = Account::find($ticket->domain_contact_account_id);
         $submittor = trans('ash.basic.domain') . ' ' . trans('ash.communication.contact');
     }
     $brand = empty($account) ? Brand::getSystemBrand() : $account->brand;
     if (empty($brand) || empty($submittor)) {
         abort(500);
     }
     $changeStatus = Input::get('changeStatus');
     if ($changeStatus == 'IGNORED' || $changeStatus == 'RESOLVED') {
         $ticket->contact_status_id = $changeStatus;
         $ticket->save();
     }
     $text = Input::get('text');
     if (empty($text) || strlen($text) < 1) {
         $message = 'noteEmpty';
     } else {
         $message = 'noteAdded';
         $note = new Note();
         $note->ticket_id = $ticket->id;
         $note->submitter = $submittor;
         $note->text = $text;
         $note->save();
     }
     return view('ash')->with('brand', $brand)->with('ticket', $ticket)->with('allowedChanges', $this->allowedStatusChanges($ticket))->with('token', $token)->with('message', $message);
 }
Esempio n. 2
0
 /**
  * this should not be part of the setUp method because the database connection
  * has NOT been setUp properly at that moment.
  */
 private function initDB()
 {
     Account::where('id', '!=', 1)->delete();
     $this->accounts = factory(Account::class, 10)->create();
     $this->name1 = $this->accounts->first()->name;
     $this->name2 = $this->accounts->get(1)->name;
 }
Esempio n. 3
0
 public function testValidCreate()
 {
     $faker = Factory::create();
     $name = $faker->name;
     Artisan::call('contact:create', ['name' => $name, 'reference' => $faker->domainWord, 'account_id' => Account::getSystemAccount()->id, 'enabled' => $faker->boolean(), 'email' => $faker->email, 'api_host' => $faker->url]);
     $this->assertContains('The contact has been created', Artisan::output());
     Contact::where('name', $name)->forceDelete();
 }
Esempio n. 4
0
 public function testSetSystemAccount()
 {
     $this->initDB();
     $exitCode = Artisan::call('account:edit', ['id' => $this->account->id, '--systemaccount' => true]);
     $this->assertEquals($exitCode, 0);
     $this->assertContains('The account has been updated', Artisan::output());
     $this->assertTrue((bool) Account::find($this->account->id)->systemaccount);
 }
Esempio n. 5
0
 public function testCreateValid()
 {
     $brand = factory(Brand::class)->create();
     Artisan::call('account:create', ['name' => 'test_dummy', 'brand_id' => $brand->id]);
     $output = Artisan::output();
     $this->assertContains('The account has been created', $output);
     Account::where('name', 'test_dummy')->forceDelete();
     $brand->forceDelete();
 }
Esempio n. 6
0
 /**
  * @return Brand
  */
 protected function getModelFromRequest()
 {
     $brand = new Brand();
     $brand->name = $this->argument('name');
     $brand->company_name = $this->argument('company_name');
     $brand->introduction_text = $this->argument('introduction_text');
     $brand->logo = Brand::getDefaultLogo();
     $brand->creator_id = Account::getSystemAccount()->id;
     return $brand;
 }
Esempio n. 7
0
 /**
  * @param $name
  *
  * @return mixed
  */
 protected function findAccountByName($name)
 {
     $account = Account::where('id', $name)->orWhere('name', $name)->first();
     if ($account === null) {
         $account = Account::find(['name' => 'Default'])->first();
         if ($account === null) {
             $account = Account::all()->first();
         }
         $this->info(sprintf("No account was found for given account name so '%s' was used", $account->name));
     }
     return $account;
 }
Esempio n. 8
0
 /**
  * Return undefined contact.
  *
  * @return object
  */
 public static function undefined()
 {
     $account = Account::system();
     $contact = new Contact();
     $contact->reference = 'UNDEF';
     $contact->name = 'Undefined Contact';
     $contact->enabled = true;
     $contact->auto_notify = false;
     $contact->email = '';
     $contact->api_host = '';
     $contact->account_id = $account->id;
     return $contact;
 }
Esempio n. 9
0
 /**
  * {@inheritdoc}.
  */
 protected function handleOptions($model)
 {
     $this->updateFieldWithOption($model, 'first_name');
     $this->updateFieldWithOption($model, 'last_name');
     $this->updateFieldWithOption($model, 'email');
     $this->handleLanguageUpdate($model);
     $this->handleEnableDisable($model);
     if (!empty($this->option('account'))) {
         $newAccount = Account::find($this->option('account'));
         if (null === $newAccount) {
             $this->error('Unable to find account with this criteria');
             return false;
         }
         $model->account_id = $newAccount->id;
     }
     $this->handlePasswordUpdate($model);
     return true;
 }
Esempio n. 10
0
 /**
  * Get the validation rules that apply to the request.
  *
  * @return array
  */
 public function rules()
 {
     switch ($this->method) {
         case 'GET':
             break;
         case 'DELETE':
             break;
         case 'POST':
             return Account::createRules($this);
         case 'PUT':
             break;
         case 'PATCH':
             return Account::updateRules($this);
         default:
             break;
     }
     return [];
 }
Esempio n. 11
0
 /**
  * Execute the console command.
  *
  * @return boolean
  */
 public function handle()
 {
     $generatedPassword = substr(md5(rand()), 0, 8);
     if (empty($this->option('password'))) {
         $this->info("Using auto generated password: {$generatedPassword}");
     }
     if (empty($this->option('account'))) {
         $account = Account::where('name', '=', 'default')->first();
     } else {
         $account = Account::where('name', '=', $this->option('account'))->first();
         if (!is_object($account)) {
             $this->error("The account named {$this->option('account')} was not found");
             return false;
         }
     }
     $user = new User();
     $user->email = empty($this->option('email')) ? false : $this->option('email');
     $user->password = empty($this->option('password')) ? $generatedPassword : $this->option('password');
     $user->first_name = $this->option('firstname');
     $user->last_name = $this->option('lastname');
     $user->locale = $this->option('language');
     $user->account_id = $account->id;
     $user->disabled = $this->option('disabled');
     $validation = Validator::make($user->toArray(), User::createRules($user));
     if ($validation->fails()) {
         foreach ($validation->messages()->all() as $message) {
             $this->warn($message);
         }
         $this->error('Failed to create the user due to validation warnings');
         return false;
     }
     if (!$user->save()) {
         $this->error('Failed to save the user into the database');
         return false;
     }
     $this->info("The user {$this->option('email')} has been created");
     return true;
 }
Esempio n. 12
0
 /**
  * Remove the specified resource from storage.
  *
  * @param  int  $id
  * @return \Illuminate\Http\Response
  */
 public function destroy(Account $account)
 {
     // Do not allow the default admin user account to be deleted.
     if ($account->id == 1) {
         return Redirect::back()->with('message', 'Not allowed to delete the default admin account.');
     }
     $account->delete();
     // todo: delete related users/brands as well
     return Redirect::route('admin.accounts.index')->with('message', 'Account and it\'s related users and brands have been deleted.');
 }
Esempio n. 13
0
 /**
  * Show the form for editing the specified resource.
  *
  * @param  User   $user
  * @return \Illuminate\Http\Response
  */
 public function edit(User $user)
 {
     $accounts = Account::lists('name', 'id');
     return view('users.edit')->with('user', $user)->with('account_selection', $accounts)->with('selected', $user->account_id)->with('auth_user', $this->auth_user);
 }
Esempio n. 14
0
 /**
  * Static method to check if the account has access to the model instance.
  *
  * @param  $model_id                        Model Id
  * @param \AbuseIO\Models\Account $account The Account Model
  *
  * @return bool
  */
 public static function checkAccountAccess($model_id, Account $account)
 {
     // Early return when we are in the system account
     if ($account->isSystemAccount()) {
         return true;
     }
     $ticket = self::find($model_id);
     $allowed = $ticket->ip_contact_account_id == $account->id || $ticket->domain_contact_account_id == $account->id;
     return $allowed;
 }
Esempio n. 15
0
 /**
  * Static method to check if the account has access to the model instance.
  *
  * @param int                     $model_id
  * @param \AbuseIO\Models\Account $account
  *
  * @return bool
  */
 public static function checkAccountAccess($model_id, Account $account)
 {
     // Early return when we are in the system account
     if ($account->isSystemAccount()) {
         return true;
     }
     // Get all tickets related to this evidence
     $tickets = self::find($model_id)->tickets;
     // If tickets ip or domain contact is the same as current account
     // then allow access to this evidence
     foreach ($tickets as $ticket) {
         if ($ticket->ip_contact_account_id == $account->id || $ticket->domain_contact_account_id == $account->id) {
             return true;
         }
     }
     return false;
 }
Esempio n. 16
0
 /**
  * {@inherit docs}.
  */
 protected function getCollectionWithArguments()
 {
     return Account::where('name', 'like', '%' . $this->argument('account') . '%')->orWhere('id', $this->argument('account'));
 }
Esempio n. 17
0
 /**
  * Execute the console command.
  *
  * @return boolean
  */
 public function handle()
 {
     if (empty($this->option('user'))) {
         $this->warn('the required user argument was not passed, try --help');
         return false;
     }
     $user = false;
     if (!is_object($user)) {
         $user = User::where('email', $this->option('user'))->first();
     }
     if (!is_object($user)) {
         $user = User::find($this->option('user'));
     }
     if (!is_object($user)) {
         $this->error('Unable to find user with this criteria');
         return false;
     }
     // Apply changes to the user object
     if (!empty($this->option('email'))) {
         $user->email = $this->option('email');
     }
     if (!empty($this->option('password'))) {
         $user->password = $this->option('password');
     }
     if (!empty($this->option('autopassword'))) {
         $generatedPassword = substr(md5(rand()), 0, 8);
         $this->info("Using auto generated password: {$generatedPassword}");
         $user->password = $generatedPassword;
     }
     if (!empty($this->option('firstname'))) {
         $user->first_name = $this->option('firstname');
     }
     if (!empty($this->option('lastname'))) {
         $user->last_name = $this->option('lastname');
     }
     if (!empty($this->option('account'))) {
         $account = Account::where('name', '=', $this->option('account'))->first();
         if (!is_object($account)) {
             $this->error("The account named {$this->option('account')} was not found");
             return false;
         }
         $user->account_id = $account->id;
     }
     if (!empty($this->option('language'))) {
         $user->locale = $this->option('language');
     }
     if (!empty($this->option('disable'))) {
         $user->disabled = true;
     }
     if (!empty($this->option('enable'))) {
         $user->disabled = false;
     }
     // Validate the changes
     $validation = Validator::make($user->toArray(), User::updateRules($user));
     if ($validation->fails()) {
         foreach ($validation->messages()->all() as $message) {
             $this->warn($message);
         }
         $this->error('Failed to create the user due to validation warnings');
         return false;
     }
     // Save the object
     $user->save();
     $this->info("User has been successfully updated");
     return true;
 }
Esempio n. 18
0
 /**
  * Show the form for editing the specified resource.
  *
  * @param Brand $brand
  *
  * @return \Illuminate\Http\Response
  */
 public function edit(Brand $brand)
 {
     $accounts = Account::lists('name', 'id');
     return view('brands.edit')->with('account_selection', $accounts)->with('selected', $brand->creator_id)->with('brand', $brand)->with('auth_user', $this->auth_user);
 }
Esempio n. 19
0
 /**
  * Show the form for editing the specified resource.
  *
  * @param User $user
  *
  * @return \Illuminate\Http\Response
  */
 public function edit(User $user)
 {
     $accounts = Account::lists('name', 'id');
     $roles = Role::lists('name', 'id');
     $locales = [];
     foreach (Config::get('app.locales') as $locale => $locale_data) {
         $locales[$locale] = $locale_data[0];
     }
     return view('users.edit')->with('user', $user)->with('account_selection', $accounts)->with('selected', $user->account_id)->with('locale_selection', $locales)->with('locale_selected', null)->with('disabled_checked', $user->disabled)->with('roles', $roles)->with('selected_roles', $user->roles->lists('id')->toArray())->with('auth_user', $this->auth_user);
 }
Esempio n. 20
0
 /**
  * {@inheritdoc}.
  */
 protected function findWithCondition($filter)
 {
     return Account::where('name', 'like', "%{$filter}%")->get();
 }
Esempio n. 21
0
 /**
  * Static method to check if the account has access to the model instance.
  *
  * @param int                     $model_id
  * @param \AbuseIO\Models\Account $account
  *
  * @return bool
  */
 public static function checkAccountAccess($model_id, Account $account)
 {
     // Early return when we are in the system account
     if ($account->isSystemAccount()) {
         return true;
     }
     $user = self::find($model_id);
     $allowed = $user->account_id == $account->id;
     return $allowed;
 }
Esempio n. 22
0
 /**
  * Remove the specified resource from storage.
  *
  * @param Account $account
  *
  * @return \\Illuminate\Http\RedirectResponse
  */
 public function destroy(Account $account)
 {
     $brand = $account->brand;
     if (!$account->mayDestroy($this->auth_user)) {
         return Redirect::route('admin.accounts.index')->with('message', 'User is not authorized to edit this account.');
     }
     // Do not allow the system admin user account to be deleted.
     if ($account->isSystemAccount()) {
         return Redirect::back()->with('message', 'Not allowed to delete the default admin account.');
     }
     // delete the linked users
     foreach ($account->users as $user) {
         $user->delete();
     }
     // delete the account
     $account->delete();
     // delete the brand
     if ($brand->canDelete()) {
         $brand->delete();
     }
     return Redirect::route('admin.accounts.index')->with('message', 'Account and it\'s related users and brands have been deleted.');
 }
Esempio n. 23
0
 /**
  * Remove the specified resource from storage.
  *
  * @param  Account $account
  * @return \\Illuminate\Http\RedirectResponse
  */
 public function destroy(Account $account)
 {
     // may we edit this brand (is the brand connected to our account)
     if (!$account->mayDestroy($this->auth_user)) {
         return Redirect::route('admin.accounts.index')->with('message', 'User is not authorized to edit this account.');
     }
     // Do not allow the default admin user account to be deleted.
     if ($account->id == 1) {
         return Redirect::back()->with('message', 'Not allowed to delete the default admin account.');
     }
     $account->delete();
     // TODO: delete related users/brands as well
     return Redirect::route('admin.accounts.index')->with('message', 'Account and it\'s related users and brands have been deleted.');
 }
Esempio n. 24
0
 /**
  * Sends out mail notifications for a specific $customerReference
  *
  * @param array $notifications
  * @return boolean  Returns if succeeded or not
  */
 public function send($notifications)
 {
     foreach ($notifications as $customerReference => $notificationTypes) {
         $mails = [];
         $tickets = [];
         $accounts = [];
         foreach ($notificationTypes as $notificationType => $tickets) {
             foreach ($tickets as $ticket) {
                 $token['ip'] = $ticket->ash_token_ip;
                 $token['domain'] = $ticket->ash_topen_domain;
                 $ashUrl = config('main.ash.url') . 'collect/' . $ticket->id . '/';
                 $this->addIodefObject($ticket, $token[$notificationType], $ashUrl);
                 $box = ['ticket_notification_type' => $notificationType, 'ip_contact_ash_link' => $ashUrl . $token['ip'], 'domain_contact_ash_link' => $ashUrl . $token['domain'], 'ticket_number' => $ticket->id, 'ticket_ip' => $ticket->ip, 'ticket_domain' => $ticket->domain, 'ticket_type_name' => trans("types.type.{$ticket->type_id}.name"), 'ticket_type_description' => trans("types.type.{$ticket->type_id}.description"), 'ticket_class_name' => trans("classifications.{$ticket->class_id}.name"), 'ticket_event_count' => $ticket->events->count()];
                 /*
                  * Even that all these tickets relate to the same customer reference, the contacts might be
                  * changed (added addresses, etc) for a specific ticket. To make sure people only get their own
                  * notificiations we aggregate them here before sending.
                  */
                 if ($notificationType == 'ip') {
                     $recipient = $ticket->ip_contact_email;
                     $mails[$recipient][] = $box;
                     $accounts[$recipient] = Account::find($ticket->ip_contact_account_id);
                 }
                 if ($notificationType == 'domain') {
                     $recipient = $ticket->domain_contact_email;
                     $mails[$recipient][] = $box;
                     $accounts[$recipient] = Account::find($ticket->domain_contact_account_id);
                 }
             }
         }
         foreach ($mails as $recipient => $boxes) {
             if (!empty($boxes)) {
                 // create a new message
                 $message = Swift_Message::newInstance();
                 // create the src url for the active brand logo
                 if (!empty($accounts[$recipient])) {
                     $account = $accounts[$recipient];
                 } else {
                     $account = Account::getSystemAccount();
                 }
                 $logo_url = URL::to('/ash/logo/' . $account->brand_id);
                 $brand = $account->brand;
                 $replacements = ['boxes' => $boxes, 'ticket_count' => count($tickets), 'logo_src' => $logo_url];
                 $subject = config("{$this->configBase}.templates.subject");
                 $htmlmail = config("{$this->configBase}.templates.html_mail");
                 $plainmail = config("{$this->configBase}.templates.plain_mail");
                 // render the default templates
                 $htmlmail = view(['template' => $htmlmail], $replacements)->render();
                 $plainmail = view(['template' => $plainmail], $replacements)->render();
                 // if the current brand has custom mail template, use them
                 if ($brand->mail_custom_template) {
                     // defensive programming, doubble check the templates
                     $validator = \Validator::make(['html' => $brand->mail_template_html, 'plain' => $brand->mail_template_plain], ['html' => 'required|bladetemplate', 'plain' => 'required|bladetemplate']);
                     if ($validator->passes()) {
                         try {
                             // only use the templates if they pass the validation
                             $htmloutput = view(['template' => $brand->mail_template_html], $replacements)->render();
                             $plainoutput = view(['template' => $brand->mail_template_plain], $replacements)->render();
                             // no errors occurred while rendering
                             $htmlmail = $htmloutput;
                             $plainmail = $plainoutput;
                         } catch (\ErrorException $e) {
                             Log::warning("Incorrect template, falling back to default: " . $e->getMessage());
                         }
                     }
                 }
                 $iodef = new Iodef\Writer();
                 $iodef->formatOutput = true;
                 $iodef->write([['name' => 'IODEF-Document', 'attributes' => $this->iodefDocument->getAttributes(), 'value' => $this->iodefDocument]]);
                 $XmlAttachmentData = $iodef->outputMemory();
                 if (!empty(Config::get('mail.smime.enabled')) && Config::get('mail.smime.enabled') === true && !empty(Config::get('mail.smime.certificate')) && !empty(Config::get('mail.smime.key')) && is_file(Config::get('mail.smime.certificate')) && is_file(Config::get('mail.smime.key'))) {
                     $smimeSigner = Swift_Signers_SMimeSigner::newInstance();
                     $smimeSigner->setSignCertificate(Config::get('mail.smime.certificate'), Config::get('mail.smime.key'));
                     $message->attachSigner($smimeSigner);
                 }
                 $message->setFrom([Config::get('main.notifications.from_address') => Config::get('main.notifications.from_name')]);
                 if (!empty(Config::get('mail.override_address'))) {
                     $message->setTo([Config::get('mail.override_address')]);
                 } else {
                     $message->setTo([$recipient]);
                 }
                 if (!empty(Config::get('main.notifications.bcc_enabled'))) {
                     $message->setBcc([Config::get('main.notifications.bcc_address')]);
                 }
                 $message->setPriority(1);
                 $message->setSubject($subject);
                 $message->setBody($htmlmail, 'text/html');
                 $message->addPart($plainmail, 'text/plain');
                 $message->attach(Swift_Attachment::newInstance($XmlAttachmentData, 'iodef.xml', 'text/xml'));
                 $transport = Swift_SmtpTransport::newInstance();
                 $transport->setHost(config('mail.host'));
                 $transport->setPort(config('mail.port'));
                 $transport->setUsername(config('mail.username'));
                 $transport->setPassword(config('mail.password'));
                 $transport->setEncryption(config('mail.encryption'));
                 $mailer = Swift_Mailer::newInstance($transport);
                 if (!$mailer->send($message)) {
                     return $this->failed("Error while sending message to {$recipient}");
                 }
             }
         }
     }
     return $this->success();
 }
Esempio n. 25
0
 public function testSetSystemAccount()
 {
     $account = factory(Account::class)->create();
     $account->systemaccount = true;
     $this->assertTrue((bool) Account::find($account->id)->systemaccount);
 }
Esempio n. 26
0
 /**
  * {@inheritdoc}.
  */
 protected function getValidator($model)
 {
     return Validator::make($model->toArray(), Account::updateRules($model));
 }
Esempio n. 27
0
 /**
  * {@inherit docs}
  */
 protected function getCollectionWithArguments()
 {
     return Account::where("name", "like", "%" . $this->argument("account") . "%")->orWhere("id", $this->argument("account"));
 }
Esempio n. 28
0
 /**
  * Execute the console command.
  *
  * @return bool
  */
 public function handle()
 {
     $account = Account::getSystemAccount();
     if (empty($this->option('start')) && empty($this->option('prepare')) && empty($this->option('clean'))) {
         $this->error('You need to either prepare or start the migration. try --help');
         die;
     }
     if (!empty($this->option('clean'))) {
         $this->warn('This will remove all data from the database except prepared data. Do not run ' . 'this in producion and only when a migration has gone bad and you want to restart it');
         if ($this->confirm('Do you wish to continue? [y|N]')) {
             $this->info('starting clean up');
             DB::statement('SET foreign_key_checks=0');
             Note::truncate();
             Event::truncate();
             Ticket::truncate();
             Netblock::truncate();
             Contact::truncate();
             DB::statement('SET foreign_key_checks=1');
         } else {
             $this->info('cancelled clean up');
         }
     }
     /*
      * Combine the use of start/stop and threading here for usage with prepare and start of migration
      */
     $startFrom = $this->option('startfrom');
     $endWith = $this->option('endwith');
     if (!empty($this->option('prepare')) || !empty($this->option('start'))) {
         if (!empty($this->option('threaded'))) {
             if (empty($this->option('threadid')) || empty($this->option('threadsize'))) {
                 $this->error('threadid and threadsize are required to calculate this threads start/stop ID');
                 die;
             }
             $this->info("*** using threaded mode, instance ID {$this->option('threadid')}");
             $startFrom = $this->option('threadid') * $this->option('threadsize') - $this->option('threadsize') + 1;
             $endWith = $startFrom + $this->option('threadsize') - 1;
             $this->info("*** starting with ticket {$startFrom} " . "and ending with ticket {$endWith} ");
         }
     }
     if (!empty($this->option('prepare'))) {
         $this->info('building required evidence cache files');
         $filesystem = new Filesystem();
         $path = storage_path() . '/migration/';
         umask(07);
         if (!$filesystem->isDirectory($path)) {
             // If a datefolder does not exist, then create it or die trying
             if (!$filesystem->makeDirectory($path, 0770)) {
                 $this->error('Unable to create directory: ' . $path);
                 $this->exception();
             }
             if (!is_dir($path)) {
                 $this->error('Path vanished after write: ' . $path);
                 $this->exception();
             }
             chgrp($path, config('app.group'));
         }
         DB::setDefaultConnection('abuseio3');
         $evidenceRows = DB::table('Evidence')->where('id', '>=', $startFrom)->where('id', '<=', $endWith);
         $migrateCount = $evidenceRows->count();
         $evidences = $evidenceRows->get();
         $this->output->progressStart($migrateCount);
         // If there are now rows to do, advance to complete
         if ($migrateCount === 0) {
             $this->output->progressAdvance();
             echo ' nothing to do, because there are no records in this selection';
         }
         foreach ($evidences as $evidence) {
             $this->output->progressAdvance();
             // Before we go into an error, lets see if this evidence was even linked to any ticket at all
             // If not we can ignore the error and just smile and wave
             $evidenceLinks = DB::table('EvidenceLinks')->where('EvidenceID', '=', $evidence->ID)->get();
             if (count($evidenceLinks) === 0) {
                 echo " skipping unlinked evidence ID {$evidence->ID}         ";
                 continue;
             }
             $filename = $path . "evidence_id_{$evidence->ID}.data";
             if (is_file($filename)) {
                 // Check weither the evidence was actually created in the database
                 DB::setDefaultConnection('mysql');
                 $evidenceCheck = Evidence::where('id', $evidence->ID);
                 if ($evidenceCheck->count() !== 1) {
                     $this->error("file {$filename} exists however not in database. try deleting it to retry");
                     die;
                 }
                 DB::setDefaultConnection('abuseio3');
                 continue;
             } else {
                 echo " working on evidence ID {$evidence->ID}                    ";
             }
             $rawEmail = $evidence->Data;
             $parsedMail = new MimeParser();
             $parsedMail->setText($rawEmail);
             // Start with detecting valid ARF e-mail
             $attachments = $parsedMail->getAttachments();
             $arfMail = [];
             foreach ($attachments as $attachment) {
                 if ($attachment->contentType == 'message/feedback-report') {
                     $arfMail['report'] = $attachment->getContent();
                 }
                 if ($attachment->contentType == 'message/rfc822') {
                     $arfMail['evidence'] = utf8_encode($attachment->getContent());
                 }
                 if ($attachment->contentType == 'text/plain') {
                     $arfMail['message'] = $attachment->getContent();
                 }
             }
             if (empty($arfMail['message']) && isset($arfMail['report']) && isset($arfMail['evidence'])) {
                 $arfMail['message'] = $parsedMail->getMessageBody();
             }
             // If we do not have a complete e-mail, then we empty the perhaps partially filled arfMail
             // which is useless, hence reset to false
             if (!isset($arfMail['report']) || !isset($arfMail['evidence']) || !isset($arfMail['message'])) {
                 $arfMail = false;
             }
             // Asking ParserFactory for an object based on mappings, or die trying
             $parser = ParserFactory::create($parsedMail, $arfMail);
             if ($parser !== false) {
                 $parserResult = $parser->parse();
             } else {
                 $this->error('No parser available to handle message ' . $evidence->ID . ' from : ' . $evidence->Sender . ' with subject: ' . $evidence->Subject);
                 continue;
             }
             if ($parserResult !== false && $parserResult['errorStatus'] === true) {
                 $this->error('Parser has ended with fatal errors ! : ' . $parserResult['errorMessage']);
                 $this->exception();
             }
             if ($parserResult['warningCount'] !== 0) {
                 $this->error('Configuration has warnings set as critical and ' . $parserResult['warningCount'] . ' warnings were detected.');
                 //var_dump($rawEmail);
                 $this->exception();
             }
             // Write the evidence into the archive
             $evidenceWrite = new EvidenceSave();
             $evidenceData = $rawEmail;
             $evidenceFile = $evidenceWrite->save($evidenceData);
             // Save the file reference into the database
             $evidenceSave = new Evidence();
             $evidenceSave->id = $evidence->ID;
             $evidenceSave->filename = $evidenceFile;
             $evidenceSave->sender = $parsedMail->getHeader('from');
             $evidenceSave->subject = $parsedMail->getHeader('subject');
             $incidentsProcess = new IncidentsProcess($parserResult['data'], $evidenceSave);
             /*
              * Because google finds it 'obvious' not to include the IP address relating to abuse
              * the IP field might now be empty with reparsing if the domain/label does not resolve
              * anymore. For these cases we need to lookup the ticket that was linked to the evidence
              * match the domain and retrieve its IP.
              */
             foreach ($parserResult['data'] as $index => $incident) {
                 if ($incident->source == 'Google Safe Browsing' && $incident->domain != false && $incident->ip == '127.0.0.1') {
                     // Get the list of tickets related to this evidence
                     $evidenceLinks = DB::table('EvidenceLinks')->where('EvidenceID', '=', $evidence->ID)->get();
                     // For each ticket check if the domain name is matching the evidence we need to update
                     foreach ($evidenceLinks as $evidenceLink) {
                         $ticket = DB::table('Reports')->where('ID', '=', $evidenceLink->ReportID)->first();
                         if ($ticket->Domain == $incident->domain) {
                             $incident->ip = $ticket->IP;
                         }
                     }
                     // Update the original object by overwriting it
                     $parserResult['data'][$index] = $incident;
                 }
             }
             // Only continue if not empty, empty set is acceptable (exit OK)
             if (!$incidentsProcess->notEmpty()) {
                 $this->warn("No evidence build, no results from parser for {$evidence->ID}");
                 continue;
             }
             // Validate the data set
             if (!$incidentsProcess->validate()) {
                 $this->error('Validation failed of object.');
                 $this->exception();
             }
             $incidents = [];
             foreach ($parserResult['data'] as $incident) {
                 $incidents[$incident->ip][] = $incident;
             }
             DB::setDefaultConnection('mysql');
             $evidenceSave->save();
             DB::setDefaultConnection('abuseio3');
             $output = ['evidenceId' => $evidence->ID, 'evidenceData' => $evidence->Data, 'incidents' => $incidents, 'newId' => $evidenceSave->id];
             if ($filesystem->put($filename, json_encode($output)) === false) {
                 $this->error('Unable to write file: ' . $filename);
                 return false;
             }
         }
         $this->output->progressFinish();
     }
     if (!empty($this->option('start'))) {
         if (empty($this->option('skipcontacts'))) {
             $this->info('starting migration - phase 1 - contact data');
             DB::setDefaultConnection('abuseio3');
             $customers = DB::table('Customers')->get();
             DB::setDefaultConnection('mysql');
             $this->output->progressStart(count($customers));
             foreach ($customers as $customer) {
                 $newContact = new Contact();
                 $newContact->reference = $customer->Code;
                 $newContact->name = $customer->Name;
                 $newContact->email = $customer->Contact;
                 $newContact->auto_notify = $customer->AutoNotify;
                 $newContact->enabled = 1;
                 $newContact->account_id = $account->id;
                 $newContact->created_at = Carbon::parse($customer->LastModified);
                 $newContact->updated_at = Carbon::parse($customer->LastModified);
                 $validation = Validator::make($newContact->toArray(), Contact::createRules());
                 if ($validation->fails()) {
                     $message = implode(' ', $validation->messages()->all());
                     $this->error('fatal error while creating contacts :' . $message);
                     $this->exception();
                 } else {
                     $newContact->save();
                 }
                 $this->output->progressAdvance();
                 echo " Working on contact {$customer->Code}      ";
             }
             $this->output->progressFinish();
         } else {
             $this->info('skipping migration - phase 1 - contact data');
         }
         if (empty($this->option('skipnetblocks'))) {
             $this->info('starting migration - phase 2 - netblock data');
             DB::setDefaultConnection('abuseio3');
             $netblocks = DB::table('Netblocks')->get();
             DB::setDefaultConnection('mysql');
             $this->output->progressStart(count($netblocks));
             foreach ($netblocks as $netblock) {
                 $contact = FindContact::byId($netblock->CustomerCode);
                 if ($contact->reference != $netblock->CustomerCode) {
                     $this->error('Contact lookup failed, mismatched results');
                     $this->{$this}->exception();
                 }
                 $newNetblock = new Netblock();
                 $newNetblock->first_ip = long2ip($netblock->begin_in);
                 $newNetblock->last_ip = long2ip($netblock->end_in);
                 $newNetblock->description = 'Imported from previous AbuseIO version which did not include a description';
                 $newNetblock->contact_id = $contact->id;
                 $newNetblock->enabled = 1;
                 $newNetblock->created_at = Carbon::parse($netblock->LastModified);
                 $newNetblock->updated_at = Carbon::parse($netblock->LastModified);
                 $validation = Validator::make($newNetblock->toArray(), Netblock::createRules($newNetblock));
                 if ($validation->fails()) {
                     $message = implode(' ', $validation->messages()->all());
                     $this->error('fatal error while creating contacts :' . $message);
                     $this->exception();
                 } else {
                     $newNetblock->save();
                 }
                 $this->output->progressAdvance();
                 echo ' Working on netblock ' . long2ip($netblock->begin_in) . '       ';
             }
             $this->output->progressFinish();
         } else {
             $this->info('skipping migration - phase 2 - netblock data');
         }
         if (empty($this->option('skiptickets'))) {
             $this->info('starting migration - phase 3 - ticket and evidence data');
             DB::setDefaultConnection('abuseio3');
             $ticketRows = DB::table('Reports')->where('id', '>=', $startFrom)->where('id', '<=', $endWith);
             $migrateCount = $ticketRows->count();
             $tickets = $ticketRows->get();
             DB::setDefaultConnection('mysql');
             $this->output->progressStart($migrateCount);
             // If there are now rows to do, advance to complete
             if ($migrateCount === 0) {
                 $this->output->progressAdvance();
                 echo ' nothing to do, because there are no records in this selection';
             }
             foreach ($tickets as $ticket) {
                 // Get the list of evidence ID's related to this ticket
                 DB::setDefaultConnection('abuseio3');
                 $evidenceLinks = DB::table('EvidenceLinks')->where('ReportID', '=', $ticket->ID)->get();
                 DB::setDefaultConnection('mysql');
                 // DO NOT REMOVE! Legacy versions (1.0 / 2.0) have imports without evidence.
                 // These dont have any linked evidence and will require a manual building of evidence
                 // for now we ignore them. This will not affect any 3.x installations
                 if ($ticket->CustomerName == 'Imported from AbuseReporter' || !empty(json_decode($ticket->Information)->importnote)) {
                     // Manually build the evidence
                     $this->output->progressAdvance();
                     echo " Working on events from ticket {$ticket->ID}";
                     $this->replayTicket($ticket, $account);
                     continue;
                 }
                 if (count($evidenceLinks) != (int) $ticket->ReportCount) {
                     // Count does not match, known 3.0 limitation related to not always saving all the data
                     // so we will do a little magic to fix that
                     $this->output->progressAdvance();
                     echo " Working on events from ticket {$ticket->ID}";
                     $this->replayTicket($ticket, $account);
                     continue;
                 } else {
                     // Just work as normal
                     $this->output->progressAdvance();
                     echo " Working on events from ticket {$ticket->ID}";
                     $newTicket = $this->createTicket($ticket, $account);
                     // Create all the events
                     foreach ($evidenceLinks as $evidenceLink) {
                         $path = storage_path() . '/migration/';
                         $filename = $path . "evidence_id_{$evidenceLink->EvidenceID}.data";
                         if (!is_file($filename)) {
                             $this->error('missing cache file ');
                             $this->exception();
                         }
                         $evidence = json_decode(file_get_contents($filename));
                         $evidenceID = (int) $evidence->evidenceId;
                         $incidents = $evidence->incidents;
                         // Yes we only grab nr 0 from the array, because that is what the old aggregator did
                         // which basicly ignored a few incidents because they werent considered unique (which
                         // they were with the domain name)
                         $ip = $newTicket->ip;
                         if (property_exists($incidents, $ip)) {
                             $incidentTmp = $incidents->{$ip};
                             $incident = $incidentTmp[0];
                             $newEvent = new Event();
                             $newEvent->evidence_id = $evidenceID;
                             $newEvent->information = $incident->information;
                             $newEvent->source = $incident->source;
                             $newEvent->ticket_id = $newTicket->id;
                             $newEvent->timestamp = $incident->timestamp;
                         } else {
                             // Parser did not find any related evidence so replay it from the ticket only reason
                             // Why it happends here if DNS has changed and google report cannot be matched
                             $newEvent = new Event();
                             $newEvent->evidence_id = $evidenceID;
                             $newEvent->information = $ticket->Information;
                             $newEvent->source = $ticket->Source;
                             $newEvent->ticket_id = $newTicket->id;
                             $newEvent->timestamp = $ticket->FirstSeen;
                         }
                         // Validate the model before saving
                         $validator = Validator::make(json_decode(json_encode($newEvent), true), Event::createRules());
                         if ($validator->fails()) {
                             $this->error('DevError: Internal validation failed when saving the Event object ' . implode(' ', $validator->messages()->all()));
                             $this->exception();
                         }
                         $newEvent->save();
                     }
                 }
             }
             $this->output->progressFinish();
         } else {
             $this->info('skipping migration - phase 3 - Tickets');
         }
         if (empty($this->option('skipnotes'))) {
             $this->info('starting migration - phase 4 - Notes');
             DB::setDefaultConnection('abuseio3');
             $notes = DB::table('Notes')->get();
             DB::setDefaultConnection('mysql');
             $this->output->progressStart(count($notes));
             foreach ($notes as $note) {
                 $newNote = new Note();
                 $newNote->id = $note->ID;
                 $newNote->ticket_id = $note->ReportID;
                 $newNote->submitter = $note->Submittor;
                 $newNote->text = $note->Text;
                 $newNote->hidden = true;
                 $newNote->viewed = true;
                 $newNote->created_at = Carbon::parse($note->LastModified);
                 $newNote->updated_at = Carbon::parse($note->LastModified);
                 $validation = Validator::make($newNote->toArray(), Note::createRules());
                 if ($validation->fails()) {
                     $message = implode(' ', $validation->messages()->all());
                     $this->error('fatal error while creating contacts :' . $message);
                     $this->exception();
                 } else {
                     $newNote->save();
                 }
                 $this->output->progressAdvance();
                 echo " Working on note {$note->ID}       ";
             }
             $this->output->progressFinish();
         } else {
             $this->info('skipping migration - phase 4 - Notes');
         }
     }
     return true;
 }
Esempio n. 29
0
 /**
  * Static method to check if the account has access to the model instance.
  *
  * @param int                     $model_id
  * @param \AbuseIO\Models\Account $account
  *
  * @return bool
  */
 public static function checkAccountAccess($model_id, Account $account)
 {
     // Early return when we are in the system account
     if ($account->isSystemAccount()) {
         return true;
     }
     $domain = self::find($model_id);
     return $domain->contact->account->id == $account->id;
 }
Esempio n. 30
0
 /**
  * {@inheritdoc}.
  */
 protected function getObjectByArguments()
 {
     return Account::find($this->argument('id'));
 }