3 months ago
pragma solidity ^0.4.18;

// ----------------------------------------------------------------------------
// 'FIXED' 'Example Fixed Supply Token' token contract
//
// Symbol      : FIXED
// Name        : Your own token
// Total supply: 1,000,000,000.000000000000000000
// Decimals    : 18
//
// Enjoy.
//
// (c) BokkyPooBah / Bok Consulting Pty Ltd 2017. The MIT Licence.
// ----------------------------------------------------------------------------


// ----------------------------------------------------------------------------
// Safe maths
// ----------------------------------------------------------------------------
library SafeMath {
    function add(uint a, uint b) internal pure returns (uint c) {
        c = a + b;
        require(c >= a);
    }
    function sub(uint a, uint b) internal pure returns (uint c) {
        require(b <= a);
        c = a - b;
    }
    function mul(uint a, uint b) internal pure returns (uint c) {
        c = a * b;
        require(a == 0 || c / a == b);
    }
    function div(uint a, uint b) internal pure returns (uint c) {
        require(b > 0);
        c = a / b;
    }
}


// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ----------------------------------------------------------------------------
contract ERC20Interface {
    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}


// ----------------------------------------------------------------------------
// Contract function to receive approval and execute function in one call
//
// Borrowed from MiniMeToken
// ----------------------------------------------------------------------------
contract ApproveAndCallFallBack {
    function receiveApproval(address from, uint256 tokens, address token, bytes data) public;
}


// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
    address public owner;
    address public newOwner;

    event OwnershipTransferred(address indexed _from, address indexed _to);

    function Owned() public {
        owner = msg.sender;
    }

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    function transferOwnership(address _newOwner) public onlyOwner {
        newOwner = _newOwner;
    }
    function acceptOwnership() public {
        require(msg.sender == newOwner);
        OwnershipTransferred(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}


// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals and an
// initial fixed supply
// ----------------------------------------------------------------------------
contract FixedSupplyToken is ERC20Interface, Owned {
    using SafeMath for uint;

    string public symbol;
    string public  name;
    uint8 public decimals;
    uint public _totalSupply;

    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;


    // ------------------------------------------------------------------------
    // Constructor
    // ------------------------------------------------------------------------
    function FixedSupplyToken() public {
        symbol = "FIXED";
        name = "Your own Token";
        decimals = 18;
        _totalSupply = 4200000000 * 10**uint(decimals);
        balances[owner] = _totalSupply;
        Transfer(address(0), owner, _totalSupply);
    }


    // ------------------------------------------------------------------------
    // Total supply
    // ------------------------------------------------------------------------
    function totalSupply() public constant returns (uint) {
        return _totalSupply  - balances[address(0)];
    }


    // ------------------------------------------------------------------------
    // Get the token balance for account `tokenOwner`
    // ------------------------------------------------------------------------
    function balanceOf(address tokenOwner) public constant returns (uint balance) {
        return balances[tokenOwner];
    }


    // ------------------------------------------------------------------------
    // Transfer the balance from token owner's account to `to` account
    // - Owner's account must have sufficient balance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transfer(address to, uint tokens) public returns (bool success) {
        balances[msg.sender] = balances[msg.sender].sub(tokens);
        balances[to] = balances[to].add(tokens);
        Transfer(msg.sender, to, tokens);
        return true;
    }


    // ------------------------------------------------------------------------
    // Token owner can approve for `spender` to transferFrom(...) `tokens`
    // from the token owner's account
    //
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
    // recommends that there are no checks for the approval double-spend attack
    // as this should be implemented in user interfaces 
    // ------------------------------------------------------------------------
    function approve(address spender, uint tokens) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        Approval(msg.sender, spender, tokens);
        return true;
    }


    // ------------------------------------------------------------------------
    // Transfer `tokens` from the `from` account to the `to` account
    // 
    // The calling account must already have sufficient tokens approve(...)-d
    // for spending from the `from` account and
    // - From account must have sufficient balance to transfer
    // - Spender must have sufficient allowance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        balances[from] = balances[from].sub(tokens);
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);
        balances[to] = balances[to].add(tokens);
        Transfer(from, to, tokens);
        return true;
    }


    // ------------------------------------------------------------------------
    // Returns the amount of tokens approved by the owner that can be
    // transferred to the spender's account
    // ------------------------------------------------------------------------
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }


    // ------------------------------------------------------------------------
    // Token owner can approve for `spender` to transferFrom(...) `tokens`
    // from the token owner's account. The `spender` contract function
    // `receiveApproval(...)` is then executed
    // ------------------------------------------------------------------------
    function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        Approval(msg.sender, spender, tokens);
        ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
        return true;
    }


    // ------------------------------------------------------------------------
    // Don't accept ETH
    // ------------------------------------------------------------------------
    function () public payable {
        revert();
    }


    // ------------------------------------------------------------------------
    // Owner can transfer out any accidentally sent ERC20 tokens
    // ------------------------------------------------------------------------
    function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
        return ERC20Interface(tokenAddress).transfer(owner, tokens);
    }
}

 
5 months ago
adduser appdev
adduser appdev sudo
vim /etc/ssh/sshd_config

