aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/core/auth/auth.service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/core/auth/auth.service.ts')
-rw-r--r--client/src/app/core/auth/auth.service.ts236
1 files changed, 118 insertions, 118 deletions
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts
index 4c75df1ca..32f7a5503 100644
--- a/client/src/app/core/auth/auth.service.ts
+++ b/client/src/app/core/auth/auth.service.ts
@@ -1,40 +1,40 @@
1import { Injectable } from '@angular/core'; 1import { Injectable } from '@angular/core'
2import { Headers, Http, Response, URLSearchParams } from '@angular/http'; 2import { Headers, Http, Response, URLSearchParams } from '@angular/http'
3import { Router } from '@angular/router'; 3import { Router } from '@angular/router'
4import { Observable } from 'rxjs/Observable'; 4import { Observable } from 'rxjs/Observable'
5import { Subject } from 'rxjs/Subject'; 5import { Subject } from 'rxjs/Subject'
6import 'rxjs/add/operator/map'; 6import 'rxjs/add/operator/map'
7import 'rxjs/add/operator/mergeMap'; 7import 'rxjs/add/operator/mergeMap'
8import 'rxjs/add/observable/throw'; 8import 'rxjs/add/observable/throw'
9 9
10import { NotificationsService } from 'angular2-notifications'; 10import { NotificationsService } from 'angular2-notifications'
11 11
12import { AuthStatus } from './auth-status.model'; 12import { AuthStatus } from './auth-status.model'
13import { AuthUser } from './auth-user.model'; 13import { AuthUser } from './auth-user.model'
14// Do not use the barrel (dependency loop) 14// Do not use the barrel (dependency loop)
15import { RestExtractor } from '../../shared/rest'; 15import { RestExtractor } from '../../shared/rest'
16 16
17@Injectable() 17@Injectable()
18export class AuthService { 18export class AuthService {
19 private static BASE_CLIENT_URL = API_URL + '/api/v1/clients/local'; 19 private static BASE_CLIENT_URL = API_URL + '/api/v1/clients/local'
20 private static BASE_TOKEN_URL = API_URL + '/api/v1/users/token'; 20 private static BASE_TOKEN_URL = API_URL + '/api/v1/users/token'
21 private static BASE_USER_INFORMATIONS_URL = API_URL + '/api/v1/users/me'; 21 private static BASE_USER_INFORMATIONS_URL = API_URL + '/api/v1/users/me'
22 22
23 loginChangedSource: Observable<AuthStatus>; 23 loginChangedSource: Observable<AuthStatus>
24 24
25 private clientId: string; 25 private clientId: string
26 private clientSecret: string; 26 private clientSecret: string
27 private loginChanged: Subject<AuthStatus>; 27 private loginChanged: Subject<AuthStatus>
28 private user: AuthUser = null; 28 private user: AuthUser = null
29 29
30 constructor( 30 constructor (
31 private http: Http, 31 private http: Http,
32 private notificationsService: NotificationsService, 32 private notificationsService: NotificationsService,
33 private restExtractor: RestExtractor, 33 private restExtractor: RestExtractor,
34 private router: Router 34 private router: Router
35 ) { 35 ) {
36 this.loginChanged = new Subject<AuthStatus>(); 36 this.loginChanged = new Subject<AuthStatus>()
37 this.loginChangedSource = this.loginChanged.asObservable(); 37 this.loginChangedSource = this.loginChanged.asObservable()
38 38
39 // Fetch the client_id/client_secret 39 // Fetch the client_id/client_secret
40 // FIXME: save in local storage? 40 // FIXME: save in local storage?
@@ -43,120 +43,120 @@ export class AuthService {
43 .catch((res) => this.restExtractor.handleError(res)) 43 .catch((res) => this.restExtractor.handleError(res))
44 .subscribe( 44 .subscribe(
45 result => { 45 result => {
46 this.clientId = result.client_id; 46 this.clientId = result.client_id
47 this.clientSecret = result.client_secret; 47 this.clientSecret = result.client_secret
48 console.log('Client credentials loaded.'); 48 console.log('Client credentials loaded.')
49 }, 49 },
50 50
51 error => { 51 error => {
52 let errorMessage = `Cannot retrieve OAuth Client credentials: ${error.text}. \n`; 52 let errorMessage = `Cannot retrieve OAuth Client credentials: ${error.text}. \n`
53 errorMessage += 'Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.'; 53 errorMessage += 'Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.'
54 54
55 // We put a bigger timeout 55 // We put a bigger timeout
56 // This is an important message 56 // This is an important message
57 this.notificationsService.error('Error', errorMessage, { timeOut: 7000 }); 57 this.notificationsService.error('Error', errorMessage, { timeOut: 7000 })
58 } 58 }
59 ); 59 )
60 60
61 // Return null if there is nothing to load 61 // Return null if there is nothing to load
62 this.user = AuthUser.load(); 62 this.user = AuthUser.load()
63 } 63 }
64 64
65 getRefreshToken() { 65 getRefreshToken () {
66 if (this.user === null) return null; 66 if (this.user === null) return null
67 67
68 return this.user.getRefreshToken(); 68 return this.user.getRefreshToken()
69 } 69 }
70 70
71 getRequestHeaderValue() { 71 getRequestHeaderValue () {
72 return `${this.getTokenType()} ${this.getAccessToken()}`; 72 return `${this.getTokenType()} ${this.getAccessToken()}`
73 } 73 }
74 74
75 getAccessToken() { 75 getAccessToken () {
76 if (this.user === null) return null; 76 if (this.user === null) return null
77 77
78 return this.user.getAccessToken(); 78 return this.user.getAccessToken()
79 } 79 }
80 80
81 getTokenType() { 81 getTokenType () {
82 if (this.user === null) return null; 82 if (this.user === null) return null
83 83
84 return this.user.getTokenType(); 84 return this.user.getTokenType()
85 } 85 }
86 86
87 getUser(): AuthUser { 87 getUser () {
88 return this.user; 88 return this.user
89 } 89 }
90 90
91 isAdmin() { 91 isAdmin () {
92 if (this.user === null) return false; 92 if (this.user === null) return false
93 93
94 return this.user.isAdmin(); 94 return this.user.isAdmin()
95 } 95 }
96 96
97 isLoggedIn() { 97 isLoggedIn () {
98 if (this.getAccessToken()) { 98 if (this.getAccessToken()) {
99 return true; 99 return true
100 } else { 100 } else {
101 return false; 101 return false
102 } 102 }
103 } 103 }
104 104
105 login(username: string, password: string) { 105 login (username: string, password: string) {
106 let body = new URLSearchParams(); 106 let body = new URLSearchParams()
107 body.set('client_id', this.clientId); 107 body.set('client_id', this.clientId)
108 body.set('client_secret', this.clientSecret); 108 body.set('client_secret', this.clientSecret)
109 body.set('response_type', 'code'); 109 body.set('response_type', 'code')
110 body.set('grant_type', 'password'); 110 body.set('grant_type', 'password')
111 body.set('scope', 'upload'); 111 body.set('scope', 'upload')
112 body.set('username', username); 112 body.set('username', username)
113 body.set('password', password); 113 body.set('password', password)
114 114
115 let headers = new Headers(); 115 let headers = new Headers()
116 headers.append('Content-Type', 'application/x-www-form-urlencoded'); 116 headers.append('Content-Type', 'application/x-www-form-urlencoded')
117 117
118 let options = { 118 let options = {
119 headers: headers 119 headers: headers
120 }; 120 }
121 121
122 return this.http.post(AuthService.BASE_TOKEN_URL, body.toString(), options) 122 return this.http.post(AuthService.BASE_TOKEN_URL, body.toString(), options)
123 .map(this.restExtractor.extractDataGet) 123 .map(this.restExtractor.extractDataGet)
124 .map(res => { 124 .map(res => {
125 res.username = username; 125 res.username = username
126 return res; 126 return res
127 }) 127 })
128 .flatMap(res => this.mergeUserInformations(res)) 128 .flatMap(res => this.mergeUserInformations(res))
129 .map(res => this.handleLogin(res)) 129 .map(res => this.handleLogin(res))
130 .catch((res) => this.restExtractor.handleError(res)); 130 .catch((res) => this.restExtractor.handleError(res))
131 } 131 }
132 132
133 logout() { 133 logout () {
134 // TODO: make an HTTP request to revoke the tokens 134 // TODO: make an HTTP request to revoke the tokens
135 this.user = null; 135 this.user = null
136 136
137 AuthUser.flush(); 137 AuthUser.flush()
138 138
139 this.setStatus(AuthStatus.LoggedOut); 139 this.setStatus(AuthStatus.LoggedOut)
140 } 140 }
141 141
142 refreshAccessToken() { 142 refreshAccessToken () {
143 console.log('Refreshing token...'); 143 console.log('Refreshing token...')
144 144
145 const refreshToken = this.getRefreshToken(); 145 const refreshToken = this.getRefreshToken()
146 146
147 let body = new URLSearchParams(); 147 let body = new URLSearchParams()
148 body.set('refresh_token', refreshToken); 148 body.set('refresh_token', refreshToken)
149 body.set('client_id', this.clientId); 149 body.set('client_id', this.clientId)
150 body.set('client_secret', this.clientSecret); 150 body.set('client_secret', this.clientSecret)
151 body.set('response_type', 'code'); 151 body.set('response_type', 'code')
152 body.set('grant_type', 'refresh_token'); 152 body.set('grant_type', 'refresh_token')
153 153
154 let headers = new Headers(); 154 let headers = new Headers()
155 headers.append('Content-Type', 'application/x-www-form-urlencoded'); 155 headers.append('Content-Type', 'application/x-www-form-urlencoded')
156 156
157 let options = { 157 let options = {
158 headers: headers 158 headers: headers
159 }; 159 }
160 160
161 return this.http.post(AuthService.BASE_TOKEN_URL, body.toString(), options) 161 return this.http.post(AuthService.BASE_TOKEN_URL, body.toString(), options)
162 .map(this.restExtractor.extractDataGet) 162 .map(this.restExtractor.extractDataGet)
@@ -164,41 +164,41 @@ export class AuthService {
164 .catch((res: Response) => { 164 .catch((res: Response) => {
165 // The refresh token is invalid? 165 // The refresh token is invalid?
166 if (res.status === 400 && res.json() && res.json().error === 'invalid_grant') { 166 if (res.status === 400 && res.json() && res.json().error === 'invalid_grant') {
167 console.error('Cannot refresh token -> logout...'); 167 console.error('Cannot refresh token -> logout...')
168 this.logout(); 168 this.logout()
169 this.router.navigate(['/login']); 169 this.router.navigate(['/login'])
170 170
171 return Observable.throw({ 171 return Observable.throw({
172 json: () => '', 172 json: () => '',
173 text: () => 'You need to reconnect.' 173 text: () => 'You need to reconnect.'
174 }); 174 })
175 } 175 }
176 176
177 return this.restExtractor.handleError(res); 177 return this.restExtractor.handleError(res)
178 }); 178 })
179 } 179 }
180 180
181 refreshUserInformations() { 181 refreshUserInformations () {
182 const obj = { 182 const obj = {
183 access_token: this.user.getAccessToken() 183 access_token: this.user.getAccessToken()
184 }; 184 }
185 185
186 this.mergeUserInformations(obj) 186 this.mergeUserInformations (obj)
187 .subscribe( 187 .subscribe(
188 res => { 188 res => {
189 this.user.displayNSFW = res.displayNSFW; 189 this.user.displayNSFW = res.displayNSFW
190 this.user.role = res.role; 190 this.user.role = res.role
191 191
192 this.user.save(); 192 this.user.save()
193 } 193 }
194 ); 194 )
195 } 195 }
196 196
197 private mergeUserInformations(obj: { access_token: string }) { 197 private mergeUserInformations (obj: { access_token: string }) {
198 // Do not call authHttp here to avoid circular dependencies headaches 198 // Do not call authHttp here to avoid circular dependencies headaches
199 199
200 const headers = new Headers(); 200 const headers = new Headers()
201 headers.set('Authorization', `Bearer ${obj.access_token}`); 201 headers.set('Authorization', `Bearer ${obj.access_token}`)
202 202
203 return this.http.get(AuthService.BASE_USER_INFORMATIONS_URL, { headers }) 203 return this.http.get(AuthService.BASE_USER_INFORMATIONS_URL, { headers })
204 .map(res => res.json()) 204 .map(res => res.json())
@@ -207,38 +207,38 @@ export class AuthService {
207 id: res.id, 207 id: res.id,
208 role: res.role, 208 role: res.role,
209 displayNSFW: res.displayNSFW 209 displayNSFW: res.displayNSFW
210 }; 210 }
211 211
212 return Object.assign(obj, newProperties); 212 return Object.assign(obj, newProperties)
213 } 213 }
214 ); 214 )
215 } 215 }
216 216
217 private handleLogin (obj: any) { 217 private handleLogin (obj: any) {
218 const id = obj.id; 218 const id = obj.id
219 const username = obj.username; 219 const username = obj.username
220 const role = obj.role; 220 const role = obj.role
221 const email = obj.email; 221 const email = obj.email
222 const displayNSFW = obj.displayNSFW; 222 const displayNSFW = obj.displayNSFW
223 const hashTokens = { 223 const hashTokens = {
224 access_token: obj.access_token, 224 accessToken: obj.access_token,
225 token_type: obj.token_type, 225 tokenType: obj.token_type,
226 refresh_token: obj.refresh_token 226 refreshToken: obj.refresh_token
227 }; 227 }
228 228
229 this.user = new AuthUser({ id, username, role, displayNSFW, email }, hashTokens); 229 this.user = new AuthUser({ id, username, role, displayNSFW, email }, hashTokens)
230 this.user.save(); 230 this.user.save()
231 231
232 this.setStatus(AuthStatus.LoggedIn); 232 this.setStatus(AuthStatus.LoggedIn)
233 } 233 }
234 234
235 private handleRefreshToken (obj: any) { 235 private handleRefreshToken (obj: any) {
236 this.user.refreshTokens(obj.access_token, obj.refresh_token); 236 this.user.refreshTokens(obj.access_token, obj.refresh_token)
237 this.user.save(); 237 this.user.save()
238 } 238 }
239 239
240 private setStatus(status: AuthStatus) { 240 private setStatus (status: AuthStatus) {
241 this.loginChanged.next(status); 241 this.loginChanged.next(status)
242 } 242 }
243 243
244} 244}