Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.

Commit b214963

Browse files
committed
Example config, mousetrap
1 parent 4e77d0e commit b214963

File tree

8 files changed

+236
-6
lines changed

8 files changed

+236
-6
lines changed

README.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ The `config.toml` file must be present in a working directory. Config file shoul
2929
* `receive` - URL of the webhook where requests will be sent when a new payment appears in receiving account. **WARNING** Gateway server can send multiple requests to this webhook for a single payment! You need to be prepared for it. See: [Security](#security).
3030
* `error` - URL of the webhook where requests will be sent when there is an error with incoming payment
3131

32+
Check [`config-example.toml`](./config-example.toml).
33+
34+
## Getting started
35+
36+
After creating `config.toml` file, you need to run DB migrations:
37+
```
38+
./gateway --migrate-db
39+
```
40+
41+
Then you can start the server:
42+
```
43+
./gateway
44+
```
45+
3246
## API
3347

3448
### GET /payment
@@ -72,12 +86,6 @@ memo=125"
7286

7387
//
7488

75-
## Usage
76-
77-
```
78-
./gateway
79-
```
80-
8189
## Building
8290

8391
[gb](http://getgb.io) is used for building and testing.

config-example.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
port = 8001
2+
horizon = "https://horizon-testnet.stellar.org"
3+
4+
api_key = ""
5+
assets = ["USD", "EUR"]
6+
7+
[database]
8+
type = "mysql"
9+
url = "root:@/gateway_test?parseTime=true"
10+
11+
[accounts]
12+
# GCAW3TYUYGCNODKO4QKMD6PSH5GP3KES4GWGVFCKZ6DD6EJUDUQ77BO6
13+
authorizing_seed = "SDMRITVCFY6IIK6H5DXIVUOL342YFVE3VFOGVF3D7XXHGITPX4ABMYXR"
14+
# GCOGCYU77DLEVYCXDQM7F32M5PCKES6VU3Z5GURF6U6OA5LFOVTRYPOX
15+
issuing_seed = "SCLRUYW3QOMS63AU2IMAEXLCSK73RRL35SY5MYSFV6I63S7BFKJ4KBYF"
16+
# GCFC3H73ATKZOTWB2VUQMNDC7P66WARC2B5MLTY7DOOJ3QUIQBMDPGIJ
17+
receiving_account_id = "GAJBUSUTGTS3MAU2KP6MWJFJACDN4ZJ5YCET23U6XYZZ7WUD2OYQQUR2"
18+
19+
[hooks]
20+
receive = "http://localhost:8002/receive"
21+
error = "http://localhost:8002/error"

vendor/manifest

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@
7575
"revision": "ae71a9cc54fddb61d946abe9191d05a24ac0e21b",
7676
"branch": "master"
7777
},
78+
{
79+
"importpath": "github.com/inconshreveable/mousetrap",
80+
"repository": "https://github.com/inconshreveable/mousetrap",
81+
"revision": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75",
82+
"branch": "master"
83+
},
7884
{
7985
"importpath": "github.com/jmoiron/sqlx",
8086
"repository": "https://github.com/jmoiron/sqlx",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2014 Alan Shreve
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# mousetrap
2+
3+
mousetrap is a tiny library that answers a single question.
4+
5+
On a Windows machine, was the process invoked by someone double clicking on
6+
the executable file while browsing in explorer?
7+
8+
### Motivation
9+
10+
Windows developers unfamiliar with command line tools will often "double-click"
11+
the executable for a tool. Because most CLI tools print the help and then exit
12+
when invoked without arguments, this is often very frustrating for those users.
13+
14+
mousetrap provides a way to detect these invocations so that you can provide
15+
more helpful behavior and instructions on how to run the CLI tool. To see what
16+
this looks like, both from an organizational and a technical perspective, see
17+
https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/
18+
19+
### The interface
20+
21+
The library exposes a single interface:
22+
23+
func StartedByExplorer() (bool)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// +build !windows
2+
3+
package mousetrap
4+
5+
// StartedByExplorer returns true if the program was invoked by the user
6+
// double-clicking on the executable from explorer.exe
7+
//
8+
// It is conservative and returns false if any of the internal calls fail.
9+
// It does not guarantee that the program was run from a terminal. It only can tell you
10+
// whether it was launched from explorer.exe
11+
//
12+
// On non-Windows platforms, it always returns false.
13+
func StartedByExplorer() bool {
14+
return false
15+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// +build windows
2+
// +build !go1.4
3+
4+
package mousetrap
5+
6+
import (
7+
"fmt"
8+
"os"
9+
"syscall"
10+
"unsafe"
11+
)
12+
13+
const (
14+
// defined by the Win32 API
15+
th32cs_snapprocess uintptr = 0x2
16+
)
17+
18+
var (
19+
kernel = syscall.MustLoadDLL("kernel32.dll")
20+
CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot")
21+
Process32First = kernel.MustFindProc("Process32FirstW")
22+
Process32Next = kernel.MustFindProc("Process32NextW")
23+
)
24+
25+
// ProcessEntry32 structure defined by the Win32 API
26+
type processEntry32 struct {
27+
dwSize uint32
28+
cntUsage uint32
29+
th32ProcessID uint32
30+
th32DefaultHeapID int
31+
th32ModuleID uint32
32+
cntThreads uint32
33+
th32ParentProcessID uint32
34+
pcPriClassBase int32
35+
dwFlags uint32
36+
szExeFile [syscall.MAX_PATH]uint16
37+
}
38+
39+
func getProcessEntry(pid int) (pe *processEntry32, err error) {
40+
snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
41+
if snapshot == uintptr(syscall.InvalidHandle) {
42+
err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
43+
return
44+
}
45+
defer syscall.CloseHandle(syscall.Handle(snapshot))
46+
47+
var processEntry processEntry32
48+
processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
49+
ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
50+
if ok == 0 {
51+
err = fmt.Errorf("Process32First: %v", e1)
52+
return
53+
}
54+
55+
for {
56+
if processEntry.th32ProcessID == uint32(pid) {
57+
pe = &processEntry
58+
return
59+
}
60+
61+
ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
62+
if ok == 0 {
63+
err = fmt.Errorf("Process32Next: %v", e1)
64+
return
65+
}
66+
}
67+
}
68+
69+
func getppid() (pid int, err error) {
70+
pe, err := getProcessEntry(os.Getpid())
71+
if err != nil {
72+
return
73+
}
74+
75+
pid = int(pe.th32ParentProcessID)
76+
return
77+
}
78+
79+
// StartedByExplorer returns true if the program was invoked by the user double-clicking
80+
// on the executable from explorer.exe
81+
//
82+
// It is conservative and returns false if any of the internal calls fail.
83+
// It does not guarantee that the program was run from a terminal. It only can tell you
84+
// whether it was launched from explorer.exe
85+
func StartedByExplorer() bool {
86+
ppid, err := getppid()
87+
if err != nil {
88+
return false
89+
}
90+
91+
pe, err := getProcessEntry(ppid)
92+
if err != nil {
93+
return false
94+
}
95+
96+
name := syscall.UTF16ToString(pe.szExeFile[:])
97+
return name == "explorer.exe"
98+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// +build windows
2+
// +build go1.4
3+
4+
package mousetrap
5+
6+
import (
7+
"os"
8+
"syscall"
9+
"unsafe"
10+
)
11+
12+
func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
13+
snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
14+
if err != nil {
15+
return nil, err
16+
}
17+
defer syscall.CloseHandle(snapshot)
18+
var procEntry syscall.ProcessEntry32
19+
procEntry.Size = uint32(unsafe.Sizeof(procEntry))
20+
if err = syscall.Process32First(snapshot, &procEntry); err != nil {
21+
return nil, err
22+
}
23+
for {
24+
if procEntry.ProcessID == uint32(pid) {
25+
return &procEntry, nil
26+
}
27+
err = syscall.Process32Next(snapshot, &procEntry)
28+
if err != nil {
29+
return nil, err
30+
}
31+
}
32+
}
33+
34+
// StartedByExplorer returns true if the program was invoked by the user double-clicking
35+
// on the executable from explorer.exe
36+
//
37+
// It is conservative and returns false if any of the internal calls fail.
38+
// It does not guarantee that the program was run from a terminal. It only can tell you
39+
// whether it was launched from explorer.exe
40+
func StartedByExplorer() bool {
41+
pe, err := getProcessEntry(os.Getppid())
42+
if err != nil {
43+
return false
44+
}
45+
return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
46+
}

0 commit comments

Comments
 (0)