update PasswordAuthentication from no to yes to allow new user login with password

service ssh restart

on local machine

ssh-copy-id appdev@mzctjkj.com
ssh appdev@mzctjkj.com
vim /etc/ssh/sshd_config

update PasswordAuthentication from yes to no to secure your linux server
and update PermitRootLogin from yes to no

sudo service ssh restart
sudo apt-get update
sudo apt-get upgrade

install tool

sudo apt-get install build-essential git-core curl libssl-dev libreadline5 libreadline-gplv2-dev zlib1g zlib1g-dev libcurl4-openssl-dev libxslt-dev libxml2-dev libffi-dev git vim

install rvm without root user

\curl -sSL https://get.rvm.io | bash
source ~/.rvm/scripts/rvm

install ruby now

rvm install 2.3.1

update gem source from default to china mirror

gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
gem sources -l
$*** CURRENT SOURCES ***

$https://gems.ruby-china.org
$## confirm there is only one gems.ruby-china.org
gem install bundler
gem install passenger
rvmsudo passenger-install-nginx-module

选择Ruby & NodeJS

再选择选项1. Yes: download, complie and install Nginx for me. (recommended)

选择安装目录, 可以直接按回车,使用默认安装目录[/opt/niginx]

install nginx with passenger now

git clone git://github.com/jnstq/rails-nginx-passenger-ubuntu.git
sudo mv rails-nginx-passenger-ubuntu/nginx/nginx /etc/init.d/nginx
sudo chown root:root /etc/init.d/nginx
sudo vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStartPre=/opt/nginx/sbin/nginx -t
ExecStart=/opt/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target

restart nginx to verify

sudo /etc/init.d/nginx restart

install rails

gem install rails -v 5.1.4

install nodejs

sudo apt-get install npm

install PostgreSQL

sudo apt-get install postgresql postgresql-contrib libpq-dev
gem install pg

update postgre password

sudo -u postgres psql
\password postgres

leave by

\q

let rails know how to connect database

sudo vim /etc/postgresql/9.5/main/pg_hba.conf

update all md5 to peer

sudo /etc/init.d/postgresql reload

now the machine is running

 
6 months ago

copy muyushi_zscjq folder to linux server

scp -r your_folder user@remote

login to remote, move the file under location

ssh user@remote
sudo mv folder /var/www 

create muyushi_zscjq folder under /var/www

create muyushi_zscqj.conf under /etc/nginx/sites-enabled

server {
  listen 80;
  server_name xxx.com;
  location ~/muyushi_zscqj {
    root /var/www/;
  }
}
sudo service nginx restart

open browser to browser http://xxx.com/muyushi_zscqj to verify result

 
6 months ago
adduser appdev
adduser appdev sudo
vim /etc/ssh/sshd_config

update PasswordAuthentication from no to yes to allow new user login with password

service ssh restart

on local machine

ssh-copy-id appdev@mzctjkj.com
ssh appdev@mzctjkj.com
vim /etc/ssh/sshd_config

update PasswordAuthentication from yes to no to secure your linux server
and update PermitRootLogin from yes to no

sudo service ssh restart
sudo apt-get update
sudo apt-get upgrade

install tool

sudo apt-get install build-essential git-core curl libssl-dev libreadline5 libreadline-gplv2-dev zlib1g zlib1g-dev libcurl4-openssl-dev libxslt-dev libxml2-dev libffi-dev git vim

install rvm without root user

