Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added files to support custom URL scheme for application registration…

…; README updated with instructions
  • Loading branch information...
commit 1d9c1ec6d11fa71f3a05af9b4f64c4e0827421d4 1 parent 2edd097
authored
133  README
@@ -5,10 +5,11 @@ TABLE OF CONTENTS
5 5
 =================
6 6
 
7 7
 1. DESCRIPTION
8  
-2. USAGE
9  
-3. GENERATING KEYS
10  
-4. LICENCE
11  
-5. CREDITS
  8
+2. FEATURES
  9
+3. USAGE
  10
+4. GENERATING KEYS
  11
+5. LICENCE
  12
+6. CREDITS
12 13
 
13 14
 1. DESCRIPTION
14 15
 ==============
@@ -33,12 +34,28 @@ One of the advantages of DSA is that for a given registration name, each
33 34
 generated code is different, as there is a random element introduced during
34 35
 the process.
35 36
 
  37
+2. FEATURES
  38
+===========
  39
+
  40
+(to be written)
  41
+
  42
+3. USAGE
  43
+========
  44
+
  45
+The best way to get the latest version of the code is to clone the main Git
  46
+repository:
  47
+
  48
+git://github.com/gbd/cocoafob.git
  49
+
  50
+You can also download the latest version from the CocoaFob home page at
  51
+<http://github.com/gbd/cocoafob/>.
  52
+
36 53
 Providing a Registration Source String
37 54
 --------------------------------------
38 55
 
39 56
 To register an application that uses CocoaFob, it is necessary to provide a
40 57
 string of source information, which may be as simple as a registration name
41  
-and arbitrarily complex in case your application is processing the included
  58
+or arbitrarily complex in case your application is processing the included
42 59
 information in a user-friendly way. For example, as suggested in the sample
43 60
 implementation of Potion Store licence generator, a source string may contain
44 61
 application name, user name and number of copies:
@@ -49,8 +66,8 @@ When sending registration mail, you need to provide both the source string and
49 66
 the registration code. Potion Store does this for you. However, small
50 67
 modifications are needed to make automatic activation work.
51 68
 
52  
-Automatic Activation
53  
---------------------
  69
+Generating automatic activation URLs
  70
+------------------------------------
54 71
 
55 72
 Potion Store supports automatic activation of an installed application by
56 73
 clicking on a special link in a registration email or on the Thank You store
@@ -61,35 +78,97 @@ page. For this to work, you need to:
61 78
 - modify Potion Store so that automatic activation link contains not only
62 79
   registration code, but registration source string as well.
63 80
 
64  
-<more info coming>
  81
+The stock implementation of Potion Store registration code support assumes a
  82
+registration code is all that is needed to register an application. However,
  83
+CocoaFob needs to know both registration name and registration code in order
  84
+to verify the licence. This means when Potion Store generates an automatic
  85
+registration URL for your application, it needs to include registration source
  86
+string in it. One of the possible solutions is as follows:
65 87
 
66  
-2. USAGE
67  
-========
  88
+- In the file app/models/line_item.rb, add the following line at the top:
  89
+
  90
+    require base64
  91
+
  92
+- In the same file find function called license_url--it's near the bottom of
  93
