tag:blogger.com,1999:blog-33142611116507445102024-03-07T17:12:54.625+08:00Linux, OpenOffice.org and Open Source SoftwareLooking at alternative computer software solutions for a variety of reasons. This includes price, computer security, virus prevention and reliability.
Here are my notes and great that if it helps you, otherwise please understand what you are doing and not follow blindly.
All works expressed are my own and does not necessarily express the products or organisations mentioned here.Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.comBlogger442125tag:blogger.com,1999:blog-3314261111650744510.post-50955550649305918222024-01-26T20:00:00.017+08:002024-01-29T10:23:52.882+08:00Handling date and time with carbon<p>In PHP and Laravel, date and time can be managed using Carbon. Default PHP uses the Date object, which does not have as many flexibility as Carbon object. To start using Carbon on Laravel, add at top, along with other "use" statements. </p><code style="color: black; overflow-wrap: normal; word-wrap: normal;"><p>use Carbon\Carbon</p></code><p>Here are examples of its usage. Declare current date and time</p><p>$currentDateTime = Carbon::now();</p><p>The current value can be printed with </p><p>print_r($currentDateTime);</p><p><br /></p><p>Format to user specific output.</p>
<code style="color: black; overflow-wrap: normal; word-wrap: normal;"><p>$now = Carbon::now()->format('d-m-Y'); // 1-1-2024</p><p>$now->toDateString(); // 2024-01-01</p><p>$now->toFormattedDateString(); // Jan 1, 2024</p><p>$now->toTimeString(); // 00:00:00</p><p>$now->toDateTimeString(); // 2024-01-01 00:00:00</p><p>$now->toDayDateTimeString(); // Mon, Jan 1, 2024 12:00 AM</p><p>$now->toCookieString(); // Monday, 01-Jan-2024 00:00:00 UTC</p><p>$now->toIso8601String(); // 2024-01-01T00:00:00+00:00</p><p><br /></p></code><p>Other ways of creating a Carbon object</p><p><span style="font-family: courier;">Carbon::parse('2023-03-10'); // Carbon instance for 2023-01-01 00:00:00</span></p><p><span style="font-family: courier;">Carbon::parse('Monday of this week'); // Monday of this week</span></p><p><span style="font-family: courier;">Carbon::parse('first day of January 2024'); // first day of January 2024</span></p><p><span style="font-family: courier;">Carbon::parse('first day of this month'); // first day of this month</span></p><p><span style="font-family: courier;">Carbon::parse('first day of next month'); // first day of next month</span></p><p><span style="font-family: courier;">Carbon::parse('first day of last month'); // first day of last month</span></p><p><span style="font-family: courier;">Carbon::parse('last day of last month'); // last day of last month</span></p><p><br /></p><p>Retrieve values of a carbon in various formats;</p><p><span style="font-family: courier;">$now->year; </span></p><p><span style="font-family: courier;">$now->month; </span></p><p><span style="font-family: courier;">$now->dayOfWeek; </span></p><p><span style="font-family: courier;">$now->englishDayOfWeek; </span></p><p><span style="font-family: courier;">$now->englishMonth; </span></p><p><span style="font-family: courier;">$now->tzName; </span></p><p><span style="font-family: courier;">$now->dst;</span></p><p><br /></p><p>Subtract one hour</p><p><span style="font-family: courier;">Carbon::now()->subHour();</span></p><p>Subtract more than 1 hour</p><p><span style="font-family: courier;">Carbon::now()->subHours(2);</span></p><p><br /></p><p>Add one hour</p><p><span style="font-family: courier;">Carbon::now()->addHour();</span></p><p>Add more than 1 hour</p><p><span style="font-family: courier;">Carbon::now()->addHours(2);</span></p><p><br /></p><p>Add one day</p><p><span style="font-family: courier;">Carbon::now()->addDay();</span></p><p>Add more than 1 day</p><p><span style="font-family: courier;">Carbon::now()->addDays(2);</span></p><p><br /></p><p>This can also be applied to subWeeks(), addWeeks().</p><p><br /></p><p>Set to a specific date by altering day or month or year</p><p><span style="font-family: courier;">$currentDateTime = $currentDateTime->setMonth(2);</span></p><p><span style="font-family: courier;">$currentDateTime = $currentDateTime->setDay(18);</span></p><p><span style="font-family: courier;">$currentDateTime = $currentDateTime->setYear(2025);</span></p><p>Example that applies a specific day and month.</p><p><span style="font-family: courier;">$</span><span style="font-family: courier;">currentDateTime </span><span style="font-family: courier;">= $workDayStart-><b>setDay</b>($calcCreatedDate-><b>format('d')</b>)-><b>setMonth(</b>$calcCreatedDate-><b>format('m')</b>)-><b>setYear</b>($calcCreatedDate-><b>format('Y')</b>);</span></p><p><br /></p><p>Retrieve the difference between 2 Carbon dates $start and $now.</p><p><span style="font-family: courier;">$start->diff($now); \\ returns DateInterval</span></p><p><span style="font-family: courier;">$start->diffInMinutes($now); \\ returns difference in minutes</span></p><p><span style="font-family: courier;">$start->diffInMinutes($now); \\ returns difference in</span></p><p><span style="font-family: courier;">$start->diffForHumans($now);</span></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-91624938492431144082023-12-01T18:55:00.005+08:002023-12-01T18:56:55.189+08:00Manage services on Centos Linux<p>On Centos Linux (in this case version 8), the command systemctl allows administration of services on Linux. The version of systemctl in use is displayed with command</p><p>systemctl --version</p><p>systemd 239 (239-58.el8)</p><p>+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy</p><p><br /></p><h3 style="text-align: left;">Check status of services</h3><p>systemctl status httpd</p><p>systemctl status containerd</p><p>systemctl status kubelet</p><p>systemctl list-unit-files</p><p><br /></p><h3 style="text-align: left;">Background services is list with</h3><p>systemctl list-jobs</p><p><br /></p><h3 style="text-align: left;">View service information</h3><p>systemctl show httpd</p><p>systemctl show containerd</p><p><br /></p><h3 style="text-align: left;">Start and stop a service</h3><p>systemctl start httpd</p><p>systemctl stop httpd</p><p><br /></p><p>On some services, there is the command to restart or reload. Reload, reads the updated configuration for a service without stopping the service.</p><p>systemctl start httpd</p><p>systemctl reload httpd</p><p><br /></p><h2 style="text-align: left;">Boot target</h2><div>On linux, the run levels describe what the server should do after a startup. Where runlevel and the numeric equivalent of target. Here is a list of runlevel and in brackets are the systemctl commands for it.</div><div><br /></div><div>Runlevel 0 - poweroff.target (systemctl isolate poweroff.target)</div><div>Runlevel 1 - rescue.target (systemctl isolate rescue.target)</div><div>Runlevel 2 - text based multi-user.target without network (systemctl isolate runlevel2.target)</div><div>Runlevel 3 - text based multi-user.target with network (systemctl isolate runlevel3.target)</div><div>Runlevel 5 - graphical graphical.target (systemctl isolate graphical.target)</div><div>Runlevel 6 - reboot.target (systemctl isolate reboot.target)</div><div><br /></div><div>Default boot target is set by /etc/systemd/system/default.target and can be easily viewed with the command 'ls'.</div><div><br /></div><div>Or the command systemctl get-default</div><div><div>multi-user.target</div><div><br /></div></div><div>View available targets</div><div>systemctl list-units --type target --all</div><div><br /></div><div>To change a default boot target,</div><div>systemctl set-default multi-user.target</div><div><br /></div><h2 style="text-align: left;">Troubleshooting</h2><p>List dependencies of the service</p><p>systemctl list-dependencies httpd</p><p><br /></p><p>Unit files are list as</p><p>systemctl list-unit files</p><p><br /></p><p>When a service is mask, it cannot be started until it is unmask. This can be done with</p><p>systemctl unmask httpd</p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-62889343669221894812023-10-18T21:30:00.007+08:002023-10-18T21:30:00.148+08:00Configure L5 Swagger and documention for GET and POST<p>Here, I will describe usage of Swagger, list the L5 Swagger basic configurations, provide templates to document POST and GET API (Application Programming Interface).</p><p>What does L5 Swagger provide?</p><p>For PHP developers, here in particular those using Laravel framework, L5 Swagger provide the means to document your API and have it presented in the form of a web page for quick browsing of available APIs and testing its results.</p><p>Currently here are good to know facts</p><p></p><ol style="text-align: left;"><li>Its is developed as a wrapper on swagger-php and swagger-api specifically for Laravel framework.</li><li>It supports OpenAPI (formerly known as Swagger), a specification for documentation of RESTful API irrespective of technology, like PHP, Java or .Net.</li><li>L5-Swagger currently supports OpenAPI version 3.0 and 3.1. Its project page is https://github.com/DarkaOnLine/L5-Swagger</li><li>It supports at least PHP version 7.2. PHP 8.1 introduces the use of attributes.</li><li>An online swagger editor is available at <a href="https://editor.swagger.io/">swagger.io</a></li></ol><div>My example hinges on PHP 7.4 with darkaonline/l5-swagger version 8.5.1. Will just dump example of code and configurations here. Details will be explained at another time. Good luck.</div><h4 style="text-align: left;">Quick notes to setup of Swagger in a ready Laravel version 7 or 10 project;</h4><div>composer require "darkaonline/l5-swagger"</div><div><div>php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"</div><div>php artisan l5-swagger:generate</div></div><div><br /></div><div>Customisation can be done by editing config/swagger.php, which can be continued in future articles.</div><p></p><h4 style="text-align: left;">Security</h4><div>Security options are;</div><div><ul style="text-align: left;"><li>None - no security is set to access API</li><li>Basic Auth - Username and password is set for each request</li><li>API Key - A key is set for each request</li><li>OATH - An authorisation scheme for each request</li></ul><h3 style="text-align: left;">Example 1 - API to login</h3><h4 style="text-align: left;">Request </h4><div><b>Headers:</b></div><div><div>App-Key: SOmeVeryLongKey</div><div><br /></div><div><b>Body form-data:</b></div><div>username: example@some.email.example</div><div>password: password</div></div><div><br /></div><h4 style="text-align: left;">API returns with HTTP code 200</h4><div><div>{</div><div> "user_id": 4142,</div><div> "token": "173892|HxOQJBfDgDgDgaqgCpSS1rh7UY7HWdurtanHhq7"</div><div>}</div></div><div><br /></div><div><h4>API returns with HTTP code 400</h4><div><div>{</div><div> "message": "These credentials do not match our records."</div><div>}</div></div></div><div><br /></div><div><h3>Example 2 - API to retrieve user profile</h3><h4>Request </h4><div><b>Headers:</b></div><div><div>App-Key: SOmeVeryLongKey</div></div><h4>API returns with HTTP code 200</h4></div><div><div>{</div><div> "status": 0,</div><div> "message": null,</div><div> "data": [</div><div> {</div><div> "id": 385,</div><div> "name": "Bintulu",</div><div> "address1": "no.3 River side, Sarawak",</div><div> "address2": null,</div><div> "introduction": "Software architect and Postgresql architect",</div><div> "phone": "1234512345",</div><div> "email": "bintulu@some.email.example",</div><div> "notes": "Call by phone"</div><div> }</div><div> ],</div><div> "timestamp": "2023-03-17T10:00:09"</div><div>}</div></div><div><br /></div><h3 style="text-align: left;">Swagger documentation</h3><h4 style="text-align: left;">Swagger group for Login</h4><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja2ixIDnNZv5SKjBQ3PEO1s0OjYLFBAcBBLIRprlf8ynQvxwJf7-0pT0xFQnGixoehb5ifemmADBW8TnvvrK2UeXBIUYWGUmnrrbDEkCud_PQ9m8U-TNKUpeLGCFNWh7jTTVbn6y-UfczZTVohj0xBnhwNx7NKy5DzciC3Nn96frNU1fcjiuQNBeYo1oeb/s910/swagger-2023-10-18-185220.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Swagger group for login" border="0" data-original-height="176" data-original-width="910" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja2ixIDnNZv5SKjBQ3PEO1s0OjYLFBAcBBLIRprlf8ynQvxwJf7-0pT0xFQnGixoehb5ifemmADBW8TnvvrK2UeXBIUYWGUmnrrbDEkCud_PQ9m8U-TNKUpeLGCFNWh7jTTVbn6y-UfczZTVohj0xBnhwNx7NKy5DzciC3Nn96frNU1fcjiuQNBeYo1oeb/w640-h124/swagger-2023-10-18-185220.png" width="640" /></a></div><br /><div><br /></div><h4 style="text-align: left;">Swagger for login</h4><div>Added example to submit with multi/form-data (which is not necessary for login)</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR2cRNymgDkf7g3DXGr1P7aPTXdgS7LBi1IRiQmrsEYASdjtyxLV2e70iaR1Ef182773Oo9XDl0fMPSYqfqLCRzk7j6Ca2KmY9K61g3j9rZXYCnvWZ4UbuktBwDZEEJPqgMeP1JLmk_GTC85PMdKUai4cNJvKoticfUHL9rW-AMvyua1Bz3etkBzSnJcbc/s902/swagger-2023-10-18-185210.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="555" data-original-width="902" height="394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR2cRNymgDkf7g3DXGr1P7aPTXdgS7LBi1IRiQmrsEYASdjtyxLV2e70iaR1Ef182773Oo9XDl0fMPSYqfqLCRzk7j6Ca2KmY9K61g3j9rZXYCnvWZ4UbuktBwDZEEJPqgMeP1JLmk_GTC85PMdKUai4cNJvKoticfUHL9rW-AMvyua1Bz3etkBzSnJcbc/w640-h394/swagger-2023-10-18-185210.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMdQe0IE9Lg7mMnapcH-fKEUpMYR8guQ4RLlfOpIZwEs7KWI0eVJoF_5yO0-wxovzk950hKiOzIiuhjWPnr8Sa9X315axbhVLcbjpr1x0youTtX2tTADMPyYmTk0hdxiGuFdx96oTdBkwPZuAoz1lsnftY498rT2JnWZHdKMFFtsDYszRCBs503b_0V-CT/s882/swagger-2023-10-18-185217.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="562" data-original-width="882" height="408" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMdQe0IE9Lg7mMnapcH-fKEUpMYR8guQ4RLlfOpIZwEs7KWI0eVJoF_5yO0-wxovzk950hKiOzIiuhjWPnr8Sa9X315axbhVLcbjpr1x0youTtX2tTADMPyYmTk0hdxiGuFdx96oTdBkwPZuAoz1lsnftY498rT2JnWZHdKMFFtsDYszRCBs503b_0V-CT/w640-h408/swagger-2023-10-18-185217.png" width="640" /></a></div><br /><h4 style="text-align: left;">Swagger for user profile</h4><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjEJ0RX0k6G9AM-cijgyz7y3jwHQJD4C3yIlhUahCGC0w_Pojg8MhjBwNoSARAXkOfLUnupdm5xmrtxEUkTkfSdtiu2cHzC5wTcoyjY2jiNWw3RCUh45pl53VFBVVa3V3kkCo-ugihvXdrNmt_kGwp54kgIQaEmWITv6aExV5Kh3JJ75qa_PyYUyspnfzb/s896/swagger-2023-10-18-185225.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Swagger user profile" border="0" data-original-height="450" data-original-width="896" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjEJ0RX0k6G9AM-cijgyz7y3jwHQJD4C3yIlhUahCGC0w_Pojg8MhjBwNoSARAXkOfLUnupdm5xmrtxEUkTkfSdtiu2cHzC5wTcoyjY2jiNWw3RCUh45pl53VFBVVa3V3kkCo-ugihvXdrNmt_kGwp54kgIQaEmWITv6aExV5Kh3JJ75qa_PyYUyspnfzb/w640-h322/swagger-2023-10-18-185225.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdQLzqBh3My54MuwY5cCD2sw69Gk9R55JFCMH_7GGTJNr_pVH_IJBPTf72nl9Lqv52JBVElFei2pbJEtCLhhsVKkaMhRRguafwCFYnIvdjGky5s5M1hXFPt9E_PyoDCcg-xv7UJvbG-vBSrwW6lIXKbjsKfYdXeGYsiD55eKDs_ZG-sud8coAC9_vrLAf0/s897/swagger-2023-10-18-185229.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Swagger user profile" border="0" data-original-height="707" data-original-width="897" height="504" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdQLzqBh3My54MuwY5cCD2sw69Gk9R55JFCMH_7GGTJNr_pVH_IJBPTf72nl9Lqv52JBVElFei2pbJEtCLhhsVKkaMhRRguafwCFYnIvdjGky5s5M1hXFPt9E_PyoDCcg-xv7UJvbG-vBSrwW6lIXKbjsKfYdXeGYsiD55eKDs_ZG-sud8coAC9_vrLAf0/w640-h504/swagger-2023-10-18-185229.png" width="640" /></a></div><br /><div><br /></div><h3 style="text-align: left;">The Code</h3><h4 style="text-align: left;">Our example api.php and UserController.php</h4></div><p style="text-align: left;">routes/api.php</p><div><span style="font-family: courier;">Route::post('/login', 'API\UserController@login');</span></div><div><span style="font-family: courier;">Route::get('/user/profile', 'API\UserController@login');</span></div><p style="text-align: left;">Function login in app/Http/Controllers/API/UserController.php</p><div><div><span style="font-family: courier;"> /**</span></div><div><span style="font-family: courier;"> * @OA\Post(</span></div><div><span style="font-family: courier;"> * path="/api/login",</span></div><div><span style="font-family: courier;"> * tags={"Login"},</span></div><div><span style="font-family: courier;"> * security={{"appkey":{}}},</span></div><div><span style="font-family: courier;"> * @OA\RequestBody( required=true, description="Login",</span></div><div><span style="font-family: courier;"> * @OA\MediaType(</span></div><div><span style="font-family: courier;"> * mediaType="multipart/form-data",</span></div><div><span style="font-family: courier;"> * @OA\Schema(</span></div><div><span style="font-family: courier;"> * required={"username","password"},</span></div><div><span style="font-family: courier;"> * @OA\Property(</span></div><div><span style="font-family: courier;"> * property="username",</span></div><div><span style="font-family: courier;"> * type="string",</span></div><div><span style="font-family: courier;"> * description="user login id of type email"</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * @OA\Property(</span></div><div><span style="font-family: courier;"> * property="password",</span></div><div><span style="font-family: courier;"> * type="password"</span></div><div><span style="font-family: courier;"> *</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> *</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * @OA\Response(response="200", description="An example endpoint",</span></div><div><span style="font-family: courier;"> * @OA\JsonContent(</span></div><div><span style="font-family: courier;"> * @OA\Property(property="id", type="number", example="1957"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="token", type="string", example="173892|HxOQJBfDgDgDgaqgCpSS1rh7UY7HWdurtanHhq7"),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * @OA\Response(response="400", description="The id or password incorrect.",</span></div><div><span style="font-family: courier;"> * @OA\JsonContent(</span></div><div><span style="font-family: courier;"> * @OA\Property(property="message", type="string", example="These credentials do not match our records."),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * )</span></div><div><span style="font-family: courier;"> */</span></div></div><div><br /></div><div>Function getUserProfile in app/Http/Controllers/API/UserController.php</div><div><div><span style="font-family: courier;"> /**</span></div><div><span style="font-family: courier;"> * @OA\Get(</span></div><div><span style="font-family: courier;"> * path="/api/user/profile",</span></div><div><span style="font-family: courier;"> * tags={"Login"},</span></div><div><span style="font-family: courier;"> * summary="Retrieve user profile",</span></div><div><span style="font-family: courier;"> * description="Retrieve user profile based on user auth detected. No parameters are required",</span></div><div><span style="font-family: courier;"> * operationId="getUserProfile",</span></div><div><span style="font-family: courier;"> * security={{"bearer_token":{}}},</span></div><div><span style="font-family: courier;"> * @OA\Parameter(</span></div><div><span style="font-family: courier;"> * name="App-Key",</span></div><div><span style="font-family: courier;"> * in="header",</span></div><div><span style="font-family: courier;"> * description="App-Key",</span></div><div><span style="font-family: courier;"> * example=L5_SWAGGER_APPKEY</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> *</span></div><div><span style="font-family: courier;"> * @OA\Response(response=401, description="User not authenticated",</span></div><div><span style="font-family: courier;"> * @OA\JsonContent(</span></div><div><span style="font-family: courier;"> * @OA\Property(property="status", type="number", example="1"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="message", type="string", example="Not authenticated"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="data", type="string", example=null),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="timestamp", type="string", example="2023-03-17T10:00:09"),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * @OA\Response(</span></div><div><span style="font-family: courier;"> * response=200,</span></div><div><span style="font-family: courier;"> * description="Success",</span></div><div><span style="font-family: courier;"> * @OA\JsonContent(</span></div><div><span style="font-family: courier;"> * @OA\Property(property="status", type="number"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="message", type="string", example=null),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="data", type="array",</span></div><div><span style="font-family: courier;"> * @OA\Items(</span></div><div><span style="font-family: courier;"> * @OA\Property(property="id", type="number", example=385),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="name", type="string", example="Bintulu"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="address1", type="string", example="no.3 River side, Sarawak"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="address2", type="string", example=null),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="introduction", type="string", example="Software architect and Postgresql architect"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="phone", type="string", example="1234512345"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="email", type="string", example="bintulu@some.email.example"),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="notes", type="string", example="Call by phone"),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * @OA\Property(property="timestamp", type="string", example="2023-03-17T10:00:09"),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> * ),</span></div><div><span style="font-family: courier;"> */</span></div></div><div><br /></div><div><br /></div><p></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-84889802906018903972023-10-17T21:10:00.005+08:002023-10-17T21:10:00.143+08:00Laravel Helper class<p>Programming is made more systematic with a large number of helper classes in Laravel. Examples are the Arr::last, Arr::add, Arr::get, asset, route, secure_url, url, dd, collect, env)</p><p>Lots of documentations are available at Laravel (see <a href="https://laravel.com/docs/7.x/helpers" target="_blank">Laravel 7</a>). </p><p>Example of usage</p><h3 style="text-align: left;">Helper url( )</h3><div>Returns a fully qualified URL</div><div><br /></div><div>$url = url('user/profile');</div><div><br /></div><h3 style="text-align: left;">Creating your first helper class</h3><div>The following illustrates a function named "courier" that will be available to all controllers. It typically returns data in a predefined format.</div><div><br /></div><h4 style="text-align: left;">Step 1: Create a helper file in app/Helpers with the name myHelpers.php</h4><div><br /></div><div>/app/Helpers/myHelpers.php</div><div><br /></div><h4 style="text-align: left;">Step 2: Create the function in the file myHelpers.php</h4><div><br /></div><div><div><?php</div><div>use Carbon\Carbon;</div><div><br /></div><div>if (! function_exists('courier')) {</div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>function courier($status, $message, $data){</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$now = carbon::now();</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$status = $status??0;</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$package = [</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>'status'=>$status,</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>'message'=>$message,</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>'data'=>$data,</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>'timestamp'=>$now,</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>];</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>return $package;</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></div><div>}</div></div><div><br /></div><h4 style="text-align: left;">Step 3: Edit [autoload] in composer.json</h4><div><br /></div><div><div>"autoload": {</div><div> "files": [</div><div> "app/Helpers/myHelpers.php",</div><div> ],</div></div><div><br /></div><h4 style="text-align: left;">Step 4: Reload Laravel</h4><div><br /></div><div>composer dump-autoload</div><div><br /></div><h3 style="text-align: left;">Usage of "courier" helper </h3><div>In any of the function in Controller classes, call the helper function. Example</div><div><br /></div><div><div>public function getUsers( ){</div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$users = User::where('status','active')->get();</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$status=0; // success</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$message=null;</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>if(count($users)>0){</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$status=1; // success but not users available</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>$message="None";</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>}</span></div><div><span style="white-space: normal;"><span style="white-space: pre;"> </span>return response(courier($status, $message, $users), 200);</span></div><div>}</div></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-75534306298525427302023-10-12T20:19:00.000+08:002023-10-12T20:19:01.924+08:00Laravel 10 - User API authentication with Sanctum<h2 style="text-align: left;">Laravel 10 and User API authentication with sanctum</h2><p>Laravel 10 is available to create restful API where it provides (1)process to issue API tokens to users AND (2)authentication of single page applications(SPA).</p><p>This tutorial requirements of system;</p><p></p><ul style="text-align: left;"><li>laravel/sanctum version 3.3.1</li><li>PHP version 8.2.11</li><li>Node version 18.12.1</li><li>Composer version 2.6.3</li><li>Npm version 8.19.2</li><li>PostgreSQL database version 15</li></ul><p></p><p>Laravel application is successfully installed will all recommended PHP extensions.</p><p>Create the database and assign user hello assign to that database, which I name as demo. Use hello, or any other user you have created in the database.</p><p><br /></p><div style="text-align: left;">create database demo;<br />grant all privileges on database demo to hello;<br />ALTER DATABASE demo OWNER TO hello;</div><p><br /></p><p>Lets create the Laravel application and add sanctum support</p><p><br /></p><div style="text-align: left;">composer create-project laravel/laravel demo<br />cd demo</div><p><br /></p><p>Configure the .env file to access the database that was declared as demo.</p><p><br /></p><div style="text-align: left;">DB_CONNECTION=pgsql<br />DB_HOST=127.0.0.1<br />DB_PORT=5432<br />DB_DATABASE=demo<br />DB_USERNAME=hello<br />DB_PASSWORD=</div><div style="text-align: left;"><br /></div><div style="text-align: left;">composer require laravel/sanctum<br />php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"</div><p><br /></p><p>Identify and inspect the following folders and files;</p><p><br /></p><div style="text-align: left;">config/sanctum.php<br />database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php</div><p><br /></p><p>Create database for Sanctum and enable Sanctum</p><p><br /></p><p>php artisan migrate</p><p><br /></p><p>Edit app/Http/Kernel.php</p><p><br /></p><div style="text-align: left;">'api' => [<br /> \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,<br /> 'throttle:api',<br /> \Illuminate\Routing\Middleware\SubstituteBindings::class,<br />],</div><p><br /></p><p>Configure sanctum by editing model, service provider and auth config. Edit app/Models/User.php</p><p><br /></p><div style="text-align: left;">use Laravel\Sanctum\HasApiTokens;<br />...<br />use HasApiTokens;</div><p><br /></p><p>Add API to register and login</p><p><br /></p><p>Edit routes/api.php</p><p> </p><div style="text-align: left;">Route::controller(RegisterController::class)->group(function(){<br /> Route::post('register', 'register');<br /> Route::post('login', 'login');<br />});</div><p><br /></p><div style="text-align: left;">php artisan make:controller BaseController<br />php artisan make:controller RegisterController</div><p><br /></p><p>Edit RegisterController </p><p><br /></p><div style="text-align: left;">use App\Http\Controllers\BaseController as BaseController;<br />use App\Models\User;<br />use Illuminate\Support\Facades\Auth;<br />use Validator;<br />use Illuminate\Http\JsonResponse;</div><p><br /></p><div style="text-align: left;">public function register(Request $request): JsonResponse<br /> {<br /> $validator = Validator::make($request->all(), [<br /> 'name' => 'required',<br /> 'email' => 'required|email',<br /> 'password' => 'required',<br /> 'c_password' => 'required|same:password',<br /> ]);</div><div style="text-align: left;"> <br /> if($validator->fails()){<br /> return $this->sendError('Validation Error.', $validator->errors()); <br /> }<br /> <br /> $input = $request->all();<br /> $input['password'] = bcrypt($input['password']);<br /> $user = User::create($input);<br /> $success['token'] = $user->createToken('MyApp')->plainTextToken;<br /> $success['name'] = $user->name;<br /> <br /> return $this->sendResponse($success, 'User register successfully.');<br /> }<br /> <br /> /**<br /> * Login api<br /> *<br /> * @return \Illuminate\Http\Response<br /> */<br /> public function login(Request $request): JsonResponse<br /> {<br /> if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ <br /> $user = Auth::user(); <br /> $success['token'] = $user->createToken('MyApp')->plainTextToken; <br /> $success['name'] = $user->name;<br /> <br /> return $this->sendResponse($success, 'User login successfully.');<br /> } <br /> else{ <br /> return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);<br /> } <br /> }</div><p><br /></p><p>Retrieve the registration api </p><p><br /></p><div style="text-align: left;">{<br /> "success": true,<br /> "data": {<br /> "token": "1|R8qfygjItwjleo23QwdqqS5ZcVLZwaRH72iJjiEqd4d85583",<br /> "name": "admin@example.com"<br /> },<br /> "message": "User register successfully."<br />}</div><p><br /></p><p>Retrieve login api</p><p><br /></p><div style="text-align: left;">{<br /> "success": true,<br /> "data": {<br /> "token": "2|IyNnxOU0N1cc0s2bADqzASxzwc8kl7z5UbqZ2oARd68aa58b",<br /> "name": "admin@example.com"<br /> },<br /> "message": "User login successfully."<br />}</div><p><br /></p><p>Ref: https://www.itsolutionstuff.com/post/laravel-10-rest-api-authentication-using-sanctum-tutorialexample.html#google_vignette</p><p>https://laravel.com/docs/10.x/sanctum#token-ability-middleware</p><p><br /></p><p>Next, add a appkey token.</p><p>https://laravel.com/docs/10.x/middleware</p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-85678501696908943342023-10-02T18:20:00.014+08:002023-10-02T18:32:54.768+08:00MySQL group by unix timestamp<p>Drupal CMS includes a webform where each form has an ID. An example to retrieve number of user access of a Drupal database for a given node id. The column ws.created is stored with a unix timestamp (looks like many digits number). Use MySQL function from_unixtime to format into something like 2023-10-02. The node in this example have an ID=940.</p>
<div class="mycode"><div style="text-align: left;">select count(ufd.name) submissions, DATE_FORMAT(from_unixtime(ws.created), "%Y-%m-%d")<br />from webform_submission ws <br />left join users_field_data ufd <br />on ws.uid = ufd.uid<br />left join node_field_data nfd <br />on ws.entity_id = nfd.nid<br />where ws.in_draft = 0<br />and ws.entity_type like 'node'<br />and ws.entity_id = 940<br />group by DATE_FORMAT(from_unixtime(ws.created), "%Y-%m-%d")</div></div><div style="text-align: left;"><br /></div><div style="text-align: left;">Here is a query to list all the associated users who accessed the webform</div><div style="text-align: left;"><br /></div><div style="text-align: left;">
<div class="mycode">select ufd.name name, ufd.mail email, from_unixtime(ws.created) accepted_at, from_unixtime(ws.changed) changed_at, ws.remote_addr <br />,nfd.title, ws.uri URL<br />from webform_submission ws <br />left join users_field_data ufd <br />on ws.uid = ufd.uid<br />left join node_field_data nfd <br />on ws.entity_id = nfd.nid <br />where ws.in_draft = 0<br />and ws.entity_type like 'node'<br />and ws.entity_id = 940<br />
</div></div><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-31513175546711113102023-09-19T23:00:00.004+08:002023-09-19T23:00:00.144+08:00R language basics<p>The R programming language can be downloaded then installed from https://cran.r-project.org/index.html</p><p>Next download and install R Studio from https://posit.co/download/rstudio-desktop/</p><p>Install the R tutorial by opening R Studio, in a console install the package swirl and start the tutorial.</p><p><span style="font-family: courier;">install.packages("swirl")</span></p><p><span style="font-family: courier;">library(swirl)</span></p><p><span style="font-family: courier;">swirl()</span></p><p>Following are the initial list of commands learnt from Swirl in lesson 1 to 4</p><p>skip(), play(), nxt(), bye(), main(), info()</p><p>c(), sqrt(), info()</p><p>help commands ?c , ?`:`</p><p>getwd(), ls(), list.files(), dir(), args(), getwd(), dir.create(), setwd(), file.create(mytest.R), file.exists(), file.info(), file.rename(from, to), file.path(),setwd(),unlink("testdir",recursive=TRUE)</p><p>seq(), seq(1,10, by=0.5), length(), rep(0, times=40),rep(c(0,1,2), times=10)</p><p>rep(c(0,1,2), each=10)</p><p><br /></p><p>Happy R gramming!</p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-90102425053046862522023-09-14T21:00:00.005+08:002023-09-14T21:00:00.160+08:00Centos 7 monitoring with cockpit<p>Monitor Centos Linux 7 servers through a web browser. On Centos Stream 8, Cockpit is installed by default on the most parts.</p><h3 style="text-align: left;">Steps to install cockpit and start the service</h3><p>These require Linux Administrative user access at the command line.</p>
<div class="mycode"><p>sudo yum install cockpit cockpit-storaged</p><p>sudo systemctl enable --now cockpit.socket</p><p>sudo firewall-cmd --permanent --zone=public --add-service=cockpit</p><p>sudo firewall-cmd --reload</p>
</div>
<p>OR with iptables</p>
<div class="mycode"><p>sudo iptables -A INPUT -i eth0 -s 0/0 -p tcp --dport 9090 -j ACCEPT</p><p>sudo systemctl start cockpit</p>
</div><h3 style="text-align: left;">Access Cockpit</h3><p>On web browser access URL http://<serverip>:9090</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR8HmoeVY5p4f1ymFq3qS7IlaViWxSkbST4PE5Vqbb2yyvEWaJV7gRNTiQOX4XL7rrLXdUs_P5fPEB7uygnn-IHKBRGJ-eXuSxUnunHEFkz6UOamBOKMqPKLZCN_dfcCxj8-d_q1syxs7MRrJ7Ad3HsELQnSkEDRrLcFOb22N6pwj2o5zV2jCJhVz_ELt3/s906/cockpit-2023-09-14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Cockpit layout" border="0" data-original-height="715" data-original-width="906" height="506" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR8HmoeVY5p4f1ymFq3qS7IlaViWxSkbST4PE5Vqbb2yyvEWaJV7gRNTiQOX4XL7rrLXdUs_P5fPEB7uygnn-IHKBRGJ-eXuSxUnunHEFkz6UOamBOKMqPKLZCN_dfcCxj8-d_q1syxs7MRrJ7Ad3HsELQnSkEDRrLcFOb22N6pwj2o5zV2jCJhVz_ELt3/w640-h506/cockpit-2023-09-14.png" title="Cockpit layout" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-19154884038492617302023-09-13T05:00:00.043+08:002023-09-13T05:00:00.134+08:00How to add remote MySQL user access.<p>Users created in MySQL should be for localhost access. In order for a user to be connected from a remote computer, the IP address must be mentioned in its user record. Removing a user access is a matter of deleting that user from the user record.</p><h3 style="text-align: left;">How to add remote user access</h3><p>Example, user with login "developer" wants to access MySQL database at server 10.1.1.100 from a laptop at the IP address 10.1.2.23.</p><p>The network and database administrator received approval to allow any user to access remotely from the IP address 10.1.2.1 to 10.1.2.224 to the existing database name "tutorial". Here is how its done.</p><p>Step 1: Login as server administrator and ensure MySQL can accept connections from remote servers.</p><p>MySQL community , edit the file /etc/my.cnf</p><p>MariaDB community , edit the file /etc/my.cnf.d/server.cnf</p><p>Add the following line, save.</p><p>bind-address=0.0.0.0</p><p>Restart the MySQL server.</p><p>Ensure the server firewall allows access to MySQL port, where default is port 3306.</p><p>Example for Centos;</p><p><span style="font-family: courier;">sudo firewall-cmd --new-zone=public --permanent</span></p><p><span style="font-family: courier;">sudo firewall-cmd --reload</span></p><p><span style="font-family: courier;">sudo firewall-cmd --permanent --zone=public --add-source=133.155.44.103</span></p><p><span style="font-family: courier;">sudo firewall-cmd --permanent --zone=public --add-port=3306/tcp</span></p><p><span style="font-family: courier;">sudo firewall-cmd --reload</span></p><p><span style="font-family: courier;">sudo firewall-cmd --list-all-zones</span></p><p><span style="font-family: courier;">sudo firewall-cmd --get-services</span></p><p><br /></p><p>Step 2: Login to MySQL database as administrator. Add login for remote user and list users.</p><p><span style="font-family: courier;">mysql -u root -p</span></p>
<div class="mycode">
<p>> CREATE USER 'developer'@'10.2.%' IDENTIFIED BY 'password';</p><p>> SELECT user,host FROM mysql.user;</p><p><br /></p></div>
<p>Step 3: Assign login to access database</p>
<div class="mycode"><p>> GRANT ALL PRIVILEGES ON 'tutorial'.* to 'developer'@'10.2.%';</p><p>> FLUSH PRIVILEGES;</p><p>> SHOW GRANTS FOR 'developer'@'10.2.%';</p></div>
<p><br /></p><p>Step 4: Monitor connection;</p>
<div class="mycode"><p>> SELECT user,host, command FROM information_schema.processlist;</p></div>
<p><br /></p><h3 style="text-align: left;">How to connect remotely</h3><p>On the remote server, run the following client command </p><p><span style="font-family: courier;">mysql -u developer -p -h 10.1.1.100</span></p><p>The MySQL client, it should have the same configuration for SSL as the server to avoid SSL issues.</p><p><br /></p><h3 style="text-align: left;">How to remove remote user access</h3><p>Login as database administrator and delete login of user and its host as recorded in database;</p>
<div class="mycode"><p>> DELETE FROM mysql.user WHERE User='developer' AND Host NOT IN ('localhost', '127.0.0.1', '::1');</p><p>> FLUSH PRIVILEGES;</p></div><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-49991725190353503122023-09-11T22:00:00.033+08:002023-09-11T22:00:00.140+08:00How to add datasource to reportserver.net?<p>Extracting from MySQL and PostgreSql database can be done via Reportserver.net. Other relational databases are also supported as of Reportserver.net version 4.</p><h3 style="text-align: left;">Configuration</h3><p>Step 1: Login as administrator user</p><p>Step 2: In the menu choose "Datasources", then right click "Datasource Root" and right click to choose "Insert" ->"Relational Database".</p><p>Step 3: Enter the following and click "Apply"</p><p></p><ul style="text-align: left;"><li>Name</li><li>Description</li><li>Database</li><li>Username</li><li>Password</li><li>URL</li></ul><div>The Permission tab provides better control for user to access.</div><div><br /></div><div><b>Postgresql database URL</b></div><div><br /></div><div><span style="font-family: courier;">jdbc:postgresql://10.1.1.102/customers</span></div><div><br /></div><div><b>MySQL database without SSL URL</b></div><div><br /></div><div><span style="font-family: courier;">jdbc:mysql://10.1.1.100:3306/customers?useSSL=false</span></div><div><br /></div><p></p><div><b>MySQL database URL</b></div><div><br /></div><div><span style="font-family: courier;">jdbc:mysql://10.1.1.100:3306/customers</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: inherit;">Details for other databases can be found at <a href="https://reportserver.net/en/guides/admin/chapters/Datasources/">https://reportserver.net/en/guides/admin/chapters/Datasources/</a></span></div><div><br /></div><h3 style="text-align: left;">Troubleshooting</h3><div>Host 'host_name' is blocked in MySQL</div><div><br /></div><div>Too many attempts made to the database can be caused by having or not having ssl. </div><div><b>Solution:</b></div><div>Try to disable SSL protocol for the client.</div><div><br /></div><div>Missing Relational Database Driver</div><div><br /></div><div>Reportserver.net comes with several drivers. To customise datasource, </div><div>Login as administrator and click "File System".</div><div>Click "Fileserver Root"->"etc"->"datasources"->"datasources".</div><div>Click on tab "Edit file".</div><div><br /></div><div>It defaults to the following:</div><div><div><span style="font-family: courier;"><?xml version="1.0" encoding="UTF-8"?></span></div><div><span style="font-family: courier;"><configuration></span></div><div><span style="font-family: courier;"> <datasource></span></div><div><span style="font-family: courier;"> <defaultDatasourceName>Demo Data</defaultDatasourceName></span></div><div><span style="font-family: courier;"> <!-- or access via ID --></span></div><div><span style="font-family: courier;"> <!-- <defaultDatasource>14</defaultDatasource> --></span></div><div><span style="font-family: courier;"> </datasource></span></div><div><span style="font-family: courier;"></configuration></span></div></div><div><br /></div><div><br /></div><div>Reference: <a href="https://reportserver.net/en/guides/config/chapters/Manual-Installation/">https://reportserver.net/en/guides/config/chapters/Manual-Installation/</a></div><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-68422296537744571422023-09-08T06:30:00.029+08:002023-09-08T06:30:00.145+08:00How to read excel data with PhpSpreadsheet<p>PhpSpreadsheet provides a PHP library of classes to read and write formats such as LibreOffice Calc, Microsoft Office and CSV. The default encoding uses UTF-8.</p><p>Ref: https://phpspreadsheet.readthedocs.io/en/latest/faq/</p><p>In Laravel 5, 6 and 7, this is available through the Composer. </p><p><span style="font-family: courier;">composer require phpoffice/phpspreadsheet niklasravnsborg/laravel-pdf mpdf/mpdf:8.1.6 league/csv</span></p><p><span style="font-family: inherit;">OR</span></p><p><span style="font-family: courier;">composer require phpoffice/phpspreadsheet niklasravnsborg/laravel-pdf mpdf/mpdf league/csv</span></p><p>Here is an example of how to read the first three columns of an xlsx file, where the first row is considered as headers.</p><p>Step 1: Import the class for LibreOffice</p><div style="text-align: left;"><span style="font-family: courier;">use PhpOffice\PhpSpreadsheet\Reader\Ods;</span></div><p>Or for Microsoft Excel</p><p><span style="font-family: courier;">use PhpOffice\PhpSpreadsheet\Reader\</span><span style="font-family: courier;">Xlsx</span><span style="font-family: courier;">;</span></p><p>Step 2: In the function that is to retrieve the data, declare object for LibreOffice</p><div style="text-align: left;"><span style="font-family: courier;">$reader = new Ods();</span></div><p style="text-align: left;"><span style="font-family: inherit;">OR </span>for Microsoft Excel</p><div style="text-align: left;"><span style="font-family: courier;">$reader = new Xlsx();</span></div><div style="text-align: left;"><span style="font-family: courier;"><br /></span></div><div style="text-align: left;"><p style="text-align: left;"><span><span style="font-family: inherit;">Step 3: Load the spreadsheet data </span></span></p><span><span style="font-family: courier;">$spreadsheet = $reader->load($path);</span><br /><span style="font-family: courier;">$sheet = $spreadsheet->getActiveSheet();</span></span></div><div><br /></div><div>OR, load a sheet with specified name</div><div><span style="font-family: courier;">$spreadsheet = $reader->setLoadSheetsOnly(["Sheet1"])->load($path);</span></div><div><span style="font-family: courier;">$sheet = $spreadsheet->getActiveSheet();</span></div><div><br /></div><div>Step 4: Process rows, and skip header in first row</div><div><br /></div><div><span style="font-family: courier;">$users = new Users();</span></div><div><div><span style="font-family: courier;">if(!empty($sheet)) {</span></div><div><span style="font-family: courier;"> foreach ($sheet->getRowIterator() as $row) {</span></div></div><div><div><span style="font-family: courier;"> if ($row->getRowIndex() === 1) {</span></div><div><span style="font-family: courier;"> continue; //Skip heading</span></div><div><span style="font-family: courier;"> }</span></div><div><span style="font-family: courier;"> $cells = iterator_to_array($row->getCellIterator("A", "H"));</span></div></div><div><div><span style="font-family: courier;"> $data = [</span></div><div><span style="font-family: courier;"> "Column A" => $cells["A"]->getValue(),</span></div><div><span style="font-family: courier;"> "Column B" => $cells["B"]->getValue(),</span></div><div><span style="font-family: courier;"> "Column C" => $cells["C"]->getValue(),</span></div><div><span style="font-family: courier;"> ];</span></div></div><div><span style="font-family: courier;"> $users->add($data);</span></div><div><span style="font-family: courier;">}</span></div><div><br /></div><div><br /></div><div>The example can be said to retrieve the first 3 columns of the spreadsheet row as fields to create a new user.</div><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-3062567650155115882023-09-07T07:00:00.001+08:002023-09-07T19:23:09.303+08:00Display GIT branch in linux<p>It is useful to have the current Git branch appear at user prompt. This can be done for Centos Linux BASH by updating the user's configuration file .bashrc in the user's home directory.</p><p>Add these lines</p><p><span style="font-family: courier;">git_branch() {</span></p><p><span style="font-family: courier;"> git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'</span></p><p><span style="font-family: courier;">}</span></p><p><span style="font-family: courier;">export PS1="\u@\h \[\e[32m\]\w \[\e[91m\]\$(git_branch)\[\e[00m\]$ "</span></p><p><br /></p><p>This will produce a user prompt like this</p><p><span style="font-family: courier;">login@hostname current_directory(git.branch.name)$</span></p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-16089427548509924792023-09-06T17:32:00.011+08:002023-09-06T17:55:17.315+08:00How to add remote to GIT repo<p>Git remote provide information to sync with a Git repository to do stuff like git fetch, git push, git pull.</p><p>This information is stored in .git/config. In the case of a new directory, that does not have git, start by configuring it with the command git init. Managing remote can be done by the following commands.</p><h4 style="text-align: left;">Adding a remote</h4><p><span style="font-family: courier;">git remote add <name> <url></span></p><p><br /></p><p>Example</p><p><span style="font-family: courier;">git remote add git_user1 user1@git.myserver.local/repo/package.git</span></p><p><span style="font-family: courier;">git remote add ssh_user1 ssh://user1@10.1.1.100/repo/package.git</span></p><p><br /></p><h4 style="text-align: left;">View the current remote and detailed remote information</h4><p><span style="font-family: courier;">git remote</span></p><p><span style="font-family: courier;">git remote -v</span></p><p><br /></p><h4 style="text-align: left;">Remove a remote</h4><p><span style="font-family: courier;">git remote remove <name></span></p><p><span style="font-family: courier;">git remote rm <name></span></p><p><br /></p><p>Example</p><p><span style="font-family: courier;">git remote rm remote_user1</span></p><p><br /></p><h4 style="text-align: left;">Push changes of the specific remote</h4><p><span style="font-family: courier;">git push <name></span></p><p><br /></p><p>Example</p><p><span style="font-family: courier;">git push ssh_user1</span></p><p>or to push as a new branch</p><p><span style="font-family: courier;">git push -u ssh_user1 new_branch</span></p><p><br /></p><h4 style="text-align: left;">Show log of the remote</h4><p><span style="font-family: courier;">git remote show <name></span></p><p><br /></p><p>Example</p><p><span style="font-family: courier;">git remote show ssh_user1</span></p><p><br /></p><h4>Show status of CURRENT branch</h4><p><span style="font-family: courier;">git status</span></p><p><br /></p><h4 style="text-align: left;">Change url of an existing remote</h4><p><span style="font-family: courier;">git remote set-url <name> <new url></span></p><p><br /></p><p>Example</p><p><span style="font-family: courier;">git remote set-url remote_user1 ssh://user1@10.1.1.23/repo/package.git</span></p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-72704786464663044652023-08-03T11:00:00.003+08:002023-08-03T11:00:00.140+08:00Basic of SQL joins<p>SQL join statements are used to combine rows from two or more tables, based on related column(s) between those tables. These statements assist user to extract data from tables which have one-to-many or many-to-many relationships between them.</p><p>Here is a basic list of join command examples as used in PostgreSQL database.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2k5PQublG12E02xu_nsjCMsg9a5lFDI9Y1Tdnj_hAoYT7jHPG2sj-tTHKTefL7_cgLQFBy-e5rbHRItoiSmTT8HIQxEZWdLuND9vHAN7jIleYwNxsT8nZYC7e75kOFzJsxGEBrInz6S8NmXx-ygTMzwUb_-e-ypr3yT2Asau_P0ihs55dTAm-vITxtfHe/s1684/basic-sql-join-0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="SQL join command examples" border="0" data-original-height="1684" data-original-width="1190" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2k5PQublG12E02xu_nsjCMsg9a5lFDI9Y1Tdnj_hAoYT7jHPG2sj-tTHKTefL7_cgLQFBy-e5rbHRItoiSmTT8HIQxEZWdLuND9vHAN7jIleYwNxsT8nZYC7e75kOFzJsxGEBrInz6S8NmXx-ygTMzwUb_-e-ypr3yT2Asau_P0ihs55dTAm-vITxtfHe/w452-h640/basic-sql-join-0.jpg" title="SQL join commands" width="452" /></a></div><br /><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-1790198890624199152023-03-28T18:10:00.000+08:002023-03-28T18:10:11.643+08:00GIT tag and retag<p>Working with GIT allows tagging specific points along the repository that have some importance. Commonly, tag is used when a version is released. Here are examples of listing tags, adding and deleting a tag.</p><h3 style="text-align: left;">List tags</h3><p>List tag on local</p><p><span style="font-family: courier;">git tag -l "v1.*"</span></p><p><span style="font-family: courier;">git tag</span></p><p>List tag on repository</p><p><span style="font-family: courier;">git ls-remote --tags</span></p><p>Display details of a tag</p><p><span style="font-family: courier;">git show v1.0.2</span></p><p><br /></p><h3 style="text-align: left;">Add tag to current branch</h3><p><span style="font-family: courier;">git tag -a v1.0.2 HEAD -m "Update for version 1.0.2"</span></p><p><span style="font-family: courier;">git push origin --tags</span></p><p>Tag can be added to a specific commit.</p><p><span style="font-family: courier;">git tag -a v1.0.2 f8c3501-m "Update for version 1.0.2" </span></p><p><br /></p><h3 style="text-align: left;">Retagging</h3><p>This requires deleting current tag, then publish changes to remote repository.</p><p><span style="font-family: courier;">git tag -d v1.0.2</span></p><p><span style="font-family: courier;">git push origin :refs/tags/v1.0.2</span></p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-88645483551081563032023-03-21T15:59:00.001+08:002023-03-21T15:59:11.396+08:00How to create a dynamic object from standard class<p> PHP provides a class to create a temporary object where no specific class and members are required.</p><p><br /></p><p>The class stdClass is the empty class in PHP used to cast other types to object. Among the example of stdClass usage;</p><p></p><ol style="text-align: left;"><li>Directly access the members by calling them</li><li>Dynamic objects can be provided for temporary usage</li></ol><div>E.g. </div><div>An array can be treated as an object by using stdClass. </div><div><br /></div><div><div>$tmpStudent = array(</div><div>"name" => "John Doe"</div></div><div>);</div><div><br /></div><div>To access data, </div><div>$tmpStudent['name']</div><div><br /></div><div>$tmpStudent = new stdClass;</div><div>$tmpStudent->name = "John Doe";</div><div><br /></div><div>Using the stdClass, this can be done as an object</div><div>$tmpStudent->name</div><div><br /></div><div><br /></div><p></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-65052363677839191542023-02-16T16:17:00.010+08:002023-02-16T18:52:59.561+08:00Reportserver query with wildcards<p>The community edition of Reportserver.net provide a large number of useful functions. This include managing user access, download in different formats, user freedom to customise the report and access from different databases.</p><p>Here is an example of string query with wildcard and parameters. The $P{email} is a parameter where you can enter a value.</p><p><br /></p><p><span style="font-family: courier;">SELECT user_id, email, registration_id, date, venue, type, status</span></p><p><span style="font-family: courier;">FROM student_registration</span></p><p><span style="font-family: courier;">WHERE email LIKE '%'||$P{email}||'%'</span></p><p><span style="font-family: inherit;">Another example to apply parameter ${timezone} which is the default handling of variable, in this case to add with date from created_at</span></p><p><span style="font-family: courier;">SELECT user_id, email, registration_id, created_at::timestamp + ${timezone}::interval as created_at</span></p><p><span style="font-family: courier;">FROM student_registration</span></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-74444201195944324912023-02-15T19:08:00.000+08:002023-02-15T19:08:39.730+08:00Centos Stream 8 with Selinux and high CPU <p>In a server with only 1 CPU, there are times where Linux service fight to gain usage of resources. However, Selinux strict policies may cause a service to repeatedly demand usage that lead to 100% CPU usage.</p><p>Several ways to diagnose, which would include to determine the max connections and process running. The commands include</p><p>To view number of connection on the web server</p><p>ss -ant | grep -E ':80|:443' </p><p>systemctl status httpd</p><div><br /></div><p>To view number of processes running, sorted by CPU or memory.</p><p>top</p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-85198421632641823982023-02-15T10:20:00.008+08:002023-02-15T10:25:30.872+08:00Laravel and search for json content in postgresql database<p>This is a note on usage of JSON in Laravel 8.</p><p>Given a Postgresql database with a table name customer, that have a column name status it would look like this</p><p><span style="font-family: courier;">status=[<br /></span><span style="font-family: courier;">{"id": 5, "name": "registered", "description": "Registered only","date":"20221002 013600}<br /></span><span style="font-family: courier;">]</span></p><p>The function to search for JSON includes;</p><p><b>whereJsonContains</b></p><p><b>orWhereJsonContains</b></p><p><br /></p><p>Laravel sample code to retrieve all rows where status is either 2, 5, or 6 would look like this;</p><p><span style="font-family: courier;">$filter = [2,5,6];</span></p><p><span style="font-family: courier;">$customers = Customers::where(function ($q) use ($filter) {</span></p><p><span style="font-family: courier;"> foreach ($filter as $val) {</span></p><p><span style="font-family: courier;"> $q->orWhereJsonContains('customers.status', [['id' => $val]]);</span></p><p><span style="font-family: courier;"> }</span></p><p><span style="font-family: courier;">})->get( );</span></p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-89024988296348224262023-01-31T10:30:00.028+08:002023-01-31T13:10:25.918+08:00Kali Linux on MS Windows 10<p>MS Windows 10 have been an interesting change for Microsoft operating system, and maybe MS Windows 11 will build on its capability to work with more operating systems.</p><p>Here is how to update MS Windows 10 to run Kali Linux, a Debian based Linux operating system. Its the basic system, and supports installation of additional Linux tools. Among default tools available are</p><p></p><ul style="text-align: left;"><li>BruteShark - Network Forensic Analysis Tool (NFAT)</li><li>Evil-WinRM - Ultimate WinRM shell</li><li>Hakrawler - Web crawler designed for easy, quick discovery of endpoints and assets</li><li>Httpx - Fast and multi-purpose HTTP toolkit</li><li>LAPSDumper - Dumps LAPS passwords</li><li>PhpSploit - Stealth post-exploitation framework</li><li>PEDump - Dump Win32 executable files</li><li>SentryPeer - SIP peer-to-peer honeypot for VoIP</li><li>Sparrow-wifi - Graphical Wi-Fi Analyzer for Linux</li><li>wifipumpkin3 - Powerful framework for rogue access points</li></ul><p></p><p>On MS Windows, the WSL2 component needs to be downloaded and configured.</p><p>Firstly, open Powershell prompt as Administrator.</p><p>In the prompt type,</p><p>Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -norestart </p><p>dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all</p><p><br /></p><p>Download and install (double click the file and follow the instructions) the wsl_update for your specific computer architecture. e.g. x64. Reboot the computer.</p><p>open Powershell prompt as Administrator.</p><p>In the prompt type,</p><p>wsl --set-default-version 2</p><p>Open microsoft app store and install Kali Linux (https://aka.ms/wslstore). Click get, then Open. A command prompt screen will appear and start to initialise.</p><p>Enter a default username (without spaces or special characters). Then enter the password and verify.</p><p>By default, Kali Linux installs dbus-x11 to access Linux desktop.</p><h4 style="text-align: left;">Install a user desktop</h4><p>On debian systems, the command apt-get installs additional packages to provide more tools and features. XFCE is a light weight desktop that provide a windows like environment to run applications, instead of the command line prompt only.</p><p>Its fun to run Linux commands on the Verify that you can access internet and install additional Linux apps with the following command</p><p>sudo apt-get install wget</p><p>Lets download the XFCE desktop and install</p><p>sudo apt-get install kali-defaults kali-root-login desktop-base xfce4 xfce4-places-plugin xfce4-goodies</p><p>sudo apt install -y kali-desktop-xfce xrdp</p><p>When asked to select the “Default display manager”, choose lightdm</p><p>Now, its time to go get some coffee after the following command as the download size is over 1.2Gb. But keep an eye on the terminal as it will prompt for your input. </p><p>Choosing different desktops</p><p>If you have other desktops, the default can be shown by</p><p>update-alternatives --config x-session-manager</p><p>After the install is done, start the desktop </p><p><br /></p><p>During installation, troubleshooting: </p><p>There is an error "kali-desktop-base_2022.4.5_all.deb 404 Not Found", it may be due to the default Kali not able to find the updated URL of resources. Run the following commands;</p><p>apt-get update</p><p>apt-get install kali-defaults kali-root-login desktop-base xfce4 xfce4-places-plugin xfce4-goodies --fix-missing</p><p>Dont know which XRDP port?</p><p>sudo lsof -i -P -n | grep LISTEN</p><h4 style="text-align: left;">Access Linux desktop on MS Windows</h4><p>On a regular Kali Linux, command to start xfce is "systemctl enable xrdp --now". But the WSL version provided doesnt support this. Lets configure xfce for larger screens, then start xfce. </p><p>cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.backup</p><p>sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini</p><p>sed -i 's/max_bpp=32/#max_bpp=32\nmax_bpp=128/g' /etc/xrdp/xrdp.ini</p><p>sed -i 's/xserverbpp=24/#xserverbpp=24\nxserverbpp=128/g' /etc/xrdp/xrdp.ini</p><p><br /></p><p>/etc/init.d/xrdp start</p><p>To stop the desktop</p><p>sudo /etc/init.d/xrdp stop</p><p>This will result in a port number being use for the desktop access. Refe to the file /etc/xrdp/xrdp.ini for details. E.g. port 3390.</p><p>From the Windows Start, Open up Remote Desktop (mstsc) and connect to localhost:3390</p><p>Login with the username you provided at the installation stage.</p><h4 style="text-align: left;">View incoming packets</h4><p>Login to Kali Linux command prompt,</p><p>apt-get install pktstat</p><p>pktstat -n</p><h4 style="text-align: left;">Access USB device (not working)</h4><p>Install the required 3rd party packages. At this moment, I have only managed to get it working on Ubuntu. Will update for Kali in future if there is a solution.</p><p>The following command should display detected disk, however Kali failed as MS Windows 10 did not have USB pass through. </p><p>fdisk -l</p><p>Open wsl, the default ubuntu and install the usb tools</p><p>sudo apt-get update && apt install linux-tools-common linux-tools-generic hwdata</p><p>Login to Kali Linux</p><p>winget install --interactive --exact dorssel.usbipd-win</p><p>apt-get install usbip</p><h4 style="text-align: left;">Install top 10 Kali tools</h4><p>A list of top 10 tools is available, which takes over 2.2Gb storage size. The command is</p><p>apt-get install kali-tools-top10</p><p><br /></p><p>Ref: </p><p><a href="https://www.kali.org/docs/general-use/xfce-faq/" target="_blank">Kali.org</a></p><p><a href="https://github.com/dorssel/usbipd-win/releases/download/v2.4.1" target="_blank">USBIPD</a><br /></p><p><a href="https://devblogs.microsoft.com/commandline/connecting-usb-devices-to-wsl/" target="_blank">XDA USB</a><br /></p><p><a href="https://www.xda-developers.com/wsl-connect-usb-devices-windows-11/" target="_blank">Another XDA USB</a><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-84700848105044665782023-01-27T14:30:00.004+08:002023-01-27T18:53:16.839+08:00Tinker and Controller methods<p> Tinker is the tool for command line debugging in Laravel. </p><p>To start the tool, type</p><p>php artisan tinker</p><h4 style="text-align: left;">Create an object from Model</h4><p>In tinker command line, objects can be created and saved to database. E.g.</p><p>$user = new App\Model\User</p><p>$user->name = "Tboxmy"</p><p>$user->email = "tboxmy@yahoo.com"</p><p>$user->save()</p><p><br /></p><p>Then to display the content of object;</p><p>$user</p><h4 style="text-align: left;">Finding data from model</h4><p>The eloquent function find( ) allows retrieving from the database, given its default index id. e.g.</p><p>$user = App\Model\User::find(2)</p><p>Then to display the content of object;</p><p>$user</p><p>Another approach is to use the function where( ) to retrieve based on the table column names. e.g.</p><p>$user = App\Model\User::where('name','Tboxmy')->first( )</p><p>Or to retrieve all those related values</p><p>$user = App\Model\User::where('id', '>', 2)->first( )</p><p>Then to display the content of object;</p><p>$user</p><div><br /></div><h4 style="text-align: left;">Introduction to app() and how to call a method in a controller?</h4><p>A helper object app( ) allows access to the different functions to access a model or controller. The call( ) function is one of the app( ) functions, it is used to access a method inside a controller. e.g. in the controller have a method declared as following;</p><p>public function methodName($id=0, $name=null){</p><p>. . .</p><p>}</p><p>The function call( ) can then be used this way;</p><p>app()->call(' App\Http\Controllers\HomeController@methodName');</p><p><br /></p><p>When working with different Controllers, its useful to declare these as variables using the make( ) function. Here is how its done;</p><p>$controller = app()->make('App\Http\Controllers\HomeController');</p><p>app()->call([$controller, 'methodName'] );</p><h4 style="text-align: left;">How to pass parameters to methods in a controller? </h4><p>This is done with the function call( ) where parameter 2 contains the method parameters. Using the method above, here is how its done;</p><p>app()->call([$controller, 'methodName'], [ 'id' => 2, 'name' => 'Tboxmy'] );</p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-85100006676892514442023-01-18T11:27:00.000+08:002023-01-18T11:27:04.187+08:00Save linux output to jpg or image file<p> There are cases where from the Linux terminal, it is required to post the output as an attachment in jpg or png. If ImageMagick is installed, this can be done easily, otherwise they use the traditional command pr to provide the output to printer.</p><p>Pre-requisite</p><p>Install ImageMagick</p><p>Combine the command convert with the output. E.g. output of the route command can be saved as png</p><p>route | convert label:@- myroutetable.png</p><p>Next to add data into the png image.</p><p>$ convert myroutetable.png \</p><p>> -set 'Copyright' 'CC-BY-SA 4.0'\</p><p>> -set 'Title' 'Routing Table for Linux' \</p><p>> routetable.png</p><p><br /></p><p>The content can then be viewed by the command hexdump</p><p>hexdump -C routetable.png</p><p>Or</p><p>strings routetable.png</p><p><br /></p><p><br /></p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-91344982468302606782023-01-10T16:22:00.004+08:002023-01-10T16:22:20.561+08:00Find files by data and type in Linux<p> How do I find files in a Linux system? or specifically on Centos Linus?</p><p>The command ls will list files in a specific directory. Using the asterisk (*) its possible to display list of files and directory with wildcards. </p><p>E.g.</p><p>ls -l</p><p>ls -lt</p><p>ls -lrt</p><p>ls /etc</p><p>ls /etc/h*</p><p><br /></p><h3 style="text-align: left;">Search files with command grep and ls</h3><p>ls -lt /etc/ | grep filename</p><p><br /></p><h3 style="text-align: left;">Search files with command find</h3><p>find directory -type f -name filename</p><p><br /></p><p>The command find provide more flexibility in search for files.</p><p><br /></p><h3 style="text-align: left;">Search ordinary files that has the extension .cpp</h3><p>find /home/you -iname "*.cpp" -type f</p><p><br /></p><h3 style="text-align: left;">Search ordinary files that has the extension .cpp that are more than 30 days</h3><p>find /home/you -iname "*.cpp" -atime -30 -type f</p><p><br /></p><h3 style="text-align: left;">Search files from a given modified date</h3><p>find . -type f -newermt 2023-01-01</p><p><br /></p><h3 style="text-align: left;">Search files from a given access date</h3><p>find . -type f -newerat 2017-09-25 ! -newerat 2017-09-26</p><p><br /></p><h3 style="text-align: left;">Search files given a date range</h3><p>touch --date "2007-01-01" /tmp/start.file</p><p>touch --date "2008-01-01" /tmp/end.file</p><p>find /data/images -type f -newer /tmp/start.file -not -newer /tmp/end.file</p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-78016276816077899842023-01-02T11:03:00.005+08:002023-01-02T11:03:38.621+08:00Copy Postgresql database to another server<p> Notes for Postgresql 11,12</p><p>This approach allows an SQL file to be copied to a destination server and install using that sql file.</p><p>On the source server</p><p><span style="font-family: courier;">pg_dump -C -Fp -f dump.sql -U postgres database_name</span></p><p><br /></p><p>Copy the file dump.sql to the destination server. On the destination server</p><p><span style="font-family: courier;">psql -U postgres -f dump.sql</span></p><p><br /></p><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0tag:blogger.com,1999:blog-3314261111650744510.post-45125962762494178142022-11-03T12:46:00.007+08:002022-11-03T13:00:00.011+08:00SQL Query with JSON column in Postgresql<p>I still use JSON datatypes in databases, and its proving to its worth. Postgresql loads the whole row during queries and this reduce access to other tables for join and retains data, instead of relying on dynamic changes of another table. JSONB type column is supported by Reportserver.net which I have mentioned in <a href="https://tboxmy.blogspot.com/2021/02/select-query-with-json-column-in.html" rel="nofollow">previous post</a>. </p><p>Here is an example to use JSONB type column in Postgresql 12 and newer. Difference from previous post, here its saved as an object instead of an array. Use of JSON or JSONB type is very much determined by the data intended for storage and retrieval.</p><p>Points to note:</p><p>Symbol <span style="font-family: courier;">-></span></p><p>meaning: Get JSON array element (indexed from zero, negative integers count from the end)</p><p>Or Get JSON object field by key</p><p>Symbol: <span style="font-family: courier;">->></span></p><p>meaning: Get JSON array element as text Or Get JSON object field as text</p><p>Symbol: @></p><p>meaning: Does the left JSON value contain the right JSON path/value entries at the top level?</p><h3 style="background-color: #fcfdfe; border: 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; margin: 0px; padding: 7px 0px;">Step 1: Create the sample database</h3><span style="font-family: courier;"><div>CREATE TABLE public.products (</div><div><span style="white-space: pre;"> </span>id serial NOT NULL,</div><div><span style="white-space: pre;"> </span>"name" varchar(255) NOT NULL,</div><div><span style="white-space: pre;"> </span>unit varchar NOT NULL, -- limit to 2 decimals</div><div><span style="white-space: pre;"> </span>product jsonb NOT NULL,</div><div><span style="white-space: pre;"> </span>created_at timestamp(0) NULL,</div><div><span style="white-space: pre;"> </span>updated_at timestamp(0) NULL,</div><div><span style="white-space: pre;"> </span>CONSTRAINT products_pkey PRIMARY KEY (id)</div><div>);</div><div><br /></div></span><h3 style="background-color: #fcfdfe; border: 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; margin: 0px; padding: 7px 0px;">Step 2: Add sample data</h3><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4z0UxShCFG8kGD0zbxd4Upzic48mxit1ycbNuV7ga1sf5Kkg4lJgIOCPGnUzZ6LX2GU1Jh2ppNm3OV9676ayWQyMNuZxRV5Shm6V7r4eBxgIcregEULC_-9yrjICQKB6Yk3ff7lDwPU12wcTmzcpJwj-2wicE9t9374uBPuORlb17jjEfMGEp2bFukg/s1257/product_sample_data.PNG" style="margin-left: 1em; margin-right: 1em;"><img alt="sample data" border="0" data-original-height="177" data-original-width="1257" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4z0UxShCFG8kGD0zbxd4Upzic48mxit1ycbNuV7ga1sf5Kkg4lJgIOCPGnUzZ6LX2GU1Jh2ppNm3OV9676ayWQyMNuZxRV5Shm6V7r4eBxgIcregEULC_-9yrjICQKB6Yk3ff7lDwPU12wcTmzcpJwj-2wicE9t9374uBPuORlb17jjEfMGEp2bFukg/w640-h90/product_sample_data.PNG" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><h3 style="background-color: #fcfdfe; border: 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; margin: 0px; padding: 7px 0px; text-align: left;">Step 3: Run an SQL query</h3><span style="font-family: courier; text-align: left;"><div><span style="font-family: "Times New Roman";">Display list of data as is.</span></div><div><span style="font-family: "Times New Roman";"><br /></span></div>SELECT id, name, product from products;</span><div style="text-align: left;"><span style="font-family: courier;"><br /></span></div></div><p style="background-color: #fcfdfe; border: 0px; margin: 0px; padding: 7px 0px;"><span style="color: #333333; font-family: courier; font-size: xx-small;">id|name |product |</span></p><p style="background-color: #fcfdfe; border: 0px; margin: 0px; padding: 7px 0px;"><span style="color: #333333; font-family: courier; font-size: xx-small;">--|-----------|-------------------------------------------------------------------------------------------------------|</span></p><p style="background-color: #fcfdfe; border: 0px; margin: 0px; padding: 7px 0px;"><span style="color: #333333; font-family: courier; font-size: xx-small;"> 3|Apple Pie |{"id": 5, "name": "Apple Pie", "details": {"value": "1All-1-1000-xzp", "source": "Malaysia"}} |</span></p><p style="background-color: #fcfdfe; border: 0px; margin: 0px; padding: 7px 0px;"><span style="color: #333333; font-family: courier; font-size: xx-small;"> 1|Orange Bod |{"id": 18, "name": "Orange Gala", "details": {"value": "1Bll-1-99-aaa", "source": "Malaysia"}} |</span></p><p style="background-color: #fcfdfe; border: 0px; margin: 0px; padding: 7px 0px;"><span style="color: #333333; font-family: courier; font-size: xx-small;"> 2|Chicken Pie|{"id": 4, "name": "Downtown Chicken Pie", "details": {"value": "1Bll-1-201-aaa", "source": "Malaysia"}}|</span></p><h3 style="background-color: #fcfdfe; border: 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; margin: 0px; padding: 7px 0px;"><span style="background-color: transparent; font-family: "Times New Roman";"><br /></span></h3>Display columns id, name and product->details<div><span style="font-family: courier;"><span style="font-family: "Times New Roman";"><br /></span></span></div><div><span style="font-family: courier;">SELECT id, name, product->'details' from products;</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;"><span style="font-family: "Times New Roman";">or</span></span></div><div><span style="font-family: courier;">SELECT id, name, product->'details' as details from products;</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;"><span style="font-family: "Times New Roman";">Display columns id, name and sub contents of a json data</span></span></div><div><span style="font-family: courier;">select id, name, (product->'details')::jsonb->'source' as details from products;</span></div><div><span style="font-family: courier;"><br /></span></div><div><br /></div><div><h3>The WHERE clause</h3><div><p style="background-color: #fcfdfe; border: 0px; color: #333333; font-size: 13px; margin: 0px; padding: 7px 0px;"><span style="color: black; font-size: medium;">Lets retrieve rows where jsonb element key 'name' have a specific value.</span></p><p style="background-color: #fcfdfe; border: 0px; color: #333333; font-size: 13px; margin: 0px; padding: 7px 0px;"><span style="background-color: transparent; font-family: courier;">SELECT id, name, product->'details' as details from products</span></p><span style="font-family: courier;">where product->>'name'= 'Apple Pie'</span></div><div><span style="font-family: courier;"><br /></span></div><p style="text-align: left;">Retrieve rows where jsonb element key 'name' have a wildcard (%) value.</p><div><span style="font-family: courier;">select id, name, product->'details' as details from products</span></div><div><span style="font-family: courier;"><div>where product->>'name' like 'Apple %'</div><div><br /></div></span><p style="text-align: left;">Retrieve rows where jsonb sub element key 'value' have a wildcard (%) value.</p><span style="font-family: courier;"><div><div>select id, name, product->'details' as details from products</div><div>where product->'details'->>'value'::text like '1All-1-%'</div></div><div><div><br /></div><p style="text-align: left;"><span style="font-family: "Times New Roman";">Retrieve rows where jsonb element have a specific key:value</span></p><div>select id, name, product as details from products</div><div>where product @> '{"name":"Orange Gala"}'</div></div></span></div><div><br /></div><div><br /></div>I hope these examples will benefit you. </div><div class="blogger-post-footer"><script type="text/javascript"><!--
google_ad_client = "pub-5866957587922171";
//468x60, created 1/9/08
google_ad_slot = "5375318316";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Tboxmyhttp://www.blogger.com/profile/06749525177696246387noreply@blogger.com0