\curl -sSL https://get.rvm.io | bash
source ~/.rvm/scripts/rvm

install ruby now

rvm install 2.3.1

update gem source from default to china mirror

gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
gem sources -l
$*** CURRENT SOURCES ***

$https://gems.ruby-china.org
$## confirm there is only one gems.ruby-china.org
gem install bundler
gem install passenger
bundle config mirror.https://rubygems.org https://gems.ruby-china.org
rvmsudo passenger-install-nginx-module

选择Ruby & NodeJS

再选择选项1. Yes: download, complie and install Nginx for me. (recommended)

选择安装目录, 可以直接按回车,使用默认安装目录[/opt/niginx]

install nginx with passenger now

git clone git://github.com/jnstq/rails-nginx-passenger-ubuntu.git
sudo mv rails-nginx-passenger-ubuntu/nginx/nginx /etc/init.d/nginx
sudo chown root:root /etc/init.d/nginx
sudo vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStartPre=/opt/nginx/sbin/nginx -t
ExecStart=/opt/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target

restart nginx to verify

sudo /etc/init.d/nginx restart

enable auto start up for nginx

sudo systemctl enable nginx.service

install rails

gem install rails -v 5.1.4

install nodejs

sudo apt-get install npm

install PostgreSQL

sudo apt-get install postgresql postgresql-contrib libpq-dev
gem install pg

update postgre password

sudo -u postgres psql
\password postgres

leave by

\q

let rails know how to connect database

sudo vim /etc/postgresql/9.5/main/pg_hba.conf

update all md5 to peer

sudo /etc/init.d/postgresql reload

now the machine is running

/opt/nginx/conf/nginx.conf

    listen       80;
    server_name  mzctjkj.com;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    root /home/appdev/wechat/public;
    passenger_enabled on;

    location ~/muyushi{
            root /home/appdev/;
    }

setup a wechat rails server

mkdir your_app
cd your_app
git init
git remote add template https://github.com/goofansu/wechat-starter.git
git fetch template
git checkout -b master template/master
bundle install
rake db:create
bundle exec rake db:create RAILS_ENV=production

generate secret

rake secret

copy generated secret into config/secret

bundle exec rake db:migrate RAILS_ENV=production

create config/application.yml

wechat_app_id: "AppID"
wechat_secret: "AppSecret"
wechat_token:  "Token"
wechat_encoding_aes_key: "EncodingAESKey"
wechat_trusted_domain_fullname: "http://your_dev.proxy.qqbrowser.cc"

config/wechat.yml

default: &default
  appid:  "AppID"
  secret: "AppSecret"
  token:  "Token"
  access_token: "/var/tmp/wechat_access_token"
  jsapi_ticket: "/var/tmp/wechat_jsapi_ticket"

production:
  <<: *default
  encrypt_mode: false 
  encoding_aes_key: "EncodingAESKey"
  trusted_domain_fullname: "http://your_dev.proxy.qqbrowser.cc"
bundle exec rake assets:precompile db:migrate RAILS_ENV=production

config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  host : localhost
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: postgres
  password: postgres

production:
  <<: *default
  adapter: postgresql
  database: wechat_starter_production
  host : localhost
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: postgres
  password: postgres

open yourhost.com in wechat client

 
8 months ago

老猫的公众号很有意思,似乎他和xiaolai对ETH有相同的看法,就是很谨慎。我看了一下现在市场上的代币,包括DAO的历史,我终于明白为什么他们很谨慎,DAO够牛逼了,因为智能合约失误导致币被盗,引起了ETH的硬分叉。

也理解了为什么他们要投EOS,技术上讲EOS应该是风险最小的。

比特币假设10万美金一个,现在是5000美金,理论上还有20倍空间。

简单的投资方法是有钱就买,但是需要反复投入自由资金。

稍微复杂的方法是有钱就买,感觉过了顶峰就卖一点,然后下跌到一部分再买回来。 可是这个方案可能做不到。

在数字货币的世界里面,现行增长的曲线已经不够用了,要用指数增长的曲线

那么怎么操作呢?

目前观察了几个代币

 
9 months ago

当下2017年9月5日,中国大陆官方监管机构一起发文禁止ICO的第二天。所有的数字货币品种都在下跌。

有的人使用了暴跌,但是以我对数字货币的看法,暴跌并不合适。

