/** * 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); }
/** * 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; }
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(); }
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); }
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(); }
/** * @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; }
/** * @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; }
/** * 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; }
/** * {@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; }
/** * 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 []; }
/** * 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; }
/** * 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.'); }
/** * 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); }
/** * 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; }
/** * 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; }
/** * {@inherit docs}. */ protected function getCollectionWithArguments() { return Account::where('name', 'like', '%' . $this->argument('account') . '%')->orWhere('id', $this->argument('account')); }
/** * 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; }
/** * 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); }
/** * 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); }
/** * {@inheritdoc}. */ protected function findWithCondition($filter) { return Account::where('name', 'like', "%{$filter}%")->get(); }
/** * 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; }
/** * 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.'); }
/** * 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.'); }
/** * 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(); }
public function testSetSystemAccount() { $account = factory(Account::class)->create(); $account->systemaccount = true; $this->assertTrue((bool) Account::find($account->id)->systemaccount); }
/** * {@inheritdoc}. */ protected function getValidator($model) { return Validator::make($model->toArray(), Account::updateRules($model)); }
/** * {@inherit docs} */ protected function getCollectionWithArguments() { return Account::where("name", "like", "%" . $this->argument("account") . "%")->orWhere("id", $this->argument("account")); }
/** * 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; }
/** * 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; }
/** * {@inheritdoc}. */ protected function getObjectByArguments() { return Account::find($this->argument('id')); }