├── package.cmd
├── packages
├── JWT.1.3.1
│ └── lib
│ │ └── 3.5
│ │ └── JWT.dll
└── repositories.config
├── FirebaseTokenGenerator
├── packages.config
├── TokenOptions.cs
├── Properties
│ └── AssemblyInfo.cs
├── FirebaseTokenGenerator.csproj
└── TokenGenerator.cs
├── .gitattributes
├── FirebaseTokenGenerator.nuspec
├── LICENSE
├── FirebaseTokenGenerator.Tests
├── Properties
│ └── AssemblyInfo.cs
├── FirebaseTokenGenerator.Tests.csproj
└── BasicUnitTest.cs
├── FirebaseTokenGenerator.sln
├── .gitignore
└── README.md
/package.cmd:
--------------------------------------------------------------------------------
1 | nuget update -self
2 | nuget pack FirebaseTokenGenerator\FirebaseTokenGenerator.csproj
3 |
--------------------------------------------------------------------------------
/packages/JWT.1.3.1/lib/3.5/JWT.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googlearchive/firebase-token-generator-dotNet/HEAD/packages/JWT.1.3.1/lib/3.5/JWT.dll
--------------------------------------------------------------------------------
/packages/repositories.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | FirebaseTokenGenerator
5 | $version$
6 | Firebase Token Generator
7 | $author$
8 | $author$
9 | http://firebase.mit-license.org/
10 | https://github.com/firebase/firebase-token-generator-dotNet
11 | false
12 | $description$
13 | Copyright 2014
14 | firebase token jwt security authentication
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2014 Firebase
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator/TokenOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace Firebase
7 | {
8 | public class TokenOptions
9 | {
10 | public DateTime? expires { get; private set; }
11 | public DateTime? notBefore { get; private set; }
12 | public bool admin { get; private set; }
13 | public bool debug { get; private set; }
14 |
15 | ///
16 | /// Constructor. All options are optional.
17 | ///
18 | /// The date/time before which the token should not be considered valid. (default is now)
19 | /// The date/time at which the token should no longer be considered valid. (default is 24 hours from now)
20 | /// Set to true to bypass all security rules. (you can use this for trusted server code)
21 | /// Set to true to enable debug mode. (so you can see the results of Rules API operations)
22 | public TokenOptions(DateTime? notBefore = null, DateTime? expires = null, bool admin = false, bool debug = false)
23 | {
24 | this.notBefore = notBefore;
25 | this.expires = expires;
26 | this.admin = admin;
27 | this.debug = debug;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FirebaseTokenGenerator.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("FirebaseTokenGenerator.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("8e346b3e-2110-45c5-b287-3ff8d30baff1")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FirebaseTokenGenerator")]
9 | [assembly: AssemblyDescription("Firebase Token Generator for .Net")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Firebase")]
12 | [assembly: AssemblyProduct("FirebaseTokenGenerator")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("e5d72cf8-d4aa-47d4-85d3-7527260dc405")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("2.0.0.0")]
36 | [assembly: AssemblyFileVersion("2.0.0.0")]
37 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Express 2013 for Web
4 | VisualStudioVersion = 12.0.30723.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FirebaseTokenGenerator", "FirebaseTokenGenerator\FirebaseTokenGenerator.csproj", "{EDF6D0EC-8015-463C-9B3B-034EF0F897A9}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FirebaseTokenGenerator.Tests", "FirebaseTokenGenerator.Tests\FirebaseTokenGenerator.Tests.csproj", "{40A54324-D081-4C1F-8F39-F2DB4BF20166}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {EDF6D0EC-8015-463C-9B3B-034EF0F897A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {EDF6D0EC-8015-463C-9B3B-034EF0F897A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {EDF6D0EC-8015-463C-9B3B-034EF0F897A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {EDF6D0EC-8015-463C-9B3B-034EF0F897A9}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {40A54324-D081-4C1F-8F39-F2DB4BF20166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {40A54324-D081-4C1F-8F39-F2DB4BF20166}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {40A54324-D081-4C1F-8F39-F2DB4BF20166}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {40A54324-D081-4C1F-8F39-F2DB4BF20166}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator/FirebaseTokenGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Release
6 | AnyCPU
7 | {EDF6D0EC-8015-463C-9B3B-034EF0F897A9}
8 | Library
9 | Properties
10 | FirebaseTokenGenerator
11 | FirebaseTokenGenerator
12 | v3.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | False
35 | ..\packages\JWT.1.3.1\lib\3.5\JWT.dll
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
56 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 | [Dd]ebug/
46 | [Rr]elease/
47 | *_i.c
48 | *_p.c
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.vspscc
63 | .builds
64 | *.dotCover
65 |
66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
67 | #packages/
68 |
69 | # Visual C++ cache files
70 | ipch/
71 | *.aps
72 | *.ncb
73 | *.opensdf
74 | *.sdf
75 |
76 | # Visual Studio profiler
77 | *.psess
78 | *.vsp
79 |
80 | # ReSharper is a .NET coding add-in
81 | _ReSharper*
82 |
83 | # Installshield output folder
84 | [Ee]xpress
85 |
86 | # DocProject is a documentation generator add-in
87 | DocProject/buildhelp/
88 | DocProject/Help/*.HxT
89 | DocProject/Help/*.HxC
90 | DocProject/Help/*.hhc
91 | DocProject/Help/*.hhk
92 | DocProject/Help/*.hhp
93 | DocProject/Help/Html2
94 | DocProject/Help/html
95 |
96 | # Click-Once directory
97 | publish
98 |
99 | # Others
100 | [Bb]in
101 | [Oo]bj
102 | sql
103 | TestResults
104 | *.Cache
105 | ClientBin
106 | stylecop.*
107 | ~$*
108 | *.dbmdl
109 | Generated_Code #added for RIA/Silverlight projects
110 |
111 | # Backup & report files from converting an old project file to a newer
112 | # Visual Studio version. Backup files are not needed, because we have git ;-)
113 | _UpgradeReport_Files/
114 | Backup*/
115 | UpgradeLog*.XML
116 |
117 |
118 |
119 | ############
120 | ## Windows
121 | ############
122 |
123 | # Windows image file caches
124 | Thumbs.db
125 |
126 | # Folder config file
127 | Desktop.ini
128 |
129 |
130 | #############
131 | ## Python
132 | #############
133 |
134 | *.py[co]
135 |
136 | # Packages
137 | *.egg
138 | *.egg-info
139 | dist
140 | build
141 | eggs
142 | parts
143 | bin
144 | var
145 | sdist
146 | develop-eggs
147 | .installed.cfg
148 |
149 | # Installer logs
150 | pip-log.txt
151 |
152 | # Unit test / coverage reports
153 | .coverage
154 | .tox
155 |
156 | #Translations
157 | *.mo
158 |
159 | #Mr Developer
160 | .mr.developer.cfg
161 |
162 | # Mac crap
163 | .DS_Store
164 |
165 | # NuGet packages.
166 | *.nupkg
167 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Status: Archived
2 | This repository has been archived and is no longer maintained.
3 |
4 | 
5 |
6 | # Firebase Token Generator - .NET
7 |
8 | **WARNING: This token generator is compatible with versions 1.x.x and 2.x.x of the Firebase SDK. If you are using the 3.x.x SDK, please refer to the documentation [here](https://firebase.google.com/docs/auth/server#use_a_jwt_library).**
9 |
10 | [Firebase Custom Login](https://www.firebase.com/docs/web/guide/simple-login/custom.html)
11 | gives you complete control over user authentication by allowing you to authenticate users
12 | with secure JSON Web Tokens (JWTs). The auth payload stored in those tokens is available
13 | for use in your Firebase [security rules](https://www.firebase.com/docs/security/api/rule/).
14 | This is a token generator library for .Net which allows you to easily create those JWTs.
15 |
16 |
17 | ## Installation
18 |
19 | The easiest way to install The Firebase .Net token generator is via NuGet. Just search for
20 | "FirebaseTokenGenerator" in NuGet or install it via the Package Manager Console:
21 |
22 | ```
23 | PM> Install-Package FirebaseTokenGenerator
24 | ```
25 |
26 |
27 | ## A Note About Security
28 |
29 | **IMPORTANT:** Because token generation requires your Firebase Secret, you should only generate
30 | tokens on *trusted servers*. Never embed your Firebase Secret directly into your application and
31 | never share your Firebase Secret with a connected client.
32 |
33 |
34 | ## Generating Tokens
35 |
36 | To generate tokens, you'll need your Firebase Secret which you can find by entering your Firebase
37 | URL into a browser and clicking the "Secrets" tab on the left-hand navigation menu.
38 |
39 | Once you've downloaded the library and grabbed your Firebase Secret, you can generate a token with
40 | this snippet of .Net code:
41 |
42 | ```
43 | var tokenGenerator = new Firebase.TokenGenerator("");
44 | var authPayload = new Dictionary()
45 | {
46 | { "uid", "1" },
47 | { "some", "arbitrary" },
48 | { "data", "here" }
49 | };
50 | string token = tokenGenerator.CreateToken(authPayload);
51 | ```
52 |
53 | The payload object passed into `CreateToken()` is then available for use within your
54 | security rules via the [`auth` variable](https://www.firebase.com/docs/security/api/rule/auth.html).
55 | This is how you pass trusted authentication details (e.g. the client's user ID) to your
56 | Firebase rules. The payload can contain any data of your choosing, however it
57 | must contain a "uid" key, which must be a string of less than 256 characters. The
58 | generated token must be less than 1024 characters in total.
59 |
60 |
61 | ## Token Options
62 |
63 | A second `options` argument can be passed to `CreateToken()` to modify how Firebase treats the
64 | token. Available options are:
65 |
66 | * **expires** (DateTime) - A timestamp denoting the time after which this token should no longer
67 | be valid.
68 |
69 | * **notBefore** (DateTime) - A timestamp denoting the time before which this token should be
70 | rejected by the server.
71 |
72 | * **admin** (bool) - Set to `true` if you want to disable all security rules for this client. This
73 | will provide the client with read and write access to your entire Firebase.
74 |
75 | * **debug** (bool) - Set to `true` to enable debug output from your security rules. You should
76 | generally *not* leave this set to `true` in production (as it slows down the rules implementation
77 | and gives your users visibility into your rules), but it can be helpful for debugging.
78 |
79 | Here is an example of how to use the second `options` argument:
80 |
81 | ```
82 | var tokenGenerator = new Firebase.TokenGenerator("");
83 | var authPayload = new Dictionary()
84 | {
85 | { "uid", "1" },
86 | { "some", "arbitrary" },
87 | { "data", "here" }
88 | };
89 | string token = tokenGenerator.CreateToken(authPayload, new Firebase.TokenOptions(admin: true));
90 | ```
91 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator/TokenGenerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Firebase
7 | {
8 | ///
9 | /// Generates firebase auth tokens for your firebase.
10 | ///
11 | public class TokenGenerator
12 | {
13 | private static int TOKEN_VERSION = 0;
14 | private string _firebaseSecret;
15 |
16 | ///
17 | /// Constructor.
18 | ///
19 | /// The Firebase Secret for your firebase (can be found by entering your Firebase URL into a web browser, and clicking the "Auth" pane).
20 | public TokenGenerator(string firebaseSecret)
21 | {
22 | _firebaseSecret = firebaseSecret;
23 | }
24 |
25 | ///
26 | /// Creates an authentication token containing arbitrary auth data.
27 | ///
28 | /// Arbitrary data that will be passed to the Firebase Rules API, once a client authenticates. Must be able to be serialized to JSON with .
29 | /// The auth token.
30 | public string CreateToken(Dictionary data)
31 | {
32 | return CreateToken(data, new TokenOptions());
33 | }
34 |
35 | ///
36 | /// Creates an authentication token containing arbitrary auth data and the specified options.
37 | ///
38 | /// Arbitrary data that will be passed to the Firebase Rules API, once a client authenticates. Must be able to be serialized to JSON with .
39 | /// A set of custom options for the token.
40 | /// The auth token.
41 | public string CreateToken(Dictionary data, TokenOptions options)
42 | {
43 | var dataEmpty = (data == null || data.Count == 0);
44 | if (dataEmpty && (options == null || (!options.admin && !options.debug)))
45 | {
46 | throw new Exception("data is empty and no options are set. This token will have no effect on Firebase.");
47 | }
48 |
49 | var claims = new Dictionary();
50 | claims["v"] = TOKEN_VERSION;
51 | claims["iat"] = secondsSinceEpoch(DateTime.Now);
52 |
53 | var isAdminToken = (options != null && options.admin);
54 | validateToken(data, isAdminToken);
55 |
56 | if (!dataEmpty)
57 | {
58 | claims["d"] = data;
59 | }
60 |
61 | // Handle options.
62 | if (options != null)
63 | {
64 | if (options.expires.HasValue)
65 | claims["exp"] = secondsSinceEpoch(options.expires.Value);
66 | if (options.notBefore.HasValue)
67 | claims["nbf"] = secondsSinceEpoch(options.notBefore.Value);
68 | if (options.admin)
69 | claims["admin"] = true;
70 | if (options.debug)
71 | claims["debug"] = true;
72 | }
73 |
74 | var token = computeToken(claims);
75 | if (token.Length > 1024)
76 | {
77 | throw new Exception("Generated token is too long. The token cannot be longer than 1024 bytes.");
78 | }
79 | return token;
80 | }
81 |
82 | private string computeToken(Dictionary claims)
83 | {
84 | return JWT.JsonWebToken.Encode(claims, this._firebaseSecret, JWT.JwtHashAlgorithm.HS256);
85 | }
86 |
87 | private static long secondsSinceEpoch(DateTime dt)
88 | {
89 | TimeSpan t = dt.ToUniversalTime() - new DateTime(1970, 1, 1);
90 | return (long)t.TotalSeconds;
91 | }
92 |
93 | private static void validateToken(Dictionary data, Boolean isAdminToken)
94 | {
95 | var containsUid = (data != null && data.ContainsKey("uid"));
96 | if ((!containsUid && !isAdminToken) || (containsUid && !(data["uid"] is string)))
97 | {
98 | throw new Exception("Data payload must contain a \"uid\" key that must not be a string.");
99 | }
100 | else if (containsUid && data["uid"].ToString().Length > 256)
101 | {
102 | throw new Exception("Data payload must contain a \"uid\" key that must not be longer than 256 characters.");
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator.Tests/FirebaseTokenGenerator.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {40A54324-D081-4C1F-8F39-F2DB4BF20166}
7 | Library
8 | Properties
9 | Firebase.Tests
10 | FirebaseTokenGenerator.Tests
11 | v3.5
12 | 512
13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 10.0
15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
17 | False
18 | UnitTest
19 |
20 |
21 |
22 | true
23 | full
24 | false
25 | bin\Debug\
26 | DEBUG;TRACE
27 | prompt
28 | 4
29 |
30 |
31 | pdbonly
32 | true
33 | bin\Release\
34 | TRACE
35 | prompt
36 | 4
37 |
38 |
39 |
40 | False
41 | ..\packages\JWT.1.3.1\lib\3.5\JWT.dll
42 |
43 |
44 |
45 | 3.5
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | {edf6d0ec-8015-463c-9b3b-034ef0f897a9}
67 | FirebaseTokenGenerator
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | False
78 |
79 |
80 | False
81 |
82 |
83 | False
84 |
85 |
86 | False
87 |
88 |
89 |
90 |
91 |
92 |
93 |
100 |
--------------------------------------------------------------------------------
/FirebaseTokenGenerator.Tests/BasicUnitTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Text.RegularExpressions;
6 | using Microsoft.VisualStudio.TestTools.UnitTesting;
7 | using Firebase;
8 |
9 | namespace Firebase.Tests
10 | {
11 | [TestClass]
12 | public class BasicUnitTest
13 | {
14 | private string FIREBASE_SUPER_SECRET_KEY = "moozooherpderp";
15 |
16 | [TestMethod]
17 | [ExpectedException(typeof(Exception))]
18 | public void CheckIfBasicLength()
19 | {
20 | var payload = new Dictionary();
21 |
22 | var tokenGenerator = new TokenGenerator("x");
23 | var token = tokenGenerator.CreateToken(payload);
24 | }
25 |
26 | [TestMethod]
27 | public void CheckBasicStructureHasCorrectNumberOfFragments()
28 | {
29 | var payload = new Dictionary
30 | {
31 | { "uid", "1" },
32 | { "abc", "0123456789~!@#$%^&*()_+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?\"{}|" }
33 | };
34 |
35 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
36 | var token = tokenGenerator.CreateToken(payload);
37 |
38 | String[] tokenFragments = token.Split('.');
39 |
40 | Assert.IsTrue(tokenFragments.Length == 3, "Token has the proper number of fragments: jwt metadata, payload, and signature");
41 | }
42 |
43 | [TestMethod]
44 | public void CheckResultProperlyDoesNotHavePadding()
45 | {
46 | var payload = new Dictionary
47 | {
48 | { "uid", "1" },
49 | { "abc", "0123456789~!@#$%^&*()_+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?\"{}|" }
50 | };
51 |
52 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
53 | var token = tokenGenerator.CreateToken(payload);
54 |
55 | Assert.IsTrue(token.IndexOf('=') < 0);
56 | }
57 |
58 | [TestMethod]
59 | public void CheckIfResultIsUrlSafePlusSign()
60 | {
61 | var payload = new Dictionary
62 | {
63 | { "uid", "1" },
64 | { "abc", "0123456789~!@#$%^&*()_+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?\"{}|" }
65 | };
66 |
67 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
68 | var token = tokenGenerator.CreateToken(payload);
69 |
70 | Assert.IsTrue(token.IndexOf('+') < 0);
71 | }
72 |
73 | [TestMethod]
74 | public void CheckIfResultIsUrlSafePlusSlash()
75 | {
76 | var payload = new Dictionary
77 | {
78 | { "uid", "1" },
79 | { "abc", "0123456789~!@#$%^&*()_+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?\"{}|" }
80 | };
81 |
82 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
83 | var token = tokenGenerator.CreateToken(payload);
84 |
85 | Assert.IsTrue(token.IndexOf('/') < 0);
86 | }
87 |
88 | [TestMethod]
89 | public void CheckIfResultHasWhiteSpace()
90 | {
91 | var payload = new Dictionary
92 | {
93 | { "uid", "1" },
94 | { "a", "apple" },
95 | { "b", "banana" },
96 | { "c", "carrot" },
97 | { "number", Double.MaxValue },
98 | { "abc", "0123456789~!@#$%^&*()_+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?\"{}|" },
99 | { "herp1", "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.?" }
100 | };
101 |
102 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
103 | var token = tokenGenerator.CreateToken(payload);
104 |
105 | var pattern = new Regex(@"\s");
106 | var hasWhiteSpace = pattern.IsMatch(token);
107 |
108 | Assert.IsFalse(hasWhiteSpace, "Token has white space");
109 | }
110 |
111 | [TestMethod]
112 | public void BasicInspectTest()
113 | {
114 | var customData = "0123456789~!@#$%^&*()_+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?\"{}|";
115 | var payload = new Dictionary
116 | {
117 | { "uid", "1" },
118 | { "abc", customData }
119 | };
120 |
121 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
122 | var tokenOptions = new TokenOptions(DateTime.Now, DateTime.Now, true, true);
123 |
124 | var token = tokenGenerator.CreateToken(payload, tokenOptions);
125 | var decoded = JWT.JsonWebToken.DecodeToObject(token, FIREBASE_SUPER_SECRET_KEY) as Dictionary;
126 | Assert.IsTrue(decoded.ContainsKey("v") && (decoded["v"] is int) && (int.Parse(decoded["v"].ToString()) == 0));
127 | Assert.IsTrue(decoded.ContainsKey("d") && (decoded["d"] as Dictionary).ContainsKey("abc"));
128 | Assert.IsTrue(decoded.ContainsKey("exp") && (decoded["exp"] is int));
129 | Assert.IsTrue(decoded.ContainsKey("iat") && (decoded["iat"] is int));
130 | Assert.IsTrue(decoded.ContainsKey("nbf") && (decoded["nbf"] is int));
131 | Assert.IsTrue(decoded.ContainsKey("admin") && (decoded["admin"] is bool));
132 | Assert.IsTrue(decoded.ContainsKey("debug") && (decoded["debug"] is bool));
133 | }
134 |
135 | [TestMethod]
136 | [ExpectedException(typeof(Exception))]
137 | public void RequireUidInPayload()
138 | {
139 | var payload = new Dictionary
140 | {
141 | { "abc", "0123456789~!@#$%^&*()_+-=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./;'[]\\<>?\"{}|" }
142 | };
143 |
144 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
145 | var token = tokenGenerator.CreateToken(payload);
146 | }
147 |
148 | [TestMethod]
149 | [ExpectedException(typeof(Exception))]
150 | public void RequireUidStringInPayload()
151 | {
152 | var payload = new Dictionary
153 | {
154 | { "uid", 1 }
155 | };
156 |
157 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
158 | var token = tokenGenerator.CreateToken(payload);
159 | }
160 |
161 | [TestMethod]
162 | public void AllowMaxLengthUid()
163 | {
164 | var payload = new Dictionary
165 | {
166 | // 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 256
167 | { "uid", "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" }
168 | };
169 |
170 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
171 | var token = tokenGenerator.CreateToken(payload);
172 | }
173 |
174 | [TestMethod]
175 | [ExpectedException(typeof(Exception))]
176 | public void DisallowUidTooLong()
177 | {
178 | var payload = new Dictionary
179 | {
180 | // 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 257
181 | { "uid", "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567" }
182 | };
183 |
184 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
185 | var token = tokenGenerator.CreateToken(payload);
186 | }
187 |
188 | [TestMethod]
189 | public void AllowEmptyStringUid()
190 | {
191 | var payload = new Dictionary
192 | {
193 | { "uid", "" }
194 | };
195 |
196 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
197 | var token = tokenGenerator.CreateToken(payload);
198 | }
199 |
200 | [TestMethod]
201 | [ExpectedException(typeof(Exception))]
202 | public void DisallowTokensTooLong()
203 | {
204 | var payload = new Dictionary
205 | {
206 | { "uid", "blah" },
207 | { "longVar", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345612345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234561234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" }
208 | };
209 |
210 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
211 | var token = tokenGenerator.CreateToken(payload);
212 | }
213 |
214 | [TestMethod]
215 | public void AllowNoUidWithAdmin()
216 | {
217 | var tokenOptions = new TokenOptions(null, null, true, false);
218 |
219 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
220 | var token = tokenGenerator.CreateToken(null, tokenOptions);
221 | var payload1 = new Dictionary();
222 | var token1 = tokenGenerator.CreateToken(payload1, tokenOptions);
223 | var payload2 = new Dictionary
224 | {
225 | { "foo", "bar" }
226 | };
227 | var token2 = tokenGenerator.CreateToken(payload2, tokenOptions);
228 | }
229 |
230 | [TestMethod]
231 | [ExpectedException(typeof(Exception))]
232 | public void DisallowInvalidUidWithAdmin1()
233 | {
234 | var payload = new Dictionary
235 | {
236 | { "uid", 1 }
237 | };
238 |
239 | var tokenOptions = new TokenOptions(null, null, true, false);
240 |
241 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
242 | var token = tokenGenerator.CreateToken(payload, tokenOptions);
243 | }
244 |
245 | [TestMethod]
246 | [ExpectedException(typeof(Exception))]
247 | public void DisallowInvalidUidWithAdmin2()
248 | {
249 | var payload = new Dictionary
250 | {
251 | { "uid", null }
252 | };
253 |
254 | var tokenOptions = new TokenOptions(null, null, true, false);
255 |
256 | var tokenGenerator = new TokenGenerator(FIREBASE_SUPER_SECRET_KEY);
257 | var token = tokenGenerator.CreateToken(payload, tokenOptions);
258 | }
259 | }
260 | }
261 |
--------------------------------------------------------------------------------