Merge pull request #101 from appleboy/p12
fixed #90 Support load p12 format of certificate file.
This commit is contained in:
commit
06ae84a1a0
|
@ -45,6 +45,7 @@ A push notification server using [Gin](https://github.com/gin-gonic/gin) framewo
|
||||||
* Support `/api/stat/app` show notification success and failure counts.
|
* Support `/api/stat/app` show notification success and failure counts.
|
||||||
* Support `/api/config` show your [YAML](https://en.wikipedia.org/wiki/YAML) config.
|
* Support `/api/config` show your [YAML](https://en.wikipedia.org/wiki/YAML) config.
|
||||||
* Support store app stat to memory, [Redis](http://redis.io/) or [BoltDB](https://github.com/boltdb/bolt).
|
* Support store app stat to memory, [Redis](http://redis.io/) or [BoltDB](https://github.com/boltdb/bolt).
|
||||||
|
* Support `p12` or `pem` formtat of iOS certificate file.
|
||||||
|
|
||||||
See the [YAML config example](config/config.yml):
|
See the [YAML config example](config/config.yml):
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ android:
|
||||||
|
|
||||||
ios:
|
ios:
|
||||||
enabled: false
|
enabled: false
|
||||||
pem_path: "key.pem"
|
key_path: "key.pem"
|
||||||
password: "" # certificate password, default as empty string.
|
password: "" # certificate password, default as empty string.
|
||||||
production: false
|
production: false
|
||||||
|
|
||||||
|
@ -113,13 +114,13 @@ Server Options:
|
||||||
-m, --message <message> Notification message
|
-m, --message <message> Notification message
|
||||||
-t, --token <token> Notification token
|
-t, --token <token> Notification token
|
||||||
iOS Options:
|
iOS Options:
|
||||||
-i, --pem <file> certificate key file path
|
-i, --key <file> certificate key file path
|
||||||
-P, --password <password> certificate key password
|
-P, --password <password> certificate key password
|
||||||
--topic <topic> iOS topic
|
--topic <topic> iOS topic
|
||||||
--ios enabled iOS (default: false)
|
--ios enabled iOS (default: false)
|
||||||
--production iOS production mode (default: false)
|
--production iOS production mode (default: false)
|
||||||
Android Options:
|
Android Options:
|
||||||
-k, --key <api_key> Android API Key
|
-k, --apikey <api_key> Android API Key
|
||||||
--android enabled android (default: false)
|
--android enabled android (default: false)
|
||||||
Common Options:
|
Common Options:
|
||||||
-h, --help Show this message
|
-h, --help Show this message
|
||||||
|
@ -147,7 +148,7 @@ $ gorush -ios -m="your message" -i="your certificate path" -t="device token" -to
|
||||||
```
|
```
|
||||||
|
|
||||||
* `-m`: Notification message.
|
* `-m`: Notification message.
|
||||||
* `-i`: Apple Push Notification Certificate path (`pem` file).
|
* `-i`: Apple Push Notification Certificate path (`pem` or `p12` file).
|
||||||
* `-t`: Device token.
|
* `-t`: Device token.
|
||||||
* `-topic`: The topic of the remote notification.
|
* `-topic`: The topic of the remote notification.
|
||||||
* `-password`: The certificate password.
|
* `-password`: The certificate password.
|
||||||
|
|
|
@ -45,7 +45,7 @@ type SectionAndroid struct {
|
||||||
// SectionIos is sub seciont of config.
|
// SectionIos is sub seciont of config.
|
||||||
type SectionIos struct {
|
type SectionIos struct {
|
||||||
Enabled bool `yaml:"enabled"`
|
Enabled bool `yaml:"enabled"`
|
||||||
PemPath string `yaml:"pem_path"`
|
KeyPath string `yaml:"key_path"`
|
||||||
Password string `yaml:"password"`
|
Password string `yaml:"password"`
|
||||||
Production bool `yaml:"production"`
|
Production bool `yaml:"production"`
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ func BuildDefaultPushConf() ConfYaml {
|
||||||
|
|
||||||
// iOS
|
// iOS
|
||||||
conf.Ios.Enabled = false
|
conf.Ios.Enabled = false
|
||||||
conf.Ios.PemPath = "key.pem"
|
conf.Ios.KeyPath = "key.pem"
|
||||||
conf.Ios.Password = ""
|
conf.Ios.Password = ""
|
||||||
conf.Ios.Production = false
|
conf.Ios.Production = false
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ android:
|
||||||
|
|
||||||
ios:
|
ios:
|
||||||
enabled: false
|
enabled: false
|
||||||
pem_path: "key.pem"
|
key_path: "key.pem"
|
||||||
password: ""
|
password: ""
|
||||||
production: false
|
production: false
|
||||||
|
|
||||||
|
|
14
gorush.go
14
gorush.go
|
@ -30,13 +30,13 @@ Server Options:
|
||||||
-m, --message <message> Notification message
|
-m, --message <message> Notification message
|
||||||
-t, --token <token> Notification token
|
-t, --token <token> Notification token
|
||||||
iOS Options:
|
iOS Options:
|
||||||
-i, --pem <file> certificate key file path
|
-i, --key <file> certificate key file path
|
||||||
-P, --password <password> certificate key password
|
-P, --password <password> certificate key password
|
||||||
--topic <topic> iOS topic
|
--topic <topic> iOS topic
|
||||||
--ios enabled iOS (default: false)
|
--ios enabled iOS (default: false)
|
||||||
--production iOS production mode (default: false)
|
--production iOS production mode (default: false)
|
||||||
Android Options:
|
Android Options:
|
||||||
-k, --key <api_key> Android API Key
|
-k, --apikey <api_key> Android API Key
|
||||||
--android enabled android (default: false)
|
--android enabled android (default: false)
|
||||||
Common Options:
|
Common Options:
|
||||||
-h, --help Show this message
|
-h, --help Show this message
|
||||||
|
@ -62,12 +62,12 @@ func main() {
|
||||||
flag.BoolVar(&showVersion, "v", false, "Print version information.")
|
flag.BoolVar(&showVersion, "v", false, "Print version information.")
|
||||||
flag.StringVar(&configFile, "c", "", "Configuration file.")
|
flag.StringVar(&configFile, "c", "", "Configuration file.")
|
||||||
flag.StringVar(&configFile, "config", "", "Configuration file.")
|
flag.StringVar(&configFile, "config", "", "Configuration file.")
|
||||||
flag.StringVar(&opts.Ios.PemPath, "i", "", "iOS certificate key file path")
|
flag.StringVar(&opts.Ios.KeyPath, "i", "", "iOS certificate key file path")
|
||||||
flag.StringVar(&opts.Ios.PemPath, "pem", "", "iOS certificate key file path")
|
flag.StringVar(&opts.Ios.KeyPath, "key", "", "iOS certificate key file path")
|
||||||
flag.StringVar(&opts.Ios.Password, "P", "", "iOS certificate password for gorush")
|
flag.StringVar(&opts.Ios.Password, "P", "", "iOS certificate password for gorush")
|
||||||
flag.StringVar(&opts.Ios.Password, "password", "", "iOS certificate password for gorush")
|
flag.StringVar(&opts.Ios.Password, "password", "", "iOS certificate password for gorush")
|
||||||
flag.StringVar(&opts.Android.APIKey, "k", "", "Android api key configuration for gorush")
|
flag.StringVar(&opts.Android.APIKey, "k", "", "Android api key configuration for gorush")
|
||||||
flag.StringVar(&opts.Android.APIKey, "key", "", "Android api key configuration for gorush")
|
flag.StringVar(&opts.Android.APIKey, "apikey", "", "Android api key configuration for gorush")
|
||||||
flag.StringVar(&opts.Core.Port, "p", "", "port number for gorush")
|
flag.StringVar(&opts.Core.Port, "p", "", "port number for gorush")
|
||||||
flag.StringVar(&opts.Core.Port, "port", "", "port number for gorush")
|
flag.StringVar(&opts.Core.Port, "port", "", "port number for gorush")
|
||||||
flag.StringVar(&token, "t", "", "token string")
|
flag.StringVar(&token, "t", "", "token string")
|
||||||
|
@ -110,8 +110,8 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Ios.PemPath != "" {
|
if opts.Ios.KeyPath != "" {
|
||||||
gorush.PushConf.Ios.PemPath = opts.Ios.PemPath
|
gorush.PushConf.Ios.KeyPath = opts.Ios.KeyPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Ios.Password != "" {
|
if opts.Ios.Password != "" {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
apns "github.com/sideshow/apns2"
|
apns "github.com/sideshow/apns2"
|
||||||
"github.com/sideshow/apns2/certificate"
|
"github.com/sideshow/apns2/certificate"
|
||||||
"github.com/sideshow/apns2/payload"
|
"github.com/sideshow/apns2/payload"
|
||||||
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ func CheckPushConf() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if PushConf.Ios.Enabled {
|
if PushConf.Ios.Enabled {
|
||||||
if PushConf.Ios.PemPath == "" {
|
if PushConf.Ios.KeyPath == "" {
|
||||||
return errors.New("Missing iOS certificate path")
|
return errors.New("Missing iOS certificate path")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,8 +141,18 @@ func CheckPushConf() error {
|
||||||
func InitAPNSClient() error {
|
func InitAPNSClient() error {
|
||||||
if PushConf.Ios.Enabled {
|
if PushConf.Ios.Enabled {
|
||||||
var err error
|
var err error
|
||||||
|
ext := filepath.Ext(PushConf.Ios.KeyPath)
|
||||||
|
|
||||||
CertificatePemIos, err = certificate.FromPemFile(PushConf.Ios.PemPath, PushConf.Ios.Password)
|
LogAccess.Debug("certificate ext is ", ext)
|
||||||
|
|
||||||
|
switch ext {
|
||||||
|
case ".p12":
|
||||||
|
CertificatePemIos, err = certificate.FromP12File(PushConf.Ios.KeyPath, PushConf.Ios.Password)
|
||||||
|
case ".pem":
|
||||||
|
CertificatePemIos, err = certificate.FromPemFile(PushConf.Ios.KeyPath, PushConf.Ios.Password)
|
||||||
|
default:
|
||||||
|
err = errors.New("Wrong Certificate key extension.")
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError.Error("Cert Error:", err.Error())
|
LogError.Error("Cert Error:", err.Error())
|
||||||
|
|
|
@ -26,7 +26,7 @@ func TestMissingIOSCertificate(t *testing.T) {
|
||||||
PushConf = config.BuildDefaultPushConf()
|
PushConf = config.BuildDefaultPushConf()
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemPath = ""
|
PushConf.Ios.KeyPath = ""
|
||||||
|
|
||||||
err := CheckPushConf()
|
err := CheckPushConf()
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ func TestCorrectConf(t *testing.T) {
|
||||||
PushConf.Android.APIKey = "xxxxx"
|
PushConf.Android.APIKey = "xxxxx"
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemPath = "xxxxx"
|
PushConf.Ios.KeyPath = "xxxxx"
|
||||||
|
|
||||||
err := CheckPushConf()
|
err := CheckPushConf()
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ func TestPushToIOS(t *testing.T) {
|
||||||
PushConf = config.BuildDefaultPushConf()
|
PushConf = config.BuildDefaultPushConf()
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemPath = "../certificate/certificate-valid.pem"
|
PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||||
InitAPNSClient()
|
InitAPNSClient()
|
||||||
InitAppStatus()
|
InitAppStatus()
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ func TestSenMultipleNotifications(t *testing.T) {
|
||||||
InitWorkers(2, 2)
|
InitWorkers(2, 2)
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemPath = "../certificate/certificate-valid.pem"
|
PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||||
InitAPNSClient()
|
InitAPNSClient()
|
||||||
|
|
||||||
PushConf.Android.Enabled = true
|
PushConf.Android.Enabled = true
|
||||||
|
@ -365,7 +365,7 @@ func TestDisabledAndroidNotifications(t *testing.T) {
|
||||||
PushConf = config.BuildDefaultPushConf()
|
PushConf = config.BuildDefaultPushConf()
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemPath = "../certificate/certificate-valid.pem"
|
PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||||
InitAPNSClient()
|
InitAPNSClient()
|
||||||
|
|
||||||
PushConf.Android.Enabled = false
|
PushConf.Android.Enabled = false
|
||||||
|
@ -398,7 +398,7 @@ func TestDisabledIosNotifications(t *testing.T) {
|
||||||
PushConf = config.BuildDefaultPushConf()
|
PushConf = config.BuildDefaultPushConf()
|
||||||
|
|
||||||
PushConf.Ios.Enabled = false
|
PushConf.Ios.Enabled = false
|
||||||
PushConf.Ios.PemPath = "../certificate/certificate-valid.pem"
|
PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||||
InitAPNSClient()
|
InitAPNSClient()
|
||||||
|
|
||||||
PushConf.Android.Enabled = true
|
PushConf.Android.Enabled = true
|
||||||
|
@ -427,21 +427,22 @@ func TestDisabledIosNotifications(t *testing.T) {
|
||||||
assert.Equal(t, 2, count)
|
assert.Equal(t, 2, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMissingIosCertificate(t *testing.T) {
|
func TestWrongIosCertificateExt(t *testing.T) {
|
||||||
PushConf = config.BuildDefaultPushConf()
|
PushConf = config.BuildDefaultPushConf()
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemPath = "test"
|
PushConf.Ios.KeyPath = "test"
|
||||||
err := InitAPNSClient()
|
err := InitAPNSClient()
|
||||||
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "Wrong Certificate key extension.", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPNSClientDevHost(t *testing.T) {
|
func TestAPNSClientDevHost(t *testing.T) {
|
||||||
PushConf = config.BuildDefaultPushConf()
|
PushConf = config.BuildDefaultPushConf()
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemPath = "../certificate/certificate-valid.pem"
|
PushConf.Ios.KeyPath = "../certificate/certificate-valid.p12"
|
||||||
InitAPNSClient()
|
InitAPNSClient()
|
||||||
|
|
||||||
assert.Equal(t, apns2.HostDevelopment, ApnsClient.Host)
|
assert.Equal(t, apns2.HostDevelopment, ApnsClient.Host)
|
||||||
|
@ -452,7 +453,7 @@ func TestAPNSClientProdHost(t *testing.T) {
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.Production = true
|
PushConf.Ios.Production = true
|
||||||
PushConf.Ios.PemPath = "../certificate/certificate-valid.pem"
|
PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||||
InitAPNSClient()
|
InitAPNSClient()
|
||||||
|
|
||||||
assert.Equal(t, apns2.HostProduction, ApnsClient.Host)
|
assert.Equal(t, apns2.HostProduction, ApnsClient.Host)
|
||||||
|
|
Loading…
Reference in New Issue