我参与的一个ICO motion.one,让大家自己选择,我选择了不退币继续支持。
在下跌之前,我还做了一个决定,每月定投1000块买EOS。禁令公文一出,EOS官方出了一个声明,宣布不欢迎中国公民购买和使用EOS,并且明确说明lixiaolai不是EOS创始人或者员工或者发言人。但是没有否认他是投资人。

定投EOS的积极原因如下,觉得这个创始人还是很靠谱,技术能力够,过去做的三个项目也都成功了,没有烂尾。想做的产品不是凭空想象,而是来自于过去几个项目的积累,目标也够宏伟,应该可以长期看好

定投EOS的反面原因如下,跌势没有走完,现在定投有点早,前期高点太近了,从投机的角度突破前期高点估计要很久,两年左右吧。产品过于宏大可能实现不了。

下一个购买是一个月以后,国庆节。 但是在数字货币的世界里面可能交易周期应该是股票三分之一。

 
9 months ago

VPS linode
64bit, OS: Ubuntu 16.04 LTS

Update system

apt update && apt upgrade

Install docker

apt install docker.io

Start docker

systemctl start docker
systemctl enable docker

pull docker image we need

docker pull imhang/kcp-shadowsocks-docker

run image for test

docker run -p 443:443 -p 443:443/udp -p 9443:9443/udp --rm -it imhang/kcp-shadowsocks-docker

download mac client from github
kcptun

run kcptune client command is

./client_darwin_amd64 -r “yourvps:9443" -l ":8388" --crypt none --key 123456 --mtu 1400 --parityshard 0 --nocomp false

run ssr client with

PORT 443
PASSWORD 123456
METHOD   chacha20
SS_TIMEOUT  600

Now we need to run the server as service

docker run -d --restart=always -e "SS_PORT=443" -e "SS_PASSWORD=123456" -e "SS_METHOD=chacha20" -e "SS_TIMEOUT=600" -e "KCP_PORT=9443" -e "KCP_MODE=fast" -e "MTU=1400" -e "SNDWND=1024" -e "RCVWND=1024" -p 443:443 -p 443:443/udp -p 9443:9443/udp --name ssserver imhang/kcp-shadowsocks-docker

and client command become

./client_darwin_amd64 -r "45.79.215.97:9443" -l ":8388" --crypt none --key 123456 --mtu 1400 --parityshard 0 --nocomp false --sndwnd 1024 --rcvwnd 1024
 
12 months ago

deploy process for a new ubuntu 16.04 64bit

part I setup linux machine for secure reason

verify root account

$ ssh root@remote
$ exit

ssh to remote with local pub key

$ ssh-copy-id root@remote

login again without password

add new user doudouappadmin

$ adduser doudouappadmin

$ adduser doudouappadmin sudo

$ exit

verify with doudouappadmin

$ ssh doudouappadmin@remote
$ exit

login with pub key without password

$ ssh-copy-id doudouappadmin@remote

login with doudouappadmin to disable root login

$ sudo vim /etc/ssh/sshd_config

edit

PermitRootLogin no

make change effect

$ sudo systemctl restart sshd
$ exit

PartII update system and basic lib

$ ssh doudouappadmin@remote

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo dpkg-reconfigure tzdata

Geographic aera - Asia
Time zone - Shanghai

support multilanguage

$ sudo locale-gen zh_TW zh_TW.UTF-8 zh_CN.UTF-8 en_US.UTF-8

用vi编辑器打开

$vim ~/.bashrc

在空白处新增行

export LC_ALL="en_US.UTF-8"

执行

$ source ~/.bashrc

install basic application and lib

$ sudo apt-get install build-essential git-core curl libssl-dev libreadline5 libreadline-gplv2-dev zlib1g zlib1g-dev libcurl4-openssl-dev libxslt-dev libxml2-dev libffi-dev git vim

install RVM

$ \curl -sSL https://get.rvm.io | bash

then run

$ source ~/.rvm/scripts/rvm

install Ruby

$ rvm install 2.3.1

confirm ruby

$ rvm list

setup ruby china mirror

$ gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
$ gem sources -l
*** CURRENT SOURCES ***

https://gems.ruby-china.org
## confirm there is only one gems.ruby-china.org
$ gem install bundler

install RMagick

