WP Meta SEO - Version 3.2.0

Version Description

  • Enable Google Analytics tracking with token access
  • Tracking options to exclude WordPress user groups from analytics
  • File download statistics activation
  • Display Analytics statistics: session, users, organic...
Download this release

Release Info

Developer JoomUnited
Plugin Icon 128x128 WP Meta SEO
Version 3.2.0
Comparing to
See all releases

Code changes from version 3.1.2 to 3.2.0

Files changed (68) hide show
  1. css/google-analytics/admin-widgets.css +291 -0
  2. css/google-analytics/jquery.ui.tooltip.html.css +54 -0
  3. css/google-analytics/nprogress.css +85 -0
  4. css/google-analytics/wpms-tracking-code.css +206 -0
  5. inc/SrcGoogle/Google/Auth/Abstract.php +40 -0
  6. inc/SrcGoogle/Google/Auth/AppIdentity.php +101 -0
  7. inc/SrcGoogle/Google/Auth/AssertionCredentials.php +143 -0
  8. inc/SrcGoogle/Google/Auth/Exception.php +21 -0
  9. inc/SrcGoogle/Google/Auth/LoginTicket.php +76 -0
  10. inc/SrcGoogle/Google/Auth/OAuth2.php +547 -0
  11. inc/SrcGoogle/Google/Auth/Simple.php +65 -0
  12. inc/SrcGoogle/Google/Cache/Abstract.php +58 -0
  13. inc/SrcGoogle/Google/Cache/Apc.php +108 -0
  14. inc/SrcGoogle/Google/Cache/Exception.php +21 -0
  15. inc/SrcGoogle/Google/Cache/File.php +186 -0
  16. inc/SrcGoogle/Google/Cache/Memcache.php +178 -0
  17. inc/SrcGoogle/Google/Cache/Null.php +54 -0
  18. inc/SrcGoogle/Google/Client.php +761 -0
  19. inc/SrcGoogle/Google/Collection.php +93 -0
  20. inc/SrcGoogle/Google/Config.php +447 -0
  21. inc/SrcGoogle/Google/Exception.php +20 -0
  22. inc/SrcGoogle/Google/Http/Batch.php +138 -0
  23. inc/SrcGoogle/Google/Http/CacheParser.php +182 -0
  24. inc/SrcGoogle/Google/Http/MediaFileUpload.php +315 -0
  25. inc/SrcGoogle/Google/Http/REST.php +143 -0
  26. inc/SrcGoogle/Google/Http/Request.php +498 -0
  27. inc/SrcGoogle/Google/IO/Abstract.php +340 -0
  28. inc/SrcGoogle/Google/IO/Curl.php +153 -0
  29. inc/SrcGoogle/Google/IO/Exception.php +21 -0
  30. inc/SrcGoogle/Google/IO/Stream.php +202 -0
  31. inc/SrcGoogle/Google/IO/cacerts.pem +2183 -0
  32. inc/SrcGoogle/Google/Logger/Abstract.php +410 -0
  33. inc/SrcGoogle/Google/Logger/Exception.php +21 -0
  34. inc/SrcGoogle/Google/Logger/File.php +149 -0
  35. inc/SrcGoogle/Google/Logger/Null.php +40 -0
  36. inc/SrcGoogle/Google/Logger/Psr.php +93 -0
  37. inc/SrcGoogle/Google/Model.php +283 -0
  38. inc/SrcGoogle/Google/Service.php +45 -0
  39. inc/SrcGoogle/Google/Service/Analytics.php +11796 -0
  40. inc/SrcGoogle/Google/Service/Exception.php +49 -0
  41. inc/SrcGoogle/Google/Service/Resource.php +240 -0
  42. inc/SrcGoogle/Google/Signer/Abstract.php +30 -0
  43. inc/SrcGoogle/Google/Signer/P12.php +78 -0
  44. inc/SrcGoogle/Google/Utils.php +147 -0
  45. inc/SrcGoogle/Google/Utils/URITemplate.php +320 -0
  46. inc/SrcGoogle/Google/Verifier/Abstract.php +31 -0
  47. inc/SrcGoogle/Google/Verifier/Pem.php +78 -0
  48. inc/autoload.php +37 -0
  49. inc/class.metaseo-admin.php +352 -8
  50. inc/class.metaseo-front_end.php +77 -0
  51. inc/class.metaseo-google-analytics.php +125 -0
  52. inc/class.metaseo-sitemap.php +2 -1
  53. inc/class.wp-metaseo.php +1 -1
  54. inc/google_analytics/tracking/code-classic.php +26 -0
  55. inc/google_analytics/tracking/code-universal.php +123 -0
  56. inc/google_analytics/tracking/events-classic.php +47 -0
  57. inc/google_analytics/tracking/events-universal.php +59 -0
  58. inc/google_analytics/wpmsga.php +47 -0
  59. inc/google_analytics/wpmsgapi.php +766 -0
  60. inc/google_analytics/wpmstools.php +224 -0
  61. inc/pages/google-analytics/menu.php +4 -0
  62. inc/pages/google-analytics/metaseo-form-clientID.php +64 -0
  63. inc/pages/google-analytics/metaseo-google-analytics-trackcode.php +204 -0
  64. inc/pages/google-analytics/metaseo-google-analytics.php +34 -0
  65. js/google-analytics/google_analytics.js +1100 -0
  66. js/google-analytics/nprogress.js +477 -0
  67. readme.txt +27 -8
  68. wp-meta-seo.php +20 -6
