diff --git a/README.md b/README.md index 9d31f28..7e9e530 100644 --- a/README.md +++ b/README.md @@ -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/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 `p12` or `pem` formtat of iOS certificate file. See the [YAML config example](config/config.yml): @@ -71,7 +72,7 @@ android: ios: enabled: false - pem_path: "key.pem" + key_path: "key.pem" password: "" # certificate password, default as empty string. production: false @@ -113,13 +114,13 @@ Server Options: -m, --message Notification message -t, --token Notification token iOS Options: - -i, --pem certificate key file path + -i, --key certificate key file path -P, --password certificate key password --topic iOS topic --ios enabled iOS (default: false) --production iOS production mode (default: false) Android Options: - -k, --key Android API Key + -k, --apikey Android API Key --android enabled android (default: false) Common Options: -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. -* `-i`: Apple Push Notification Certificate path (`pem` file). +* `-i`: Apple Push Notification Certificate path (`pem` or `p12` file). * `-t`: Device token. * `-topic`: The topic of the remote notification. * `-password`: The certificate password. diff --git a/config/config.go b/config/config.go index c3d2052..f733ae7 100644 --- a/config/config.go +++ b/config/config.go @@ -45,7 +45,7 @@ type SectionAndroid struct { // SectionIos is sub seciont of config. type SectionIos struct { Enabled bool `yaml:"enabled"` - PemPath string `yaml:"pem_path"` + KeyPath string `yaml:"key_path"` Password string `yaml:"password"` Production bool `yaml:"production"` } @@ -106,7 +106,7 @@ func BuildDefaultPushConf() ConfYaml { // iOS conf.Ios.Enabled = false - conf.Ios.PemPath = "key.pem" + conf.Ios.KeyPath = "key.pem" conf.Ios.Password = "" conf.Ios.Production = false diff --git a/config/config.yml b/config/config.yml index a6387d1..2fd36a7 100644 --- a/config/config.yml +++ b/config/config.yml @@ -20,7 +20,7 @@ android: ios: enabled: false - pem_path: "key.pem" + key_path: "key.pem" password: "" production: false diff --git a/gorush.go b/gorush.go index 1aa0425..0245142 100644 --- a/gorush.go +++ b/gorush.go @@ -30,13 +30,13 @@ Server Options: -m, --message Notification message -t, --token Notification token iOS Options: - -i, --pem certificate key file path + -i, --key certificate key file path -P, --password certificate key password --topic iOS topic --ios enabled iOS (default: false) --production iOS production mode (default: false) Android Options: - -k, --key Android API Key + -k, --apikey Android API Key --android enabled android (default: false) Common Options: -h, --help Show this message @@ -62,12 +62,12 @@ func main() { flag.BoolVar(&showVersion, "v", false, "Print version information.") flag.StringVar(&configFile, "c", "", "Configuration file.") flag.StringVar(&configFile, "config", "", "Configuration file.") - flag.StringVar(&opts.Ios.PemPath, "i", "", "iOS certificate key file path") - flag.StringVar(&opts.Ios.PemPath, "pem", "", "iOS certificate key file path") + flag.StringVar(&opts.Ios.KeyPath, "i", "", "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, "password", "", "iOS certificate password 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, "port", "", "port number for gorush") flag.StringVar(&token, "t", "", "token string") @@ -110,8 +110,8 @@ func main() { } } - if opts.Ios.PemPath != "" { - gorush.PushConf.Ios.PemPath = opts.Ios.PemPath + if opts.Ios.KeyPath != "" { + gorush.PushConf.Ios.KeyPath = opts.Ios.KeyPath } if opts.Ios.Password != "" { diff --git a/gorush/notification.go b/gorush/notification.go index ef9a463..7ea6407 100644 --- a/gorush/notification.go +++ b/gorush/notification.go @@ -7,6 +7,7 @@ import ( apns "github.com/sideshow/apns2" "github.com/sideshow/apns2/certificate" "github.com/sideshow/apns2/payload" + "path/filepath" "time" ) @@ -122,7 +123,7 @@ func CheckPushConf() error { } if PushConf.Ios.Enabled { - if PushConf.Ios.PemPath == "" { + if PushConf.Ios.KeyPath == "" { return errors.New("Missing iOS certificate path") } } @@ -140,8 +141,18 @@ func CheckPushConf() error { func InitAPNSClient() error { if PushConf.Ios.Enabled { 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 { LogError.Error("Cert Error:", err.Error()) diff --git a/gorush/notification_test.go b/gorush/notification_test.go index e6cb466..a376975 100644 --- a/gorush/notification_test.go +++ b/gorush/notification_test.go @@ -26,7 +26,7 @@ func TestMissingIOSCertificate(t *testing.T) { PushConf = config.BuildDefaultPushConf() PushConf.Ios.Enabled = true - PushConf.Ios.PemPath = "" + PushConf.Ios.KeyPath = "" err := CheckPushConf() @@ -53,7 +53,7 @@ func TestCorrectConf(t *testing.T) { PushConf.Android.APIKey = "xxxxx" PushConf.Ios.Enabled = true - PushConf.Ios.PemPath = "xxxxx" + PushConf.Ios.KeyPath = "xxxxx" err := CheckPushConf() @@ -222,7 +222,7 @@ func TestPushToIOS(t *testing.T) { PushConf = config.BuildDefaultPushConf() PushConf.Ios.Enabled = true - PushConf.Ios.PemPath = "../certificate/certificate-valid.pem" + PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem" InitAPNSClient() InitAppStatus() @@ -332,7 +332,7 @@ func TestSenMultipleNotifications(t *testing.T) { InitWorkers(2, 2) PushConf.Ios.Enabled = true - PushConf.Ios.PemPath = "../certificate/certificate-valid.pem" + PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem" InitAPNSClient() PushConf.Android.Enabled = true @@ -365,7 +365,7 @@ func TestDisabledAndroidNotifications(t *testing.T) { PushConf = config.BuildDefaultPushConf() PushConf.Ios.Enabled = true - PushConf.Ios.PemPath = "../certificate/certificate-valid.pem" + PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem" InitAPNSClient() PushConf.Android.Enabled = false @@ -398,7 +398,7 @@ func TestDisabledIosNotifications(t *testing.T) { PushConf = config.BuildDefaultPushConf() PushConf.Ios.Enabled = false - PushConf.Ios.PemPath = "../certificate/certificate-valid.pem" + PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem" InitAPNSClient() PushConf.Android.Enabled = true @@ -427,21 +427,22 @@ func TestDisabledIosNotifications(t *testing.T) { assert.Equal(t, 2, count) } -func TestMissingIosCertificate(t *testing.T) { +func TestWrongIosCertificateExt(t *testing.T) { PushConf = config.BuildDefaultPushConf() PushConf.Ios.Enabled = true - PushConf.Ios.PemPath = "test" + PushConf.Ios.KeyPath = "test" err := InitAPNSClient() assert.Error(t, err) + assert.Equal(t, "Wrong Certificate key extension.", err.Error()) } func TestAPNSClientDevHost(t *testing.T) { PushConf = config.BuildDefaultPushConf() PushConf.Ios.Enabled = true - PushConf.Ios.PemPath = "../certificate/certificate-valid.pem" + PushConf.Ios.KeyPath = "../certificate/certificate-valid.p12" InitAPNSClient() assert.Equal(t, apns2.HostDevelopment, ApnsClient.Host) @@ -452,7 +453,7 @@ func TestAPNSClientProdHost(t *testing.T) { PushConf.Ios.Enabled = true PushConf.Ios.Production = true - PushConf.Ios.PemPath = "../certificate/certificate-valid.pem" + PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem" InitAPNSClient() assert.Equal(t, apns2.HostProduction, ApnsClient.Host)