Trend Writing Secure Code Materials

這應該是我最後一次教趨勢的 Engineer Training Program: Writing Secure Code
在今天把成績送出去之後,留一下紀念

這原本是從 Microsoft 的 Writing Secure Code, Second Edition 找一些教材出來上。

但是有一些東西不見得要看,也有一些更重要的東西想多說一下。

幾次作業分別是包含

  1. Buffer Overflow
  2. SQL Injection
  3. CSRF
  4. XSS
  5. Password Storage
  6. Threat Modeling

我自已比較喜歡的幾點是

老實說自己玩的蠻開心的,唯一的缺點就是不能花工作的時間做,所以常常是假日的時候繼續來公司做。
有興趣的話可以直接看一下底下的鏈結。

Git Repo
https://bitbucket.org/yhchan/trend-etp-writing-secure-code

oh-my-zsh prompt slowness in big git repo

References:

oh-my-zsh uparse_git_dirty (git status) may be quite slow in a big git repo.

My solution is to add the following lines
zstyle ':vcs_info:*:*' check-for-changes false

It works well with theme nicoulaj.

Use Backbone.Paginator to create pagination for table layout HTML

我們教會人手非常不夠,也不見得有工程背景的人,所以很多東西都是簡單就好。
像是主日的錄音檔好了,我們的標準流程是用 Dreamweaver 修改表格,一個禮拜就會多上三個錄音檔,簡單算起來,一年就會有 156 個 entry 會放到頁面中。

例如說

<tr onMouseOver="mark(this,'#ECFBD4','#990000')" onMouseOut="mark(this,'#FFFFFF','#333333')" >
  <td align="center" valign="top">2013.01.20</td>
  <td align="center" valign="top">深思天國(一) 心決定一切</td>
  <td align="center" valign="top">徐坤靖牧師<br /></td>
  <td align="center" valign="top"><a href="http://files.ctfhc.org/sermon/130120.mp3"><img src="images/record.jpg" alt="錄音檔下載" width="120" height="28" border="0" /></a></td>
  <td align="center" valign="top"><a href="http://youtu.be/Y1iSbTN07Cc" target="_blank"><img src="images/video.jpg" alt="線上收看" width="120" height="28" border="0" /></a></td>
</tr>

長久下來之下,這個頁面就包含了 300 個 tr 標籤去顯示每個禮拜的影音檔。

剛好在 JSDC 結束之後,就決定想用 Backbone.js 來在前端用 JavaScript 動手腳,把 table 的每一個 tag 處理好當做 model,最後把 collection 做出來丟給 controller 跟 view。

中間也用了 Backbone.Paginator 幫忙做分頁,簡單的使用方式可以看一下他的範例

最後做出來就會像是

source code 放在 https://bitbucket.org/yhchan/ctfhc-media-pagination,其實東西並不難,只是一開始跟 JavaScript 不熟多花了很多時間而已。而且目前是用 JSONP 在後端把東西用 JSON 丟出來,其實應該可以在前端直接做掉的,但是我現在懶惰了…

比起這種方式,我可能還是希望有一天,我們能自己好好使用好的 CMS 去設計網站吧,2010 年想改用 Drupal,也因為人力的關係胎死腹中…

Using tox and jenkins to have python continuous integration environment

在看幾個 github 上的專案,像是 celery 都會發現他們的 repo 有一個 tox.ini,剛好手邊有個小小的 python 專案,就順便看一下 tox 是什麼。

節錄 tox 官網的介紹。

Tox as is a generic virtualenv management and test command line tool you can use for:

  • checking your package installs correctly with different Python versions and interpreters
  • running your tests in each of the environments, configuring your test tool of choice
  • acting as a frontend to Continuous Integration servers, greatly reducing boilerplate and merging CI and shell-based testing.

對我最實用的功能大概是拿來測試 python2.6 跟 python2.7 的差異,常常不小心就寫出 dictionary comprehension
(事實上如果你記得裝 syntastic 就會提醒你 …)

另外一個好處就是,他是用 virtualenv,確保每次測試的環境都是獨立的,dependency 沒有處理好就會叫一下,不會因為開發環境有裝,然後到 deployment 的時候又要再檢查。