$ sudo apt-get install imagemagick
$ sudo apt-get install libmagickwand-dev
$ gem install rmagick

install Passenger

install Passenger

$ gem install passenger

install Nginx and merge Passenger

$ rvmsudo passenger-install-nginx-module

选择Ruby & NodeJS

再选择选项1. Yes: download, complie and install Nginx for me. (recommended)

选择安装目录, 可以直接按回车,使用默认安装目录[/opt/niginx]

start nginx

$ git clone git://github.com/jnstq/rails-nginx-passenger-ubuntu.git
$ sudo mv rails-nginx-passenger-ubuntu/nginx/nginx /etc/init.d/nginx
$ sudo chown root:root /etc/init.d/nginx

edit nginx server 档(只有 Ubuntu 16+ 需要)

$ sudo vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStartPre=/opt/nginx/sbin/nginx -t
ExecStart=/opt/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target

restart Nginx

$ sudo /etc/init.d/nginx restart

Nginx

browser http://xx.xx.xx.xx to verify nginx

install rails 5.0.3

$ gem install rails -v 5.0.3

install nodejs

$ sudo apt-get install npm

install PostgreSQL

$ sudo apt-get install postgresql postgresql-contrib libpq-dev
$ gem install pg

update postgres password
login psql

$ sudo -u postgres psql

update postgres password

\password postgres

leave by

\q

let Rails know to connect db with the account

# sudo vim /etc/postgresql/9.5/main/pg_hba.conf

update all md5 to peer and save and run

$ sudo /etc/init.d/postgresql reload

镜像文件到此为止

让远端机器可以去 github 拉档案

$ ssh doudouappadmin@remote

生成ssh key

$ key ssh-keygen

查看pub key

$ more ~/.ssh/id_rsa.pub

去Github的仓库里,项目里面贴到 Settins -> Deploy keys
去远端机测试

$ ssh -T git@github.com

deploy cap if there is no cap 当前已经使用cap了。没有cap的进行如下

使用 Capistrano 部署项目

修改 Gemfile,加入以下内容

group :development do
gem "capistrano", "~> 3.4"
gem "capistrano-rvm"
gem "capistrano-rails"
end
$ bundle install

然后执行

$ cap install

修改 config/deploy.rb

lock '3.6.1'  # 每个人按自己的默认版本,不一定要是"3.6.1"

set :application, 'vidopk'

set :repo_url, 'git@github.com:jiezhon/videopk.git'  # 这里填的是每个人自己的repo地址



set :deploy_to, "/home/doudouappadmin/videopk"

注: 这里示例项目为videopk,也是Gitup的仓库名

如果有图片,视频需要存在其他的云存储服务器,关于云存储的密钥文件application.yml用linkded_files实现从shared目录下读取

set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml', 'config/application.yml')

修改 Capfile

require "capistrano/rvm"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require "capistrano/passenger"

修改config/deploy/production.rb
加上一行,配置server和user

server "1.1.1.1", user: "doudouappadmin", roles: %w{app db web}, my_property: :my_value

在远端生成档案
执行

$ cap production deploy:check

远端服务器配置

在远端机的shared目录下的设定档

$ vim database.yml
production:
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
database: videopk_production
username: postgres
password: YOURPASSWORD
$ vim secrets.yml

在本机上执行

$ rake secret

产生密钥
然后贴到远端机的

$ vim shared/config/secrets.yml
production:

  secret_key_base: 上面产生的那串密钥

配置upyun存储的相关密钥

$vim application.yml
production:
  UPYUN_OPERATOR_ID: "11"
  UPYUN_OPERATOR_PASSWORD: "11"
  UPYUN_BUCKET: "11"
  UPYUN_HOST: "http://11.b0.upaiyun.com"

正式 deploy

执行

$ cap production deploy

第一次会卡在 bundle install 比较久,并且第一次deploy会失败,因为 production db 还没创建
出错信息为 “FATAL: database "videopk_production" dose not exist”
创建DB

到最新的release目录下面

$ cd videopk/released/xxxxxxxx
RAILS_ENV="production" bundle exec rake db:create

再跑一次 cap production deploy

设定 Nginx

$ sudo vi /opt/nginx/conf/nginx.conf
    server {
        listen       80;
        server_name  dd.doudouapp.com;

        root /home/doudouappadmin/videopk/current/public;
        passenger_enabled on;
        client_max_body_size 30M;
    }