+  the file. Replace it with the following (or modify to your heart's content):
  94
+
  95
+    def license_url
  96
+      licensee_name_b64 = Base64.encode64(self.order.licensee_name)
  97
+      return "#{self.product.license_url_scheme}://#{licensee_name_b64}/#{self.license_key}" rescue nil
  98
+    end
  99
+
  100
+This will make generated registration codes to contain base64-encoded licensee
  101
+name. When your application is opened by clicking on the registration link, it
  102
+will parse the code, extract the registration name and use it to verify the
  103
+licence.
68 104
 
69  
-<to be written>
  105
+Supporting registration URL schema in your app
  106
+----------------------------------------------
70 107
 
71  
-3. GENERATING KEYS
  108
+The following files in objc directory provide a sample implementation of
  109
+support for custom URL schema for application registration. The code is almost
  110
+literally taken from [3].
  111
+
  112
+To support registration URLs in your application:
  113
+
  114
+- Add files MyApp.scriptSuite and MyApp.scriptTerminology to your project's
  115
+  resources, adjusting strings inside appropriately.
  116
+
  117
+- Add the following to your application's Info.plist file under /plist/dict
  118
+  key (replace mycompany and myapp with strings appropriate for your company
  119
+  and application):
  120
+
  121
+    <key>NSAppleScriptEnabled</key>
  122
+    <string>YES</string>
  123
+    <key>CFBundleURLTypes</key>
  124
+    <array>
  125
+        <dict>
  126
+            <key>CFBundleURLSchemes</key>
  127
+            <array>
  128
+                <string>com.mycompany.myapp.lic</string>
  129
+            </array>
  130
+        </dict>
  131
+    </array>
  132
+
  133
+- Add the files URLCommand.h and URLCommand.m to your project, paying
  134
+  attention to the TODO: comments in them. Specifically, you may want to save
  135
+  registration information to your application's preferences, and also
  136
+  broadcast a notification of a changed registration information after
  137
+  verifying the supplied registration URL.
  138
+
  139
+- Be sure the URL scheme name in the Info.plist file (com.mycompany.myapp.lic)
  140
+  is the same as the one in the database generation script for Potion Store.
  141
+  It is the file db/migrate/001_create_tables.rb, and the variable is called
  142
+  license_url_scheme.
  143
+
  144
+Test the URL schema support by making a test purchase which results in displaying an activation link, and clicking on it. If you are running your application in debugger, place a breakpoint in the 
  145
+
  146
+4. GENERATING KEYS
72 147
 ==================
73 148
 
74  
-NOTE: Included keys are for demonstration and testing purposes only. DO NOT
75  
-USE THE INCLUDE KEYS IN YOUR SOFTWARE. Before incorporating CocoaFob into your
76  
-application, you need to generate a pair of your own DSA keys. I used key
77  
-length of 512 bit which I thought was enough for the registration code
78  
-generation purposes.
  149
+IMPORTANT NOTE: Included keys are for demonstration and testing purposes only.
  150
+DO NOT USE THE INCLUDE KEYS IN YOUR SOFTWARE. Before incorporating CocoaFob
  151
+into your application, you need to generate a pair of your own DSA keys. I
  152
+used key length of 512 bit which I thought was enough for the registration
  153
+code generation purposes.
  154
+
  155
+(0) Make sure OpenSSL is installed. (If you're using Mac OS X, it is.)
79 156
 
80 157
 (1) Generate DSA parameters:
81 158
 
82  
-openssl dsaparam -out dsaparam.pem 512
  159
+    openssl dsaparam -out dsaparam.pem 512
83 160
 
84 161
 (2) Generate an unencrypted DSA private key:
85 162
 
86  
-openssl gendsa -out privkey.pem dsaparam.pem
  163
+    openssl gendsa -out privkey.pem dsaparam.pem
87 164
 
88 165
 (3) Extract public key from private key:
89 166
 
90  
-openssl dsa -in privkey.pem -pubout -out pubkey.pem
  167
+    openssl dsa -in privkey.pem -pubout -out pubkey.pem
91 168
 
92  
-4. LICENCE
  169
+See [2] for more information.
  170
+
  171
+5. LICENCE
93 172
 ==========
94 173
 
95 174
 CocoaFob is Copyright (C) 2009 PixelEspresso
@@ -100,11 +179,17 @@ CocoaFob is distributed under Creative Commons Attribution 3.0 License
100 179
 <http://creativecommons.org/licenses/by/3.0/>. Attribution may take form of a
101 180
 mention in your application About box or other documentation.
102 181
 
103  
-5. CREDITS
  182
+6. CREDITS
104 183
 ==========
105 184
 
106  
-Base32 implementation is Copyright (C) 2007 by Samuel Tesla and comes from
  185
+[1] Base32 implementation is Copyright (C) 2007 by Samuel Tesla and comes from
107 186
 Ruby base32 gem: <http://rubyforge.org/projects/base32/>. Samuel Tesla's blog
108 187
 is at <http://blog.alieniloquent.com/tag/base32/>.
109 188
 
110  
-OpenSSL key generation HOWTO: <http://www.openssl.org/docs/HOWTO/keys.txt>
  189
+[2] OpenSSL key generation HOWTO: <http://www.openssl.org/docs/HOWTO/keys.txt>
  190
+
  191
+[3] Handling URL schemes in Cocoa: a blog post by Kimbro Staken
  192
+<http://www.xmldatabases.org/WK/blog/1154?t=item>
  193
+
  194
+[4] Registering a protocol handler for an App: a post on CocoaBuilder mailing
  195
+list, <http://www.cocoabuilder.com/archive/message/cocoa/2009/2/2/229297>
12  objc/MyApp.scriptSuite
... ...
@@ -0,0 +1,12 @@
  1
+// Decloner.scriptSuite:
  2
+{
  3
+    Name = Decloner;
  4
+    AppleEventCode = "DeCl";
  5
+    Commands = {
  6
+        "GetURL" = {
  7
+            CommandClass = DCDeclonerCommand;
  8
+            AppleEventCode = GURL;
  9
+            AppleEventClassCode = GURL;
  10
+         };
  11
+    };
  12
+}
11  objc/MyApp.scriptTerminology
... ...
@@ -0,0 +1,11 @@
  1
+// Decloner.scriptTerminology:
  2
+{  
  3
+    Name = "Decloner commands";
  4
+    Description = "Commands to handle a URL";
  5
+    Commands = {
  6
+        "GetURL" = {
  7
+            "Name" = "get URL";
  8
+            "Description" = "Open a URL";
  9
+        };
  10
+    };    
  11
+}
22  objc/URLCommand.h
... ...
@@ -0,0 +1,22 @@
  1
+//
  2
+//  CocoaFob
  3
+//
  4
+//  URLCommand.h
  5
+//
  6
+//  Support for custom URL scheme for app registration
  7
+//
  8
+//  Created by Gleb Dolgich on 20/03/2009.
  9
+//  Follow me on Twitter @gbd
  10
+//  Copyright (C) 2009 PixelEspresso. All rights reserved.
  11
+//  Licensed under CC Attribution License 3.0 <http://creativecommons.org/licenses/by/3.0/>
  12
+//
  13
+//  Based on "Handling URL schemes in Cocoa", a blog post by Kimbro Staken
  14
+//  <http://www.xmldatabases.org/WK/blog/1154?t=item>
  15
+//
  16
+
  17
+#import <Foundation/Foundation.h>
  18
+
  19
+@interface URLCommand : NSScriptCommand {
  20
+}
  21
+
  22
+@end
61  objc/URLCommand.m
... ...
@@ -0,0 +1,61 @@
  1
+//
  2
+//  CocoaFob
  3
+//
  4
+//  URLCommand.h
  5
+//
  6
+//  Support for custom URL scheme for app registration.
  7
+//  Pay attention to the TODO: comments below.
  8
+//
  9
+//  Created by Gleb Dolgich on 20/03/2009.
  10
+//  Follow me on Twitter @gbd
  11
+//  Copyright (C) 2009 PixelEspresso. All rights reserved.
  12
+//  Licensed under CC Attribution License 3.0 <http://creativecommons.org/licenses/by/3.0/>
  13
+//
  14
+//  Based on "Handling URL schemes in Cocoa", a blog post by Kimbro Staken
  15
+//  <http://www.xmldatabases.org/WK/blog/1154?t=item>
  16
+//
  17
+
  18
+#import "URLCommand.h"
  19
+#import "NSString+PECrypt.h"
  20
+
  21
+@interface URLCommand ()
  22
+
  23
+- (id)performWithURL:(NSString *)url;
  24
+
  25
+@end
  26
+
  27
+
  28
+@implementation URLCommand
  29
+
  30
+- (id)performDefaultImplementation {
  31
+	NSString *url = [self directParameter];
  32
+	NSLog(@"URL = %@", url);
  33
+	return [self performWithURL:url];
  34
+}
  35
+
  36
+- (id)performWithURL:(NSString *)url {
  37
+	// URL has the following format:
  38
+	// com.mycompany.myapp.lic://<base64-encoded-username>/<serial-number>
  39
+	NSArray *protocolAndTheRest = [url componentsSeparatedByString:@"://"];
  40
+	if ([protocolAndTheRest count] != 2) {
  41
+		NSLog(@"License URL is invalid (no protocol)");
  42
+		return nil;
  43
+	}
  44
+	// Separate user name and serial number
  45
+	NSArray *userNameAndSerialNumber = [[protocolAndTheRest objectAtIndex:1] componentsSeparatedByString:@"/"];
  46
+	if ([userNameAndSerialNumber count] != 2) {
  47
+		NSLog(@"License URL is invalid (missing parts)");
  48
+		return nil;
  49
+	}
  50
+	// Decode base64-encoded user name
  51
+	NSString *usernameb64 = (NSString *)[userNameAndSerialNumber objectAtIndex:0];
  52
+	NSString *username = [usernameb64 base64Decode];
  53
+	NSLog(@"User name: %@", username);
  54
+	NSString *serial = (NSString *)[userNameAndSerialNumber objectAtIndex:1];
  55
+	NSLog(@"Serial: %@", serial);
  56
+	// TODO: Save registration to preferences.
  57
+	// TODO: Broadcast notification of a changed registration information.
  58
+	return nil;
  59
+}
  60
+
  61
+@end

0 notes on commit 1d9c1ec

Please sign in to comment.
Something went wrong with that request. Please try again.