css/google-analytics/admin-widgets.css ADDED
@@ -0,0 +1,291 @@
1
+ /* Real-Time content */
2
+ .wpms-pline {
3
+ width: 100%;
4
+ margin: 0 0;
5
+ padding: 5px 0 5px 0;
6
+ background: #fff;
7
+ -moz-box-shadow: 0px 0px 3px 0px #BBB;
8
+ -webkit-box-shadow: 0px 0px 3px 0px #BBB;
9
+ box-shadow: 0px 0px 3px 0px #BBB;
10
+ display: table;
11
+ overflow: hidden;
12
+ }
13
+
14
+ .wpms-pleft {
15
+ width: 90%;
16
+ float: left;
17
+ padding-left: 5px;
18
+ }
19
+
20
+ .wpms-pright {
21
+ width: 5%;
22
+ float: right;
23
+ padding-right: 5px;
24
+ }
25
+
26
+ [id^=wpms-realtime-] {
27
+ margin: 10px 0 0 0;
28
+ width: 100%;
29
+ }
30
+
31
+ .wpms-rt-box {
32
+ width: 100%;
33
+ margin: 0 0;
34
+ background: #fff;
35
+ text-align: center;
36
+ -moz-box-shadow: 0px 0px 5px 0px #BBB;
37
+ -webkit-box-shadow: 0px 0px 5px 0px #BBB;
38
+ box-shadow: 0px 0px 5px 0px #BBB;
39
+ display: table;
40
+ }
41
+
42
+ .wpms-tdo-left {
43
+ width: 60%;
44
+ padding: 33px 0;
45
+ float: left;
46
+ text-align: center;
47
+ }
48
+
49
+ .wpms-tdo-right {
50
+ width: 35%;
51
+ margin: 0px 10px 0px 0;
52
+ text-align: left;
53
+ font-weight: bold;
54
+ vertical-align: middle;
55
+ float: right;
56
+ display: table;
57
+ }
58
+
59
+ .wpms-online {
60
+ font-size: 100px;
61
+ font-weight: normal;
62
+ line-height: 1em;
63
+ margin: 0 auto;
64
+ width: 80%;
65
+ }
66
+
67
+ .wpms-bigtext {
68
+ font-size: 14px;
69
+ width: 100%;
70
+ margin: 0 0;
71
+ padding: 5px 5px 5px 5px;
72
+ background: #fff;
73
+ -moz-box-shadow: 0px 0px 3px 0px #BBB;
74
+ -webkit-box-shadow: 0px 0px 3px 0px #BBB;
75
+ box-shadow: 0px 0px 3px 0px #BBB;
76
+ display: table;
77
+ overflow: hidden;
78
+ }
79
+
80
+ .wpms-bleft {
81
+ float: left;
82
+ width: 80%;
83
+ }
84
+
85
+ .wpms-bright {
86
+ float: right;
87
+ width: 20%;
88
+ }
89
+
90
+ .wpms-pgdetailsr {
91
+ padding-left: 20px;
92
+ text-align: right;
93
+ }
94
+
95
+ .wpms-pgdetailsl {
96
+ min-width: 250px;
97
+ }
98
+
99
+ [id^=wpms-areachart-] {
100
+ width: 98%;
101
+ height: 100%;
102
+ margin: 10px auto 10px 0;
103
+ height: 250px;
104
+ }
105
+
106
+ .wpms-floatwraper {
107
+ display: table;
108
+ width: 100%;
109
+ height: 100%;
110
+ }
111
+
112
+ [id^=wpms-piechart-].halfsize {
113
+ width: 47%;
114
+ margin: 10px 0 0 0;
115
+ height: 200px;
116
+ float: left;
117
+ }
118
+
119
+ [id^=wpms-piechart-].floatleft {
120
+ float: left;
121
+ }
122
+
123
+ [id^=wpms-piechart-].floatright {
124
+ float: right;
125
+ }
126
+
127
+ [id^=wpms-tablechart-], [id^=wpms-tablechart-] {
128
+ width: 98%;
129
+ height: 100%;
130
+ margin: 10px auto 10px 0;
131
+ }
132
+
133
+ #dashboard-widgets-wrap .postbox {
134
+ margin-right: 10px;
135
+ }
136
+
137
+ /* Admin Widget content */
138
+ [id^=wpms-progressbar-] {
139
+ width: 100%;
140
+ height: 3px;
141
+ margin: 5px 0 0px 0;
142
+ }
143
+
144
+ [id^=wpms-bottomstats-] {
145
+ width: 50%;
146
+ margin: 0px auto;
147
+ }
148
+
149
+ [id^=wpms-bottomstats-] .inside {
150
+ display: table;
151
+ margin: 0 auto;
152
+ padding: 0px;
153
+ width: 100%;
154
+ }
155
+
156
+ .inside .small-box {
157
+ width: 30%;
158
+ float: left;
159
+ margin: 0 5px 10px 5px;
160
+ background: #fff;
161
+ text-align: center;
162
+ -moz-box-shadow: 0px 0px 7px 0px #BBB;
163
+ -webkit-box-shadow: 0px 0px 7px 0px #BBB;
164
+ box-shadow: 0px 0px 7px 0px #BBB;
165
+ }
166
+
167
+ .inside .small-box h3 {
168
+ font-size: 1em;
169
+ color: #777;
170
+ padding: 0px 5px 0px 5px;
171
+ margin: 0px 0px 0px 0px;
172
+ text-overflow: ellipsis;
173
+ overflow: hidden;
174
+ white-space: nowrap;
175
+ }
176
+
177
+ .inside .small-box p {
178
+ font-size: 1.2em;
179
+ margin: 0px 0px 2px 0px;
180
+ }
181
+
182
+ @media screen and (max-width: 410px) {
183
+ [id^=wpms-bottomstats-] .inside .small-box {
184
+ width: 45%;
185
+ }
186
+ }
187
+
188
+ .wpmsga_authorize , .wpmsga_clear_cache{
189
+ float: left;
190
+ }
191
+
192
+ .wpmsga_clear_author{
193
+ float: right;
194
+ }
195
+
196
+ .wpmsga_date , .wpmsga_report{
197
+ margin-left: 5px !important;
198
+ }
199
+
200
+ .wpmsga-btn-toolbar{
201
+ margin-bottom: 10px;
202
+ }
203
+
204
+ .google-visualization-table-th{
205
+ padding-top: 4px;
206
+ vertical-align: middle;
207
+ padding: 11px 0 0 3px;
208
+ font-weight: 400;
209
+ padding: 8px !important;
210
+ color: #0073aa;
211
+ text-align: left;
212
+ border-bottom: 1px solid #e1e1e1;
213
+ background: #fff;
214
+ }
215
+
216
+ .google-visualization-table-tr-even{
217
+ background-color: #f9f9f9;
218
+ }
219
+
220
+ .google-visualization-table-tr-odd{
221
+ background-color: #fff;
222
+ }
223
+
224
+ .google-visualization-table-td{
225
+ text-align: left !important;
226
+ padding: 10px !important;
227
+ }
228
+
229
+ .google-visualization-table-table th, .google-visualization-table-table td{
230
+ border-width: 0 0px 1px 0 !important;
231
+ }
232
+
233
+ .google-visualization-table-page-number{
234
+ width: 24px;
235
+ padding: 2px 0px;
236
+ border-radius: 0;
237
+ border: #ddd 1px solid;
238
+ background: #fff !important;
239
+ background-image: none !important;
240
+ color: #a0a5aa;
241
+ }
242
+
243
+ .charts-custom-button-inner-box{
244
+ padding: 5px 8px 7px !important;
245
+ border-radius: 0 !important;
246
+ border-style: none !important;
247
+ border: #ddd 1px solid;
248
+ }
249
+
250
+ .google-visualization-table-page-number.current{
251
+ background: #e5e5e5 !important;
252
+ font-weight: 100 !important;
253
+ color: #0073aa;
254
+ border-style : none;
255
+ }
256
+
257
+ .google-visualization-table-page-number:hover{
258
+ background: #00a0d2 !important;
259
+ color: #fff !important;
260
+ border: #00a0d2 !important;
261
+ }
262
+ .charts-custom-button-outer-box{
263
+ border-style : none !important;
264
+
265
+ }
266
+
267
+ .charts-custom-button{
268
+ border: none;
269
+ background: none;
270
+ }
271
+
272
+ .google-visualization-orgchart-node{
273
+ font-family: inherit !important;
274
+ border: 0 !important;
275
+ border-radius: 0 !important;
276
+ background: #fff !important;
277
+ box-shadow: 1px 1px 12px #ccc !important;
278
+ }
279
+
280
+ .wpms_msg_ublock{
281
+ display: none !important;
282
+ }
283
+
284
+ .nav-tab-wrapper{
285
+ display: block !important;
286
+ }
287
+
288
+ .metaseo-qtip {
289
+ font-size: 14px !important;
290
+ line-height: 18px !important;
291
+ }
css/google-analytics/jquery.ui.tooltip.html.css ADDED
@@ -0,0 +1,54 @@
1
+ /*! jQuery UI - v1.9.2 - 2013-09-22
2
+ * http://jqueryui.com
3
+ * Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
4
+ .ui-tooltip.wpms {
5
+ padding: 8px;
6
+ position: absolute;
7
+ z-index: 9999;
8
+ max-width: 300px;
9
+ -webkit-box-shadow: 0 0 5px #aaa;
10
+ box-shadow: 0 0 5px #aaa
11
+ }
12
+
13
+ * html .ui-tooltip.wpms {
14
+ background-image: none
15
+ }
16
+
17
+ body .ui-tooltip.wpms {
18
+ border-width: 2px
19
+ }
20
+
21
+ .ui-widget.wpms {
22
+ font-family: Verdana, Arial, sans-serif;
23
+ font-size: 1.1em;
24
+ }
25
+
26
+ .ui-widget.wpms .ui-widget {
27
+ font-size: 1em;
28
+ }
29
+
30
+ .ui-widget.wpms input, .ui-widget.wpms select, .ui-widget.wpms textarea, .ui-widget.wpms button {
31
+ font-family: Verdana, Arial, sans-serif;
32
+ font-size: 1em;
33
+ }
34
+
35
+ .ui-widget-content.wpms {
36
+ border: 1px solid #aaaaaa;
37
+ background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;
38
+ color: #222222;
39
+ }
40
+
41
+ .ui-widget-content.wpms a {
42
+ color: #222222;
43
+ }
44
+
45
+ .wpms .ui-widget-header {
46
+ border: 1px solid #aaaaaa;
47
+ background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;
48
+ color: #222222;
49
+ font-weight: bold;
50
+ }
51
+
52
+ .wpms .ui-widget-header a {
53
+ color: #222222;
54
+ }
css/google-analytics/nprogress.css ADDED
@@ -0,0 +1,85 @@
1
+ #nprogress {
2
+ pointer-events: none;
3
+ }
4
+
5
+ #nprogress .bar {
6
+ background: #29d;
7
+ position: fixed;
8
+ z-index: 1031;
9
+ top: 0;
10
+ left: 0;
11
+ width: 100%;
12
+ height: 2px;
13
+ }
14
+
15
+ /* Fancy blur effect */
16
+ #nprogress .peg {
17
+ display: block;
18
+ position: absolute;
19
+ right: 0px;
20
+ width: 100px;
21
+ height: 100%;
22
+ box-shadow: 0 0 10px #29d, 0 0 5px #29d;
23
+ opacity: 1.0;
24
+ -webkit-transform: rotate(3deg) translate(0px, -4px);
25
+ -ms-transform: rotate(3deg) translate(0px, -4px);
26
+ transform: rotate(3deg) translate(0px, -4px);
27
+ }
28
+
29
+ /* Remove these to get rid of the spinner */
30
+ #nprogress .spinner {
31
+ display: block;
32
+ position: fixed;
33
+ z-index: 1031;
34
+ top: 15px;
35
+ right: 15px;
36
+ }
37
+
38
+ #nprogress .spinner-icon {
39
+ width: 18px;
40
+ height: 18px;
41
+ box-sizing: border-box;
42
+ border: solid 2px transparent;
43
+ border-top-color: #29d;
44
+ border-left-color: #29d;
45
+ border-radius: 50%;
46
+ -webkit-animation: nprogress-spinner 400ms linear infinite;
47
+ animation: nprogress-spinner 400ms linear infinite;
48
+ }
49
+
50
+ .nprogress-custom-parent {
51
+ overflow: hidden;
52
+ position: relative;
53
+ }
54
+
55
+ .nprogress-custom-parent #nprogress .spinner, .nprogress-custom-parent #nprogress .bar {
56
+ position: absolute;
57
+ }
58
+
59
+ @-webkit-keyframes nprogress-spinner { 0% {
60
+ -webkit-transform: rotate(0deg);
61
+ }
62
+
63
+ 100%
64
+ {
65
+ -webkit-transform
66
+ :
67
+
68
+ rotate
69
+ (360deg);
70
+
71
+ }
72
+ }
73
+ @keyframes nprogress-spinner { 0% {
74
+ transform: rotate(0deg);
75
+ }
76
+ 100%
77
+ {
78
+ transform
79
+ :
80
+
81
+ rotate
82
+ (360deg);
83
+
84
+ }
85
+ }
css/google-analytics/wpms-tracking-code.css ADDED
@@ -0,0 +1,206 @@
1
+ /* Options pages */
2
+ table.wpmsga-settings-options {
3
+ padding-left: 10px;
4
+ width: 100%;
5
+ }
6
+
7
+ .wpmsga-settings-options td {
8
+ padding: 0px 5px 5px 5px;
9
+ }
10
+
11
+ td.wpmsga-settings-title, td.info {
12
+ width: 130px;
13
+ padding-left: 20px;
14
+ }
15
+
16
+ td.wpmsga-settings-title-s {
17
+ width: 300px;
18
+ }
19
+
20
+ .wpmsga-help {
21
+ padding-left: 15px;
22
+ }
23
+
24
+ td.wpmsga-settings-info {
25
+ padding-bottom: 15px;
26
+ }
27
+
28
+ td.wpmsga-settings-title label {
29
+ font-weight: bold;
30
+ }
31
+
32
+ .gadash-title {
33
+ float: left;
34
+ margin-right: 10px;
35
+ margin-top: 2px;
36
+ clear: left;
37
+ }
38
+
39
+ .gadash-desc {
40
+ font-size: 1em;
41
+ }
42
+
43
+ .gadash-top {
44
+ vertical-align: top;
45
+ }
46
+
47
+ pre.wpmsga-settings-logdata {
48
+ white-space: pre-wrap;
49
+ }
50
+
51
+ td.wpmsga-settings-roles {
52
+ padding-bottom: 15px;
53
+ }
54
+
55
+ #ga_speed_samplerate, #ga_realtime_pages {
56
+ width: 50px;
57
+ }
58
+
59
+ #gapi-access-code {
60
+ color: red !important;
61
+ }
62
+
63
+ #poststuff.wpmsga h2 {
64
+ padding-bottom: 0;
65
+ font-size: 19.5px;
66
+ font-weight: normal;
67
+ padding: 0;
68
+ margin: 20px 0 15px 0;
69
+ }
70
+
71
+ #poststuff.wpmsga h2.nav-tab-wrapper {
72
+ border-bottom: 1px solid #ccc;
73
+ padding-bottom: 0;
74
+ }
75
+
76
+ /* Options pages ON/OFF Switch */
77
+ .button-primary.wpmsga-settings-switchoo {
78
+ position: relative;
79
+ width: 50px;
80
+ float: left;
81
+ border: none;
82
+ padding: 0;
83
+ height: 22px;
84
+ -moz-box-shadow: none;
85
+ -webkit-box-shadow: none;
86
+ -o-box-shadow: none;
87
+ box-shadow: none;
88
+ -webkit-user-select: none;
89
+ -moz-user-select: none;
90
+ -ms-user-select: none;
91
+ }
92
+
93
+ input.wpmsga-settings-switchoo-checkbox {
94
+ display: none;
95
+ }
96
+
97
+ .wpmsga-settings-switchoo-label {
98
+ display: block;
99
+ overflow: hidden;
100
+ cursor: pointer;
101
+ background: transparent;
102
+ border: 1px solid #ddd;
103
+ border-radius: 2px;
104
+ text-shadow: none;
105
+ }
106
+
107
+ .wpmsga-settings-switchoo-inner {
108
+ width: 200%;
109
+ margin-left: -100%;
110
+ border-radius: 2px;
111
+ -moz-transition: margin 0.2s ease-in 0s;
112
+ -webkit-transition: margin 0.2s ease-in 0s;
113
+ -o-transition: margin 0.2s ease-in 0s;
114
+ transition: margin 0.2s ease-in 0s;
115
+ }
116
+
117
+ .wpmsga-settings-switchoo-inner:before, .wpmsga-settings-switchoo-inner:after {
118
+ float: left;
119
+ width: 50%;
120
+ font-weight: normal;
121
+ -moz-box-sizing: border-box;
122
+ -webkit-box-sizing: border-box;
123
+ -o-box-sizing: border-box;
124
+ box-sizing: border-box;
125
+ height: 22px;
126
+ line-height: 22px;
127
+ font-size: 12px;
128
+ text-shadow: none;
129
+ }
130
+
131
+ .wpmsga-settings-switchoo-inner:before {
132
+ content: "On";
133
+ padding-left: 5px;
134
+ border-bottom: none;
135
+ /* background-color: #00a0d2;
136
+ color: #fff; /* inherit from button props */
137
+ }
138
+
139
+ .wpmsga-settings-switchoo-inner:after {
140
+ content: "Off";
141
+ padding-right: 5px;
142
+ background-color: #ddd;
143
+ text-align: right;
144
+ }
145
+
146
+ .wpmsga-settings-switchoo-switch {
147
+ width: 22px;
148
+ height: 22px;
149
+ background: #fff;
150
+ color: #ddd;
151
+ border: 1px solid #ddd;
152
+ border-radius: 2px;
153
+ position: absolute;
154
+ top: 0;
155
+ bottom: 0;
156
+ right: 27px;
157
+ -moz-transition: all 0.2s ease-in 0s;
158
+ -webkit-transition: all 0.2s ease-in 0s;
159
+ -o-transition: all 0.2s ease-in 0s;
160
+ transition: all 0.2s ease-in 0s;
161
+ }
162
+
163
+ .wpmsga-settings-switchoo-switch:hover {
164
+ color: #aaa;
165
+ border-color: #aaa;
166
+ }
167
+
168
+ .wpmsga-settings-switchoo-switch:after {
169
+ margin: 0;
170
+ outline: 0;
171
+ display: inline-block;
172
+ font: 400 16px/16px dashicons;
173
+ content: "\f228";
174
+ padding: 3px 0 0 3px;
175
+ text-align: left;
176
+ text-decoration: none;
177
+ -webkit-font-smoothing: antialiased;
178
+ -moz-osx-font-smoothing: grayscale;
179
+ }
180
+
181
+ .wpmsga-settings-switchoo-checkbox:checked+.wpmsga-settings-switchoo-label .wpmsga-settings-switchoo-inner {
182
+ margin-left: 0;
183
+ }
184
+
185
+ .wpmsga-settings-switchoo-checkbox:checked+.wpmsga-settings-switchoo-label .wpmsga-settings-switchoo-switch {
186
+ right: 0px;
187
+ }
188
+
189
+ .switch-desc {
190
+ float: left;
191
+ margin-left: 10px;
192
+ line-height: 20px;
193
+ }
194
+
195
+ #wpmsga_dash_tracking{
196
+ float: left;
197
+ margin-right: 5px;
198
+ }
199
+
200
+ .wpms_msg_ublock{
201
+ display: none !important;
202
+ }
203
+
204
+ .nav-tab-wrapper{
205
+ display: block !important;
206
+ }
inc/SrcGoogle/Google/Auth/Abstract.php ADDED
@@ -0,0 +1,40 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ /**
20
+ * Abstract class for the Authentication in the API client
21
+ *
22
+ * @author Chris Chabot <chabotc@google.com>
23
+ *
24
+ */
25
+ abstract class Google_Auth_Abstract
26
+ {
27
+
28
+ /**
29
+ * An utility function that first calls $this->auth->sign($request) and then
30
+ * executes makeRequest() on that signed request.
31
+ * Used for when a request
32
+ * should be authenticated
33
+ *
34
+ * @param Google_Http_Request $request
35
+ * @return Google_Http_Request $request
36
+ */
37
+ abstract public function authenticatedRequest(Google_Http_Request $request);
38
+
39
+ abstract public function sign(Google_Http_Request $request);
40
+ }
inc/SrcGoogle/Google/Auth/AppIdentity.php ADDED
@@ -0,0 +1,101 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /*
18
+ * WARNING - this class depends on the Google App Engine PHP library
19
+ * which is 5.3 and above only, so if you include this in a PHP 5.2
20
+ * setup or one without 5.3 things will blow up.
21
+ */
22
+ use google\appengine\api\app_identity\AppIdentityService;
23
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
24
+
25
+ /**
26
+ * Authentication via the Google App Engine App Identity service.
27
+ */
28
+ class Google_Auth_AppIdentity extends Google_Auth_Abstract
29
+ {
30
+
31
+ const CACHE_PREFIX = "Google_Auth_AppIdentity::";
32
+
33
+ private $key = null;
34
+
35
+ private $client;
36
+
37
+ private $token = false;
38
+
39
+ private $tokenScopes = false;
40
+
41
+ public function __construct(Google_Client $client, $config = null)
42
+ {
43
+ $this->client = $client;
44
+ }
45
+
46
+ /**
47
+ * Retrieve an access token for the scopes supplied.
48
+ */
49
+ public function authenticateForScope($scopes)
50
+ {
51
+ if ($this->token && $this->tokenScopes == $scopes) {
52
+ return $this->token;
53
+ }
54
+ $cacheKey = self::CACHE_PREFIX;
55
+ if (is_string($scopes)) {
56
+ $cacheKey .= $scopes;
57
+ } else
58
+ if (is_array($scopes)) {
59
+ $cacheKey .= implode(":", $scopes);
60
+ }
61
+ $this->token = $this->client->getCache()->get($cacheKey);
62
+ if (! $this->token) {
63
+ $this->token = AppIdentityService::getAccessToken($scopes);
64
+ if ($this->token) {
65
+ $this->client->getCache()->set($cacheKey, $this->token);
66
+ }
67
+ }
68
+ $this->tokenScopes = $scopes;
69
+ return $this->token;
70
+ }
71
+
72
+ /**
73
+ * Perform an authenticated / signed apiHttpRequest.
74
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
75
+ * (which can modify the request in what ever way fits the auth mechanism)
76
+ * and then calls apiCurlIO::makeRequest on the signed request
77
+ *
78
+ * @param Google_Http_Request $request
79
+ * @return Google_Http_Request The resulting HTTP response including the
80
+ * responseHttpCode, responseHeaders and responseBody.
81
+ */
82
+ public function authenticatedRequest(Google_Http_Request $request)
83
+ {
84
+ $request = $this->sign($request);
85
+ return $this->client->getIo()->makeRequest($request);
86
+ }
87
+
88
+ public function sign(Google_Http_Request $request)
89
+ {
90
+ if (! $this->token) {
91
+ // No token, so nothing to do.
92
+ return $request;
93
+ }
94
+ $this->client->getLogger()->debug('App Identity authentication');
95
+ // Add the OAuth2 header to the request
96
+ $request->setRequestHeaders(array(
97
+ 'Authorization' => 'Bearer ' . $this->token['access_token']
98
+ ));
99
+ return $request;
100
+ }
101
+ }
inc/SrcGoogle/Google/Auth/AssertionCredentials.php ADDED
@@ -0,0 +1,143 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ /**
20
+ * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
21
+ *
22
+ * @author Chirag Shah <chirags@google.com>
23
+ */
24
+ class Google_Auth_AssertionCredentials
25
+ {
26
+
27
+ const MAX_TOKEN_LIFETIME_SECS = 3600;
28
+
29
+ public $serviceAccountName;
30
+
31
+ public $scopes;
32
+
33
+ public $privateKey;
34
+
35
+ public $privateKeyPassword;
36
+
37
+ public $assertionType;
38
+
39
+ public $sub;
40
+
41
+ /**
42
+ *
43
+ * @deprecated
44
+ *
45
+ * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
46
+ */
47
+ public $prn;
48
+
49
+ private $useCache;
50
+
51
+ /**
52
+ *
53
+ * @param
54
+ * $serviceAccountName
55
+ * @param $scopes array
56
+ * List of scopes
57
+ * @param
58
+ * $privateKey
59
+ * @param string $privateKeyPassword
60
+ * @param string $assertionType
61
+ * @param bool|string $sub
62
+ * The email address of the user for which the
63
+ * application is requesting delegated access.
64
+ * @param
65
+ * bool useCache Whether to generate a cache key and allow
66
+ * automatic caching of the generated token.
67
+ */
68
+ public function __construct($serviceAccountName, $scopes, $privateKey, $privateKeyPassword = 'notasecret', $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer', $sub = false, $useCache = true)
69
+ {
70
+ $this->serviceAccountName = $serviceAccountName;
71
+ $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
72
+ $this->privateKey = $privateKey;
73
+ $this->privateKeyPassword = $privateKeyPassword;
74
+ $this->assertionType = $assertionType;
75
+ $this->sub = $sub;
76
+ $this->prn = $sub;
77
+ $this->useCache = $useCache;
78
+ }
79
+
80
+ /**
81
+ * Generate a unique key to represent this credential.
82
+ *
83
+ * @return string
84
+ */
85
+ public function getCacheKey()
86
+ {
87
+ if (! $this->useCache) {
88
+ return false;
89
+ }
90
+ $h = $this->sub;
91
+ $h .= $this->assertionType;
92
+ $h .= $this->privateKey;
93
+ $h .= $this->scopes;
94
+ $h .= $this->serviceAccountName;
95
+ return md5($h);
96
+ }
97
+
98
+ public function generateAssertion()
99
+ {
100
+ $now = time();
101
+ $jwtParams = array(
102
+ 'aud' => Google_Auth_OAuth2::OAUTH2_TOKEN_URI,
103
+ 'scope' => $this->scopes,
104
+ 'iat' => $now,
105
+ 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
106
+ 'iss' => $this->serviceAccountName
107
+ );
108
+ if ($this->sub !== false) {
109
+ $jwtParams['sub'] = $this->sub;
110
+ } else
111
+ if ($this->prn !== false) {
112
+ $jwtParams['prn'] = $this->prn;
113
+ }
114
+ return $this->makeSignedJwt($jwtParams);
115
+ }
116
+
117
+ /**
118
+ * Creates a signed JWT.
119
+ *
120
+ * @param array $payload
121
+ * @return string The signed JWT.
122
+ */
123
+ private function makeSignedJwt($payload)
124
+ {
125
+ $header = array(
126
+ 'typ' => 'JWT',
127
+ 'alg' => 'RS256'
128
+ );
129
+ $payload = json_encode($payload);
130
+ // Handle some overzealous escaping in PHP json that seemed to cause some errors
131
+ // with claimsets.
132
+ $payload = str_replace('\/', '/', $payload);
133
+ $segments = array(
134
+ Google_Utils::urlSafeB64Encode(json_encode($header)),
135
+ Google_Utils::urlSafeB64Encode($payload)
136
+ );
137
+ $signingInput = implode('.', $segments);
138
+ $signer = new Google_Signer_P12($this->privateKey, $this->privateKeyPassword);
139
+ $signature = $signer->sign($signingInput);
140
+ $segments[] = Google_Utils::urlSafeB64Encode($signature);
141
+ return implode(".", $segments);
142
+ }
143
+ }
inc/SrcGoogle/Google/Auth/Exception.php ADDED
@@ -0,0 +1,21 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ class Google_Auth_Exception extends Google_Exception
20
+ {
21
+ }
inc/SrcGoogle/Google/Auth/LoginTicket.php ADDED
@@ -0,0 +1,76 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ /**
20
+ * Class to hold information about an authenticated login.
21
+ *
22
+ * @author Brian Eaton <beaton@google.com>
23
+ */
24
+ class Google_Auth_LoginTicket
25
+ {
26
+
27
+ const USER_ATTR = "sub";
28
+ // Information from id token envelope.
29
+ private $envelope;
30
+ // Information from id token payload.
31
+ private $payload;
32
+
33
+ /**
34
+ * Creates a user based on the supplied token.
35
+ *
36
+ * @param string $envelope
37
+ * Header from a verified authentication token.
38
+ * @param string $payload
39
+ * Information from a verified authentication token.
40
+ */
41
+ public function __construct($envelope, $payload)
42
+ {
43
+ $this->envelope = $envelope;
44
+ $this->payload = $payload;
45
+ }
46
+
47
+ /**
48
+ * Returns the numeric identifier for the user.
49
+ *
50
+ * @throws Google_Auth_Exception
51
+ * @return
52
+ *
53
+ */
54
+ public function getUserId()
55
+ {
56
+ if (array_key_exists(self::USER_ATTR, $this->payload)) {
57
+ return $this->payload[self::USER_ATTR];
58
+ }
59
+ throw new Google_Auth_Exception("No user_id in token");
60
+ }
61
+
62
+ /**
63
+ * Returns attributes from the login ticket.
64
+ * This can contain
65
+ * various information about the user session.
66
+ *
67
+ * @return array
68
+ */
69
+ public function getAttributes()
70
+ {
71
+ return array(
72
+ "envelope" => $this->envelope,
73
+ "payload" => $this->payload
74
+ );
75
+ }
76
+ }
inc/SrcGoogle/Google/Auth/OAuth2.php ADDED
@@ -0,0 +1,547 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ /**
20
+ * Authentication class that deals with the OAuth 2 web-server authentication flow
21
+ *
22
+ * @author Chris Chabot <chabotc@google.com>
23
+ * @author Chirag Shah <chirags@google.com>
24
+ *
25
+ */
26
+ class Google_Auth_OAuth2 extends Google_Auth_Abstract
27
+ {
28
+
29
+ const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
30
+
31
+ const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
32
+
33
+ const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
34
+
35
+ const CLOCK_SKEW_SECS = 300;
36
+ // five minutes in seconds
37
+ const AUTH_TOKEN_LIFETIME_SECS = 300;
38
+ // five minutes in seconds
39
+ const MAX_TOKEN_LIFETIME_SECS = 86400;
40
+ // one day in seconds
41
+ const OAUTH2_ISSUER = 'accounts.google.com';
42
+
43
+ /**
44
+ *
45
+ * @var Google_Auth_AssertionCredentials $assertionCredentials
46
+ */
47
+ private $assertionCredentials;
48
+
49
+ /**
50
+ *
51
+ * @var string The state parameters for CSRF and other forgery protection.
52
+ */
53
+ private $state;
54
+
55
+ /**
56
+ *
57
+ * @var array The token bundle.
58
+ */
59
+ private $token = array();
60
+
61
+ /**
62
+ *
63
+ * @var Google_Client the base client
64
+ */
65
+ private $client;
66
+
67
+ /**
68
+ * Instantiates the class, but does not initiate the login flow, leaving it
69
+ * to the discretion of the caller.
70
+ */
71
+ public function __construct(Google_Client $client)
72
+ {
73
+ $this->client = $client;
74
+ }
75
+
76
+ /**
77
+ * Perform an authenticated / signed apiHttpRequest.
78
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
79
+ * (which can modify the request in what ever way fits the auth mechanism)
80
+ * and then calls apiCurlIO::makeRequest on the signed request
81
+ *
82
+ * @param Google_Http_Request $request
83
+ * @return Google_Http_Request The resulting HTTP response including the
84
+ * responseHttpCode, responseHeaders and responseBody.
85
+ */
86
+ public function authenticatedRequest(Google_Http_Request $request)
87
+ {
88
+ $request = $this->sign($request);
89
+ return $this->client->getIo()->makeRequest($request);
90
+ }
91
+
92
+ /**
93
+ *
94
+ * @param string $code
95
+ * @throws Google_Auth_Exception
96
+ * @return string
97
+ */
98
+ public function authenticate($code)
99
+ {
100
+ if (strlen($code) == 0) {
101
+ throw new Google_Auth_Exception("Invalid code");
102
+ }
103
+ // We got here from the redirect from a successful authorization grant,
104
+ // fetch the access token
105
+ $request = new Google_Http_Request(self::OAUTH2_TOKEN_URI, 'POST', array(), array(
106
+ 'code' => $code,
107
+ 'grant_type' => 'authorization_code',
108
+ 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
109
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
110
+ 'client_secret' => $this->client->getClassConfig($this, 'client_secret')
111
+ ));
112
+ $request->disableGzip();
113
+ $response = $this->client->getIo()->makeRequest($request);
114
+ if ($response->getResponseHttpCode() == 200) {
115
+ $this->setAccessToken($response->getResponseBody());
116
+ $this->token['created'] = time();
117
+ return $this->getAccessToken();
118
+ } else {
119
+ $decodedResponse = json_decode($response->getResponseBody(), true);
120
+ if ($decodedResponse != null && $decodedResponse['error']) {
121
+ $errorText = $decodedResponse['error'];
122
+ if (isset($decodedResponse['error_description'])) {
123
+ $errorText .= ": " . $decodedResponse['error_description'];
124
+ }
125
+ }
126
+ throw new Google_Auth_Exception(sprintf("Error fetching OAuth2 access token, message: '%s'", $errorText), $response->getResponseHttpCode());
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Create a URL to obtain user authorization.
132
+ * The authorization endpoint allows the user to first
133
+ * authenticate, and then grant/deny the access request.
134
+ *
135
+ * @param string $scope
136
+ * The scope is expressed as a list of space-delimited strings.
137
+ * @return string
138
+ */
139
+ public function createAuthUrl($scope)
140
+ {
141
+ $params = array(
142
+ 'response_type' => 'code',
143
+ 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
144
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
145
+ 'scope' => $scope,
146
+ 'access_type' => $this->client->getClassConfig($this, 'access_type')
147
+ );
148
+ // Prefer prompt to approval prompt.
149
+ if ($this->client->getClassConfig($this, 'prompt')) {
150
+ $params = $this->maybeAddParam($params, 'prompt');
151
+ } else {
152
+ $params = $this->maybeAddParam($params, 'approval_prompt');
153
+ }
154
+ $params = $this->maybeAddParam($params, 'login_hint');
155
+ $params = $this->maybeAddParam($params, 'hd');
156
+ $params = $this->maybeAddParam($params, 'openid.realm');
157
+ $params = $this->maybeAddParam($params, 'include_granted_scopes');
158
+ // If the list of scopes contains plus.login, add request_visible_actions
159
+ // to auth URL.
160
+ $rva = $this->client->getClassConfig($this, 'request_visible_actions');
161
+ if (strpos($scope, 'plus.login') && strlen($rva) > 0) {
162
+ $params['request_visible_actions'] = $rva;
163
+ }
164
+ if (isset($this->state)) {
165
+ $params['state'] = $this->state;
166
+ }
167
+ return self::OAUTH2_AUTH_URL . "?" . http_build_query($params, '', '&');
168
+ }
169
+
170
+ /**
171
+ *
172
+ * @param string $token
173
+ * @throws Google_Auth_Exception
174
+ */
175
+ public function setAccessToken($token)
176
+ {
177
+ $token = json_decode($token, true);
178
+ if ($token == null) {
179
+ throw new Google_Auth_Exception('Could not json decode the token');
180
+ }
181
+ if (! isset($token['access_token'])) {
182
+ throw new Google_Auth_Exception("Invalid token format");
183
+ }
184
+ $this->token = $token;
185
+ }
186
+
187
+ public function getAccessToken()
188
+ {
189
+ return json_encode($this->token);
190
+ }
191
+
192
+ public function getRefreshToken()
193
+ {
194
+ if (array_key_exists('refresh_token', $this->token)) {
195
+ return $this->token['refresh_token'];
196
+ } else {
197
+ return null;
198
+ }
199
+ }
200
+
201
+ public function setState($state)
202
+ {
203
+ $this->state = $state;
204
+ }
205
+
206
+ public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
207
+ {
208
+ $this->assertionCredentials = $creds;
209
+ }
210
+
211
+ /**
212
+ * Include an accessToken in a given apiHttpRequest.
213
+ *
214
+ * @param Google_Http_Request $request
215
+ * @return Google_Http_Request
216
+ * @throws Google_Auth_Exception
217
+ */
218
+ public function sign(Google_Http_Request $request)
219
+ {
220
+ // add the developer key to the request before signing it
221
+ if ($this->client->getClassConfig($this, 'developer_key')) {
222
+ $request->setQueryParam('key', $this->client->getClassConfig($this, 'developer_key'));
223
+ }
224
+ // Cannot sign the request without an OAuth access token.
225
+ if (null == $this->token && null == $this->assertionCredentials) {
226
+ return $request;
227
+ }
228
+ // Check if the token is set to expire in the next 30 seconds
229
+ // (or has already expired).
230
+ if ($this->isAccessTokenExpired()) {
231
+ if ($this->assertionCredentials) {
232
+ $this->refreshTokenWithAssertion();
233
+ } else {
234
+ $this->client->getLogger()->debug('OAuth2 access token expired');
235
+ if (! array_key_exists('refresh_token', $this->token)) {
236
+ $error = "The OAuth 2.0 access token has expired," . " and a refresh token is not available. Refresh tokens" . " are not returned for responses that were auto-approved.";
237
+ $this->client->getLogger()->error($error);
238
+ throw new Google_Auth_Exception($error);
239
+ }
240
+ $this->refreshToken($this->token['refresh_token']);
241
+ }
242
+ }
243
+ $this->client->getLogger()->debug('OAuth2 authentication');
244
+ // Add the OAuth2 header to the request
245
+ $request->setRequestHeaders(array(
246
+ 'Authorization' => 'Bearer ' . $this->token['access_token']
247
+ ));
248
+ return $request;
249
+ }
250
+
251
+ /**
252
+ * Fetches a fresh access token with the given refresh token.
253
+ *
254
+ * @param string $refreshToken
255
+ * @return void
256
+ */
257
+ public function refreshToken($refreshToken)
258
+ {
259
+ $this->refreshTokenRequest(array(
260
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
261
+ 'client_secret' => $this->client->getClassConfig($this, 'client_secret'),
262
+ 'refresh_token' => $refreshToken,
263
+ 'grant_type' => 'refresh_token'
264
+ ));
265
+ }
266
+
267
+ /**
268
+ * Fetches a fresh access token with a given assertion token.
269
+ *
270
+ * @param Google_Auth_AssertionCredentials $assertionCredentials
271
+ * optional.
272
+ * @return void
273
+ */
274
+ public function refreshTokenWithAssertion($assertionCredentials = null)
275
+ {
276
+ if (! $assertionCredentials) {
277
+ $assertionCredentials = $this->assertionCredentials;
278
+ }
279
+ $cacheKey = $assertionCredentials->getCacheKey();
280
+ if ($cacheKey) {
281
+ // We can check whether we have a token available in the
282
+ // cache. If it is expired, we can retrieve a new one from
283
+ // the assertion.
284
+ $token = $this->client->getCache()->get($cacheKey);
285
+ if ($token) {
286
+ $this->setAccessToken($token);
287
+ }
288
+ if (! $this->isAccessTokenExpired()) {
289
+ return;
290
+ }
291
+ }
292
+ $this->client->getLogger()->debug('OAuth2 access token expired');
293
+ $this->refreshTokenRequest(array(
294
+ 'grant_type' => 'assertion',
295
+ 'assertion_type' => $assertionCredentials->assertionType,
296
+ 'assertion' => $assertionCredentials->generateAssertion()
297
+ ));
298
+ if ($cacheKey) {
299
+ // Attempt to cache the token.
300
+ $this->client->getCache()->set($cacheKey, $this->getAccessToken());
301
+ }
302
+ }
303
+
304
+ private function refreshTokenRequest($params)
305
+ {
306
+ if (isset($params['assertion'])) {
307
+ $this->client->getLogger()->info('OAuth2 access token refresh with Signed JWT assertion grants.');
308
+ } else {
309
+ $this->client->getLogger()->info('OAuth2 access token refresh');
310
+ }
311
+ $http = new Google_Http_Request(self::OAUTH2_TOKEN_URI, 'POST', array(), $params);
312
+ $http->disableGzip();
313
+ $request = $this->client->getIo()->makeRequest($http);
314
+ $code = $request->getResponseHttpCode();
315
+ $body = $request->getResponseBody();
316
+ if (200 == $code) {
317
+ $token = json_decode($body, true);
318
+ if ($token == null) {
319
+ throw new Google_Auth_Exception("Could not json decode the access token");
320
+ }
321
+ if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
322
+ throw new Google_Auth_Exception("Invalid token format");
323
+ }
324
+ if (isset($token['id_token'])) {
325
+ $this->token['id_token'] = $token['id_token'];
326
+ }
327
+ $this->token['access_token'] = $token['access_token'];
328
+ $this->token['expires_in'] = $token['expires_in'];
329
+ $this->token['created'] = time();
330
+ } else {
331
+ throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Revoke an OAuth2 access token or refresh token.
337
+ * This method will revoke the current access
338
+ * token, if a token isn't provided.
339
+ *
340
+ * @throws Google_Auth_Exception
341
+ * @param string|null $token
342
+ * The token (access token or a refresh token) that should be revoked.
343
+ * @return boolean Returns True if the revocation was successful, otherwise False.
344
+ */
345
+ public function revokeToken($token = null)
346
+ {
347
+ if (! $token) {
348
+ if (! $this->token) {
349
+ // Not initialized, no token to actually revoke
350
+ return false;
351
+ } elseif (array_key_exists('refresh_token', $this->token)) {
352
+ $token = $this->token['refresh_token'];
353
+ } else {
354
+ $token = $this->token['access_token'];
355
+ }
356
+ }
357
+ $request = new Google_Http_Request(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token");
358
+ $request->disableGzip();
359
+ $response = $this->client->getIo()->makeRequest($request);
360
+ $code = $response->getResponseHttpCode();
361
+ if ($code == 200) {
362
+ $this->token = null;
363
+ return true;
364
+ }
365
+ return false;
366
+ }
367
+
368
+ /**
369
+ * Returns if the access_token is expired.
370
+ *
371
+ * @return bool Returns True if the access_token is expired.
372
+ */
373
+ public function isAccessTokenExpired()
374
+ {
375
+ if (! $this->token || ! isset($this->token['created'])) {
376
+ return true;
377
+ }
378
+ // If the token is set to expire in the next 30 seconds.
379
+ $expired = ($this->token['created'] + ($this->token['expires_in'] - 30)) < time();
380
+ return $expired;
381
+ }
382
+ // Gets federated sign-on certificates to use for verifying identity tokens.
383
+ // Returns certs as array structure, where keys are key ids, and values
384
+ // are PEM encoded certificates.
385
+ private function getFederatedSignOnCerts()
386
+ {
387
+ return $this->retrieveCertsFromLocation($this->client->getClassConfig($this, 'federated_signon_certs_url'));
388
+ }
389
+
390
+ /**
391
+ * Retrieve and cache a certificates file.
392
+ *
393
+ * @param $url string
394
+ * location
395
+ * @throws Google_Auth_Exception
396
+ * @return array certificates
397
+ */
398
+ public function retrieveCertsFromLocation($url)
399
+ {
400
+ // If we're retrieving a local file, just grab it.
401
+ if ("http" != substr($url, 0, 4)) {
402
+ $file = file_get_contents($url);
403
+ if ($file) {
404
+ return json_decode($file, true);
405
+ } else {
406
+ throw new Google_Auth_Exception("Failed to retrieve verification certificates: '" . $url . "'.");
407
+ }
408
+ }
409
+ // This relies on makeRequest caching certificate responses.
410
+ $request = $this->client->getIo()->makeRequest(new Google_Http_Request($url));
411
+ if ($request->getResponseHttpCode() == 200) {
412
+ $certs = json_decode($request->getResponseBody(), true);
413
+ if ($certs) {
414
+ return $certs;
415
+ }
416
+ }
417
+ throw new Google_Auth_Exception("Failed to retrieve verification certificates: '" . $request->getResponseBody() . "'.", $request->getResponseHttpCode());
418
+ }
419
+
420
+ /**
421
+ * Verifies an id token and returns the authenticated apiLoginTicket.
422
+ * Throws an exception if the id token is not valid.
423
+ * The audience parameter can be used to control which id tokens are
424
+ * accepted. By default, the id token must have been issued to this OAuth2 client.
425
+ *
426
+ * @param
427
+ * $id_token
428
+ * @param
429
+ * $audience
430
+ * @return Google_Auth_LoginTicket
431
+ */
432
+ public function verifyIdToken($id_token = null, $audience = null)
433
+ {
434
+ if (! $id_token) {
435
+ $id_token = $this->token['id_token'];
436
+ }
437
+ $certs = $this->getFederatedSignonCerts();
438
+ if (! $audience) {
439
+ $audience = $this->client->getClassConfig($this, 'client_id');
440
+ }
441
+ return $this->verifySignedJwtWithCerts($id_token, $certs, $audience, self::OAUTH2_ISSUER);
442
+ }
443
+
444
+ /**
445
+ * Verifies the id token, returns the verified token contents.
446
+ *
447
+ * @param $jwt string
448
+ * the token
449
+ * @param $certs array
450
+ * of certificates
451
+ * @param $required_audience string
452
+ * the expected consumer of the token
453
+ * @param
454
+ * [$issuer] the expected issues, defaults to Google
455
+ * @param
456
+ * [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
457
+ * @throws Google_Auth_Exception
458
+ * @return mixed token information if valid, false if not
459
+ */
460
+ public function verifySignedJwtWithCerts($jwt, $certs, $required_audience, $issuer = null, $max_expiry = null)
461
+ {
462
+ if (! $max_expiry) {
463
+ // Set the maximum time we will accept a token for.
464
+ $max_expiry = self::MAX_TOKEN_LIFETIME_SECS;
465
+ }
466
+ $segments = explode(".", $jwt);
467
+ if (count($segments) != 3) {
468
+ throw new Google_Auth_Exception("Wrong number of segments in token: $jwt");
469
+ }
470
+ $signed = $segments[0] . "." . $segments[1];
471
+ $signature = Google_Utils::urlSafeB64Decode($segments[2]);
472
+ // Parse envelope.
473
+ $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true);
474
+ if (! $envelope) {
475
+ throw new Google_Auth_Exception("Can't parse token envelope: " . $segments[0]);
476
+ }
477
+ // Parse token
478
+ $json_body = Google_Utils::urlSafeB64Decode($segments[1]);
479
+ $payload = json_decode($json_body, true);
480
+ if (! $payload) {
481
+ throw new Google_Auth_Exception("Can't parse token payload: " . $segments[1]);
482
+ }
483
+ // Check signature
484
+ $verified = false;
485
+ foreach ($certs as $keyName => $pem) {
486
+ $public_key = new Google_Verifier_Pem($pem);
487
+ if ($public_key->verify($signed, $signature)) {
488
+ $verified = true;
489
+ break;
490
+ }
491
+ }
492
+ if (! $verified) {
493
+ throw new Google_Auth_Exception("Invalid token signature: $jwt");
494
+ }
495
+ // Check issued-at timestamp
496
+ $iat = 0;
497
+ if (array_key_exists("iat", $payload)) {
498
+ $iat = $payload["iat"];
499
+ }
500
+ if (! $iat) {
501
+ throw new Google_Auth_Exception("No issue time in token: $json_body");
502
+ }
503
+ $earliest = $iat - self::CLOCK_SKEW_SECS;
504
+ // Check expiration timestamp
505
+ $now = time();
506
+ $exp = 0;
507
+ if (array_key_exists("exp", $payload)) {
508
+ $exp = $payload["exp"];
509
+ }
510
+ if (! $exp) {
511
+ throw new Google_Auth_Exception("No expiration time in token: $json_body");
512
+ }
513
+ if ($exp >= $now + $max_expiry) {
514
+ throw new Google_Auth_Exception(sprintf("Expiration time too far in future: %s", $json_body));
515
+ }
516
+ $latest = $exp + self::CLOCK_SKEW_SECS;
517
+ if ($now < $earliest) {
518
+ throw new Google_Auth_Exception(sprintf("Token used too early, %s < %s: %s", $now, $earliest, $json_body));
519
+ }
520
+ if ($now > $latest) {
521
+ throw new Google_Auth_Exception(sprintf("Token used too late, %s > %s: %s", $now, $latest, $json_body));
522
+ }
523
+ $iss = $payload['iss'];
524
+ if ($issuer && $iss != $issuer) {
525
+ throw new Google_Auth_Exception(sprintf("Invalid issuer, %s != %s: %s", $iss, $issuer, $json_body));
526
+ }
527
+ // Check audience
528
+ $aud = $payload["aud"];
529
+ if ($aud != $required_audience) {
530
+ throw new Google_Auth_Exception(sprintf("Wrong recipient, %s != %s:", $aud, $required_audience, $json_body));
531
+ }
532
+ // All good.
533
+ return new Google_Auth_LoginTicket($envelope, $payload);
534
+ }
535
+
536
+ /**
537
+ * Add a parameter to the auth params if not empty string.
538
+ */
539
+ private function maybeAddParam($params, $name)
540
+ {
541
+ $param = $this->client->getClassConfig($this, $name);
542
+ if ($param != '') {
543
+ $params[$name] = $param;
544
+ }
545
+ return $params;
546
+ }
547
+ }
inc/SrcGoogle/Google/Auth/Simple.php ADDED
@@ -0,0 +1,65 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ /**
20
+ * Simple API access implementation.
21
+ * Can either be used to make requests
22
+ * completely unauthenticated, or by using a Simple API Access developer
23
+ * key.
24
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
26
+ * @author Chirag Shah <chirags@google.com>
27
+ */
28
+ class Google_Auth_Simple extends Google_Auth_Abstract
29
+ {
30
+
31
+ private $key = null;
32
+
33
+ private $client;
34
+
35
+ public function __construct(Google_Client $client, $config = null)
36
+ {
37
+ $this->client = $client;
38
+ }
39
+
40
+ /**
41
+ * Perform an authenticated / signed apiHttpRequest.
42
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
43
+ * (which can modify the request in what ever way fits the auth mechanism)
44
+ * and then calls apiCurlIO::makeRequest on the signed request
45
+ *
46
+ * @param Google_Http_Request $request
47
+ * @return Google_Http_Request The resulting HTTP response including the
48
+ * responseHttpCode, responseHeaders and responseBody.
49
+ */
50
+ public function authenticatedRequest(Google_Http_Request $request)
51
+ {
52
+ $request = $this->sign($request);
53
+ return $this->io->makeRequest($request);
54
+ }
55
+
56
+ public function sign(Google_Http_Request $request)
57
+ {
58
+ $key = $this->client->getClassConfig($this, 'developer_key');
59
+ if ($key) {
60
+ $this->client->getLogger()->debug('Simple API Access developer key authentication');
61
+ $request->setQueryParam('key', $key);
62
+ }
63
+ return $request;
64
+ }
65
+ }
inc/SrcGoogle/Google/Cache/Abstract.php ADDED
@@ -0,0 +1,58 @@
1
+ <?php
2
+
3
+ /*
4
+ * Copyright 2008 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ /**
19
+ * Abstract storage class
20
+ *
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ */
23
+ abstract class Google_Cache_Abstract
24
+ {
25
+
26
+ abstract public function __construct(Google_Client $client);
27
+
28
+ /**
29
+ * Retrieves the data for the given key, or false if they
30
+ * key is unknown or expired
31
+ *
32
+ * @param String $key
33
+ * The key who's data to retrieve
34
+ * @param boolean|int $expiration
35
+ * Expiration time in seconds
36
+ *
37
+ */
38
+ abstract public function get($key, $expiration = false);
39
+
40
+ /**
41
+ * Store the key => $value set.
42
+ * The $value is serialized
43
+ * by this function so can be of any type
44
+ *
45
+ * @param string $key
46
+ * Key of the data
47
+ * @param string $value
48
+ * data
49
+ */
50
+ abstract public function set($key, $value);
51
+
52
+ /**
53
+ * Removes the key/data pair for the given $key
54
+ *
55
+ * @param String $key
56
+ */
57
+ abstract public function delete($key);
58
+ }
inc/SrcGoogle/Google/Cache/Apc.php ADDED
@@ -0,0 +1,108 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ /**
20
+ * A persistent storage class based on the APC cache, which is not
21
+ * really very persistent, as soon as you restart your web server
22
+ * the storage will be wiped, however for debugging and/or speed
23
+ * it can be useful, and cache is a lot cheaper then storage.
24
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
26
+ */
27
+ class Google_Cache_Apc extends Google_Cache_Abstract
28
+ {
29
+
30
+ /**
31
+ *
32
+ * @var Google_Client the current client
33
+ */
34
+ private $client;
35
+
36
+ public function __construct(Google_Client $client)
37
+ {
38
+ if (! function_exists('apc_add')) {
39
+ $error = "Apc functions not available";
40
+ $client->getLogger()->error($error);
41
+ throw new Google_Cache_Exception($error);
42
+ }
43
+ $this->client = $client;
44
+ }
45
+
46
+ /**
47
+ * @inheritDoc
48
+ */
49
+ public function get($key, $expiration = false)
50
+ {
51
+ $ret = apc_fetch($key);
52
+ if ($ret === false) {
53
+ $this->client->getLogger()->debug('APC cache miss', array(
54
+ 'key' => $key
55
+ ));
56
+ return false;
57
+ }
58
+ if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
59
+ $this->client->getLogger()->debug('APC cache miss (expired)', array(
60
+ 'key' => $key,
61
+ 'var' => $ret
62
+ ));
63
+ $this->delete($key);
64
+ return false;
65
+ }
66
+ $this->client->getLogger()->debug('APC cache hit', array(
67
+ 'key' => $key,
68
+ 'var' => $ret
69
+ ));
70
+ return $ret['data'];
71
+ }
72
+
73
+ /**
74
+ * @inheritDoc
75
+ */
76
+ public function set($key, $value)
77
+ {
78
+ $var = array(
79
+ 'time' => time(),
80
+ 'data' => $value
81
+ );
82
+ $rc = apc_store($key, $var);
83
+ if ($rc == false) {
84
+ $this->client->getLogger()->error('APC cache set failed', array(
85
+ 'key' => $key,
86
+ 'var' => $var
87
+ ));
88
+ throw new Google_Cache_Exception("Couldn't store data");
89
+ }
90
+ $this->client->getLogger()->debug('APC cache set', array(
91
+ 'key' => $key,
92
+ 'var' => $var
93
+ ));
94
+ }
95
+
96
+ /**
97
+ * @inheritDoc
98
+ *
99
+ * @param String $key
100
+ */
101
+ public function delete($key)
102
+ {
103
+ $this->client->getLogger()->debug('APC cache delete', array(
104
+ 'key' => $key
105
+ ));
106
+ apc_delete($key);
107
+ }
108
+ }
inc/SrcGoogle/Google/Cache/Exception.php ADDED
@@ -0,0 +1,21 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ class Google_Cache_Exception extends Google_Exception
20
+ {
21
+ }
inc/SrcGoogle/Google/Cache/File.php ADDED
@@ -0,0 +1,186 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once realpath(dirname(__FILE__) . '/../../../autoload.php');
18
+
19
+ /*
20
+ * This class implements a basic on disk storage. While that does
21
+ * work quite well it's not the most elegant and scalable solution.
22
+ * It will also get you into a heap of trouble when you try to run
23
+ * this in a clustered environment.
24
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
26