重开Nginx

$ sudo /etc/init.d/nginx restart

迁移数据盘

$ sudo disk -l

Device     Boot Start      End  Sectors Size Id Type
/dev/vdb1        2048 41943039 41940992  20G 83 Linux
$ sudo mkdir /data
$ sudo mount /dev/vdb1 /data
$ sudo chown -R postgres:postgres /data/pkdata
#### only if you want to init a disk
$ sudo su - postgres 
$ /usr/lib/postgresql/9.5/bin/initdb -D /data/pkdata
$ exit
### 
$ sudo /etc/init.d/postgresql stop
$ sudo su - postgres
$ /usr/lib/postgresql/9.5/bin/pg_ctl -D /data/pkdata -l logfile start
$ exit
 
about 1 year ago

rails 5.0, devise 4.0
thanks for gist
and devise gem override controller

Part I: Add api

$git branch api_v1
$git checkout api_v1
$rails generate controller api/v1/battles

and copy battles_controller to the new file with some additional code

class Api::V1::BattlesController < ApplicationController
  before_action :authenticate_user!, only: [:follow_left_video, :unfollow_left_video, :follow_right_video, :unfollow_right_video]
  before_action :find_battle, only: [:follow_left_video, :unfollow_left_video, :follow_right_video, :unfollow_right_video]

  def index
    respond_to :json
    @battle = Battle.recent.first

and create file battles.json.jbuilder under app/view/api/v1/battles with content

if @battle.present?
  json.extract! @battle, :id, :title, :description, :left_video_id, :right_video_id
else
  return "no battle"
end

and add new content in route.rb

  namespace :api do
    namespace :v1 do
      resources :battles do
        member do
          post :follow_left_video
          post :unfollow_left_video
          post :follow_right_video
          post :unfollow_right_video
        end

    # resources :videos do
    #   resources :video_comments, only: [:new, :create]
    # end
      resources :battle_comments, only: [:new, :create]
      end
    end
  end

we can test it by input xxx.xx/api/v1/battles.json in browser.

$ git add .
$ git commit -m"api done"
$ git checkout master

Part II: add json login based on devise

Step 1: override devise

from devise gem devise gem override controller

$ git checkout master
$ git branch override_devise
$ git checkout override_devise
$ rails generate devise:controllers users

update devise content in route.rb

Rails.application.routes.draw do
  devise_for :users, controllers: {
    sessions: 'users/sessions'
  }
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  root 'battles#index'

test it now, the user management should still work like before.

Step2 add new gem simple_token_authentication

# Gemfile
gem 'simple_token_authentication', '~> 1.0' # see semver.org

and add one more attribute for user model

$ bundle install
$ rails g migration add_authentication_token_to_users "authentication_token:string{30}:uniq"
$ rails db:migrate

add following code to user.rb in model
on top of user.rb

# app/models/user.rb

class User < ActiveRecord::Base
  acts_as_token_authenticatable
  # Note: you can include any module you want. If available,
  # token authentication will be performed before any other
  # Devise authentication method.
  #
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :invitable, :database_authenticatable,
         :recoverable, :rememberable, :trackable, :validatable,
         :lockable

  # ...

on bottome of user.rb

   def reset_authentication_token!
     self.authentication_token = generate_authentication_token("")
     self.save
   end
 
  private
  def generate_authentication_token(token_generator)
    loop do
      token = Devise.friendly_token
      break token unless User.where(authentication_token: token).first
    end
  end

terst login and logout again, should still work well.

now update app/controllers/users/sessions_controllers.rb

