1
+ using System ;
2
+ using System . Text ;
3
+ using System . Text . RegularExpressions ;
4
+ using System . Web ;
5
+ using System . Web . Mvc ;
6
+ using Umbraco . Core ;
7
+ using Umbraco . Core . Logging ;
8
+
9
+ namespace Umbraco . Web . Mvc
10
+ {
11
+ /// <summary>
12
+ /// Used for authorizing scheduled tasks
13
+ /// </summary>
14
+ public sealed class AdminTokenAuthorizeAttribute : AuthorizeAttribute
15
+ {
16
+ private readonly ApplicationContext _applicationContext ;
17
+
18
+ /// <summary>
19
+ /// THIS SHOULD BE ONLY USED FOR UNIT TESTS
20
+ /// </summary>
21
+ /// <param name="appContext"></param>
22
+ public AdminTokenAuthorizeAttribute ( ApplicationContext appContext )
23
+ {
24
+ if ( appContext == null ) throw new ArgumentNullException ( "appContext" ) ;
25
+ _applicationContext = appContext ;
26
+ }
27
+
28
+ public AdminTokenAuthorizeAttribute ( )
29
+ {
30
+ }
31
+
32
+ private ApplicationContext GetApplicationContext ( )
33
+ {
34
+ return _applicationContext ?? ApplicationContext . Current ;
35
+ }
36
+
37
+ /// <summary>
38
+ /// Used to return the value that needs to go in the Authorization header
39
+ /// </summary>
40
+ /// <param name="appContext"></param>
41
+ /// <returns></returns>
42
+ public static string GetAuthHeaderTokenVal ( ApplicationContext appContext )
43
+ {
44
+ var admin = appContext . Services . UserService . GetUserById ( 0 ) ;
45
+
46
+ var token = string . Format ( "{0}u____u{1}u____u{2}" , admin . Email , admin . Username , admin . RawPasswordValue ) ;
47
+
48
+ var encrypted = token . EncryptWithMachineKey ( ) ;
49
+ var bytes = Encoding . UTF8 . GetBytes ( encrypted ) ;
50
+ var base64 = Convert . ToBase64String ( bytes ) ;
51
+ return "AToken val=\" " + base64 + "\" " ;
52
+ }
53
+
54
+ /// <summary>
55
+ /// Ensures that the user must be in the Administrator or the Install role
56
+ /// </summary>
57
+ /// <param name="httpContext"></param>
58
+ /// <returns></returns>
59
+ protected override bool AuthorizeCore ( HttpContextBase httpContext )
60
+ {
61
+ if ( httpContext == null ) throw new ArgumentNullException ( "httpContext" ) ;
62
+
63
+ var appContext = GetApplicationContext ( ) ;
64
+
65
+ //we need to that the app is configured and that a user is logged in
66
+ if ( appContext . IsConfigured == false ) return false ;
67
+
68
+ //need the auth header
69
+ if ( httpContext . Request . Headers [ "Authorization" ] == null || httpContext . Request . Headers [ "Authorization" ] . IsNullOrWhiteSpace ( ) ) return false ;
70
+
71
+ var header = httpContext . Request . Headers [ "Authorization" ] ;
72
+ if ( header . StartsWith ( "AToken " ) == false ) return false ;
73
+
74
+ var keyVal = Regex . Matches ( header , "AToken val=(.*?)(?:$|\\ s)" ) ;
75
+ if ( keyVal . Count != 1 ) return false ;
76
+ if ( keyVal [ 0 ] . Groups . Count != 2 ) return false ;
77
+
78
+ var admin = appContext . Services . UserService . GetUserById ( 0 ) ;
79
+ if ( admin == null ) return false ;
80
+
81
+ try
82
+ {
83
+ //get the token value from the header
84
+ var val = keyVal [ 0 ] . Groups [ 1 ] . Value . Trim ( "\" " ) ;
85
+ //un-base 64 the string
86
+ var bytes = Convert . FromBase64String ( val ) ;
87
+ var encrypted = Encoding . UTF8 . GetString ( bytes ) ;
88
+ //decrypt the string
89
+ var text = encrypted . DecryptWithMachineKey ( ) ;
90
+
91
+ //split
92
+ var split = text . Split ( new [ ] { "u____u" } , StringSplitOptions . RemoveEmptyEntries ) ;
93
+ if ( split . Length != 3 ) return false ;
94
+
95
+ //compare
96
+ return
97
+ split [ 0 ] == admin . Email
98
+ && split [ 1 ] == admin . Username
99
+ && split [ 2 ] == admin . RawPasswordValue ;
100
+ }
101
+ catch ( Exception ex )
102
+ {
103
+ LogHelper . Error < AdminTokenAuthorizeAttribute > ( "Failed to format passed in token value" , ex ) ;
104
+ return false ;
105
+ }
106
+ }
107
+ }
108
+ }
0 commit comments