Beispiel #1
0
func TestControlSign(t *testing.T) {
	param := map[string]interface{}{
		"token":   "000000000",
		"service": "service1",
		"cmd":     "reboot",
	}

	devId := "device1"
	accessKey := "820b4376bad3486199e13a7ada104106"
	secretKey := "EwYmYyqdChgitRcrInBg"
	date := time.Now().Format(time.RFC1123)
	body, _ := json.Marshal(param)
	req, _ := http.NewRequest("POST", fmt.Sprintf("http://127.0.0.1:8080/api/v1/devices/%s", devId), bytes.NewBuffer(body))
	sign := utils.Sign(secretKey, "POST", req.URL.Path, body, date, nil)
	//req, _ := http.NewRequest("POST", "http://push.scloud.letv.com/api/v1/message", bytes.NewBuffer(body))
	req.Header.Add("Date", date)
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Authorization", fmt.Sprintf("LETV %s %s", accessKey, sign))

	reqDump, _ := httputil.DumpRequest(req, true)
	t.Logf("HTTP Request:\n%s", reqDump)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		t.Errorf("request err: %s", err)
		t.FailNow()
	}

	respDump, _ := httputil.DumpResponse(resp, true)
	t.Logf("HTTP Response:\n%s", respDump)
	if resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusBadRequest {
		t.FailNow()
	}
}
Beispiel #2
0
func TestPushSign(t *testing.T) {
	param := map[string]interface{}{
		"msg_type":  1,
		"push_type": 1,
		"content":   "just a test",
	}

	accessKey := "appid_b515357337f7415ab9275df7a3f92d94"
	secretKey := "appsec_ckeasUHYFkAvEitqagAr"
	date := time.Now().Format(time.RFC1123)
	body, _ := json.Marshal(param)
	req, _ := http.NewRequest("POST", "http://127.0.0.1:8080/api/v1/message", bytes.NewBuffer(body))
	sign := utils.Sign(secretKey, "POST", req.URL.Path, body, date, nil)
	//req, _ := http.NewRequest("POST", "http://push.scloud.letv.com/api/v1/message", bytes.NewBuffer(body))
	req.Header.Add("Date", date)
	req.Header.Add("Authorization", fmt.Sprintf("LETV %s %s", accessKey, sign))

	reqDump, _ := httputil.DumpRequest(req, true)
	t.Logf("HTTP Request:\n%s", reqDump)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		t.Errorf("request err: %s", err)
		t.FailNow()
	}

	respDump, _ := httputil.DumpResponse(resp, true)
	t.Logf("HTTP Response:\n%s", respDump)
	if resp.StatusCode != http.StatusOK {
		t.FailNow()
	}
}
Beispiel #3
0
func delApp(w http.ResponseWriter, r *http.Request) {
	authstr := r.Header.Get("Authorization")
	date := r.Header.Get("Date")
	auth := strings.Fields(authstr)
	if len(auth) < 3 {
		errResponse(w, ERR_AUTHORIZE, "invalid 'Authorization' header", 400)
		return
	}
	appid := auth[1]
	sign := auth[2]
	b, err := storage.Instance.HashGet("db_apps", appid)
	if err != nil {
		errResponse(w, ERR_INTERNAL, "storage I/O failed", 500)
		return
	}
	if b == nil {
		errResponse(w, ERR_NOT_EXIST, "app not exist", 400)
		return
	}

	var rawapp storage.RawApp
	json.Unmarshal(b, &rawapp)
	body, _ := ioutil.ReadAll(r.Body)
	if sign != ADMIN_SIGN {
		if utils.Sign(rawapp.AppSec, r.Method, r.URL.Path, body, date, r.Form) != sign {
			errResponse(w, ERR_SIGN, "check sign failed", 400)
			return
		}
	}
	if _, err = storage.Instance.HashDel("db_apps", appid); err != nil {
		errResponse(w, ERR_INTERNAL, "del 'db_apps' failed", 500)
		return
	}
	if _, err = storage.Instance.HashDel("db_packages", rawapp.Pkg); err != nil {
		errResponse(w, ERR_INTERNAL, "del 'db_packages' failed", 500)
		return
	}
	var response Response
	response.ErrNo = 0
	b, _ = json.Marshal(response)
	fmt.Fprintf(w, string(b))
}
Beispiel #4
0
//
// check the signature of the request
// the signature calulation need to read full content of request body
// the body is then put into the request.Env["body"] and passed to
// the next handler
//
func AuthMiddlewareFunc(h rest.HandlerFunc) rest.HandlerFunc {
	return func(w rest.ResponseWriter, r *rest.Request) {
		controlAK := "820b4376bad3486199e13a7ada104106"
		secretKey := "EwYmYyqdChgitRcrInBg"
		authstr := r.Header.Get("Authorization")
		auth := strings.Fields(authstr)
		if len(auth) != 3 {
			rest.Error(w, "Invalid 'Authorization' header", http.StatusBadRequest)
			return
		}
		accessKey := auth[1]
		sign := auth[2]
		if accessKey != controlAK {
			rest.Error(w, "Invalid AccessKey", http.StatusForbidden)
			return
		}

		dateStr := r.Header.Get("Date")
		date, err := time.Parse(time.RFC1123, dateStr)
		if err != nil {
			rest.Error(w, "Invalid 'Date' header", http.StatusBadRequest)
			log.Warnf("Unknown 'Date' header: %s", err.Error())
			return
		}
		log.Debugf("Date header: %s", date.String())

		body, _ := ioutil.ReadAll(r.Body)
		r.ParseForm()
		if sign != "supersignature" { //TODO: remove this
			if utils.Sign(secretKey, r.Method, "/api/v1"+r.URL.Path, body, dateStr, r.Form) != sign {
				rest.Error(w, "Signature varification failed", http.StatusForbidden)
				return
			}
		}
		r.Env["body"] = body
		h(w, r)
	}
}
Beispiel #5
0
func addMessage(w http.ResponseWriter, r *http.Request) {
	authstr := r.Header.Get("Authorization")
	date := r.Header.Get("Date")
	auth := strings.Fields(authstr)
	if len(auth) < 3 {
		errResponse(w, ERR_AUTHORIZE, "invalid 'Authorization' header", 400)
		return
	}
	appid := auth[1]
	sign := auth[2]
	// load app info
	b, err := storage.Instance.HashGet("db_apps", appid)
	if err != nil {
		errResponse(w, ERR_INTERNAL, "get 'db_apps' failed", 500)
		return
	}
	if b == nil {
		errResponse(w, ERR_NOT_EXIST, "app not exist", 400)
		return
	}
	var rawapp storage.RawApp
	json.Unmarshal(b, &rawapp)

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Errorf("read request body failed: (%s) (%s)", r.Body, err)
		errResponse(w, ERR_BAD_REQUEST, "failed read request body", 400)
		return
	}
	// check sign
	if sign != ADMIN_SIGN {
		if utils.Sign(rawapp.AppSec, r.Method, r.URL.Path, body, date, r.Form) != sign {
			errResponse(w, ERR_SIGN, "check sign failed", 400)
			return
		}
	}

	// decode JSON body
	msg := storage.RawMessage{}
	if err := json.Unmarshal(body, &msg); err != nil {
		log.Errorf("JSON decode failed: (%s) (%s)", body, err)
		errResponse(w, ERR_BAD_REQUEST, "json decode body failed", 400)
		return
	}
	msg.AppId = appid
	// check message format
	ok, desc := checkMessage(&msg)
	if !ok {
		errResponse(w, ERR_INVALID_PARAMS, desc, 400)
		return
	}
	msgid := getMsgID()
	if msgid == 0 {
		errResponse(w, ERR_INTERNAL, "no avaiable msgid", 500)
		return
	}
	msg.MsgId = msgid
	if msg.Options.TTL < 0 { // send immediatly
		msg.Options.TTL = 0
	} else if msg.Options.TTL == 0 {
		msg.Options.TTL = 86400 // default
	}

	var response Response
	response.ErrNo = 0
	response.Data = map[string]int64{"msgid": msgid}
	msg.CTime = time.Now().Unix()
	msgBox <- msg
	b, _ = json.Marshal(response)
	fmt.Fprintf(w, string(b))
	storage.Instance.AppStatsPushApi(appid)
}
Beispiel #6
0
func postNotify(w http.ResponseWriter, r *http.Request) {
	var response Response
	response.ErrNo = 10000
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", 405)
		return
	}
	data := PostNotifyData{}
	if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
		response.ErrNo = 10001
		response.ErrMsg = fmt.Sprintf("invalid notification data, %s", err)
		b, _ := json.Marshal(response)
		fmt.Fprintf(w, string(b))
		return
	}

	if len(data.Notices) > conf.Config.Notify.MaxNotices {
		response.ErrNo = 10002
		response.ErrMsg = "notification msgs over limit"
		b, _ := json.Marshal(response)
		fmt.Fprintf(w, string(b))
		return
	}

	results := make(map[int64]chan *Result)
	for _, n := range data.Notices {
		if n.Id == 0 {
			log.Warnf("there's a notice without id")
			continue
		}

		log.Infof("send notice[%d]", n.Id)
		rchan := make(chan *Result)
		results[n.Id] = rchan

		go func(n Notice) {
			if !checkNotice(n) {
				rchan <- &Result{
					Error: fmt.Errorf("invalid notice, please check notice's items with wiki"),
					Data:  nil,
				}
				return
			}

			d := n.PushMsg
			d.PushType = PUSH_WITH_UID
			d.AppId = n.AppId

			log.Infof("get uids with notice[%d]", n.Id)
			err, resp := callThirdPartyIf("GET", fmt.Sprintf("%s%s", conf.Config.Notify.SubUrl, n.Tags), nil, nil)
			if err != nil {
				rchan <- &Result{
					Error: err,
					Data:  nil,
				}
				return
			}
			var uids []string
			getUids(resp, &uids)
			d.PushParams.UserId = uids
			data, _ := json.Marshal(d)

			log.Infof("push msgs with notice[%d]", n.Id)
			path := strings.SplitN(conf.Config.Notify.PushUrl, "/", 4)
			date := time.Now().UTC().String()
			sign := utils.Sign(n.AppSec, "POST", fmt.Sprintf("/%s", path[3]), data, date, nil)
			header := map[string]string{
				"Content-Type":  "application/json",
				"Date":          date,
				"Authorization": fmt.Sprintf("LETV %s %s", n.AppId, sign),
			}
			err, resp = callThirdPartyIf("POST", conf.Config.Notify.PushUrl, bytes.NewBuffer(data), &header)
			rchan <- &Result{
				Error: err,
				Data:  resp,
			}
		}(n)
	}

	for nid, c := range results {
		select {
		case result := <-c:
			log.Infof("sent notice[%d]", nid)
			if result.Error != nil {
				response.Data.UnSent = append(response.Data.UnSent, ResponseItem{Id: nid, Data: fmt.Sprintf("%s", result.Error)})
			} else {
				response.Data.Sent = append(response.Data.Sent, ResponseItem{Id: nid, Data: result.Data})
			}
		case <-time.After(conf.Config.Notify.Timeout * time.Second):
			log.Infof("notify timeout %d", nid)
			response.Data.UnSent = append(response.Data.UnSent, ResponseItem{Id: nid, Data: fmt.Sprintf("notify timeout")})
		}
	}
	b, _ := json.Marshal(response)
	fmt.Fprintf(w, string(b))
}