class Users::SessionsController < Devise::SessionsController
  # before_action :configure_sign_in_params, only: [:create]
  skip_before_action :verify_authenticity_token, if: :json_request?


  def json_request?
    request.format.json?
  end
  # GET /resource/sign_in
  # def new
  #   super
  # end

  # POST /resource/sign_in
  def create
    if json_request?
      email = params[:email] if params[:appid]
      password = params[:password] if params[:appsecret]

      id = User.find_by(email: email).try(:id) if email.presence

      # Validations
      if request.format != :json
        render status: 406, json: { message: 'The request must be JSON.' }
        return
      end

      if email.nil? or password.nil?
        render status: 400, json: { message: 'The request MUST contain the user email and password.' }
        return
      end

      # Authentication
      user = User.find_by(email: email)

      if user
        if user.valid_password? password
          user.reset_authentication_token!
          # Note that the data which should be returned depends heavily of the API client needs.
          render status: 200, json: { email: user.email, authentication_token: user.authentication_token, id: id }
        else
          render status: 401, json: { message: 'Invalid email or password.' }
        end
      else
        render status: 401, json: { message: 'Invalid email or password.' }
      end
    else
      #if json_request? == false
      super
    end
  end

  # DELETE /resource/sign_out
  def destroy
    if json_request?

      # Fetch params
      user = User.find_by(authentication_token: params[:user_token])

      if user.nil?
        render status: 404, json: { message: 'Invalid token.' }
      else
        user.authentication_token = nil
        user.save!
        render status: 204, json: nil
      end
    else
      super
    end
  end

  # protected

  # If you have extra params to permit, append them to the sanitizer.
  # def configure_sign_in_params
  #   devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
  # end
end

now we support json login, following is test code in python

import requests
rooturl = "https://lin-rails-tt-myrual.c9users.io"
loginRes = requests.post(rooturl+ "/users/sign_in.json", params={'appid':'app123', 'appsecret':'333', 'email':'admin@test.com', 'password':'123456'})
print(loginRes.text)

Step3 merge json api and simple token

git add .
git commit -m"json login done"
git merge api_v1

test all web browser login and json login again.

now we add protect to api/v1/battles controller

class Api::V1::BattlesController < ApplicationController
  #before_action :authenticate_user!, only: [:follow_left_video, :unfollow_left_video, :follow_right_video, :unfollow_right_video]
  before_action :find_battle, only: [:follow_left_video, :unfollow_left_video, :follow_right_video, :unfollow_right_video]
  #acts_as_token_authentication_handler_for User, fallback: :none
  acts_as_token_authentication_handler_for User , only: [:index, :show, :follow_left_video, :unfollow_left_video, :follow_right_video, :unfollow_right_video]

  def index

and verify in browser again, we should see error now.

now it is time to verify with python code

import requests
rooturl = "https://lin-rails-tuto2-myrual.c9users.io"
failedRes = requests.get(rooturl+"/api/v2/battles.json")
print(failedRes.text)
loginWithoutAppidRes = requests.post(rooturl+ "/users/sign_in.json", params={'appsecret':'333', 'email':'admin@test.com', 'password':'123456'})
print(loginWithoutAppidRes.text)
raw_input()

loginRes = requests.post(rooturl+ "/users/sign_in.json", params={'appid':'app123', 'appsecret':'333', 'email':'admin@test.com', 'password':'123456'})
print(loginRes.text)
auth_token = loginRes.json()['authentication_token']
successRes = requests.get(rooturl+ "/api/v2/battles.json", params={'appid':'app123', 'appsecret':'333', 'user_email':'admin@test.com', 'user_token':auth_token})
print(successRes.text)
raw_input()
failedRes = requests.get(rooturl+"/api/v2/battles.json")
print(failedRes.text)

now the url /api/v1/battles.json is protected

 
about 1 year ago

感谢

https://gorails.com/guides/free-ssl-with-rails-and-nginx-using-let-s-encrypt

linode ubuntu 16.04.02 安装let’s encrypt

首先这个版本的ubuntu没有add-apt-repository,所以要先安装相关的包

sudo apt-get install software-properties-common python-software-properties

然后安装certbot

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot

假设rails 运行在 /home/doudouappadmin/videopk/current/public

sudo letsencrypt certonly --webroot --webroot-path /home/doudouappadmin/videopk/current/public --renew-by-default --email lilin@myrual.me --text --agree-tos  -d dd.doudouapp.com

然后编辑nginx配置文件来启用ssl

sudo vim /opt/nginx/conf/nginx.conf

打开ssl 相关内容
然后

server {
    listen       443 ssl;
    server_name  dd.doudouapp.com;

    ssl_certificate      /etc/letsencrypt/live/dd.doudouapp.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/dd.doudouapp.com/privkey.pem;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    root /home/doudouappadmin/videopk/current/public;
    passenger_enabled on;
    client_max_body_size 30M;
}

然后用ngix 校验一下语法

sudo nginx -t