我這邊裝 python2.6 跟 python2.7 是用 pythonbrew

pip install pythonbrew
pythonbrew_install
pythonbrew install 2.7.3 2.6.8

另外一個蠻不錯的,就是他跟 jenkins 結合也不是很困難,大概跟著官網的說明做就好了。

最後我寫的 tox.ini 就會像是

[tox]
envlist = py26, py27

[testenv]
commands = nosetests {posargs:--with-cov --cov-report=xml --with-xunit --cov package}
flake8 --exit-zero package

deps = nose
nose-cov
coverage
mock
flake8

[testenv:py26]
basepython={homedir}/.pythonbrew/pythons/Python-2.6.8/bin/python

[testenv:py27]
basepython={homedir}/.pythonbrew/pythons/Python-2.7.3/bin/python

他同時會幫你用 flake8 檢查程式碼,再配合 nose-cov 幫你產生 cobertura 的 coverage report,以及 xunit 的測試結果,跟 jenkins 接在一起就會像是

不過,如果你是放在 github 上,也許直接用 travis-ci 會簡單的多…

Filter is good

Java

import org.apache.commons.collections.*;
CollectionUtils.filter(list, new Predicate() {
  public boolean evaluate(Object o) {
    return !((String)o).isEmpty();
  }
});

PHP

$list = array_filter($list, function($s) {return !empty($s);});

Python

l = [x for x in l if x]

JavaScript

l = _.filter(l, function(s){return s.length;});

憑著直覺寫的,如果不能動的話再說 XD
這種寫法通常好讀又簡單,不過有些語言要寫的囉嗦一點…

地址

左前方的同事即將要離職了,一如往常地,信件還是在午後送到他的手中。

那麼再下個禮拜呢?那些寫著同樣地址的信件會去哪裡呢?

信件無情緒的投遞著,並且轉送。

那是誰寄給他的呢?是張旅行明信片嗎?是大買場大量灑出的特惠消息嗎?
還是藍色紙張的電信帳單?

改變的時候,我們連地址都改變了,一個一個通知說,我換地址了。
那些重要的東西不會寄失,只有宛如無機質的廣告被寄出,然後停頓。

Hi, 我換地址了。

也許期待的不是什麼,只是害怕寄丟而已。

用 Microsoft Translator API 翻譯 properties 檔案

因為另外一套要錢,所以來用 Microsoft Translator API

#!/usr/bin/env python

# coding: utf-8

import urllib
import sys
import xml.dom.minidom

# Get Bing AppID from https://ssl.bing.com/webmaster/developers/appids.aspx
BING_APPID = 'KERO~'

FILE_FROM = 'lang.properties'
FILE_TO = 'translated.properties'

LANG_FROM = 'en'
LANG_TO = 'zh-chs'

def translate(text, from_lang, to_lang):
    base_url = 'http://api.microsofttranslator.com/v2/Http.svc/Translate?'
    data = urllib.urlencode({'appId':BING_APPID,
                             'from': from_lang.encode('utf-8'),
                             'to': to_lang.encode('utf-8'),
                             'text': text.encode('utf-8')
                            })

    url = base_url + data
    response = urllib.urlopen(url).read()

    dom = xml.dom.minidom.parseString(response)
    result = dom.documentElement.childNodes[0].nodeValue

    return result.encode('utf-8')

def parse_properties(filename):
    langs = {}
    with open(filename, 'r') as f:
        lines = [ line.strip() for line in f.readlines() ]
        for line in lines:
            idx = line.find('=')
            if idx == -1:
                continue

            (key, val) = (line[:idx], line[idx+1:])
            if not key:
                continue

            langs[key] = val

    return langs

def main():
    langs = parse_properties(FILE_FROM)
    translated = { k: translate(v, LANG_FROM, LANG_TO) if v else ""
                   for k,v in langs.items() }

    with open(FILE_TO, 'w+') as f:
        for k,v in sorted(translated.items()):
            f.write("%s=%s\n" % (k,v))

if __name__ == '__main__':
    main()

隨手寫寫,一年沒寫文章,也許有點刻意,差不多該是改變的時候了。