or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-io.mdauthentication.mdhttp-client-server.mdindex.mdnetworking.mdtemplates.mdtesting.mdutilities.mdweb-framework.mdwebsocket.md

authentication.mddocs/

0

# Authentication

1

2

Authentication and authorization support for third-party services including OAuth, OAuth2, OpenID, and integration with major providers like Google, Facebook, and Twitter.

3

4

## Capabilities

5

6

### OAuth 1.0/1.0a Support

7

8

Abstract base classes for implementing OAuth 1.0 and 1.0a authentication flows.

9

10

```python { .api }

11

class OAuthMixin:

12

"""Abstract implementation of OAuth 1.0 and 1.0a."""

13

14

def get_auth_http_client(self):

15

"""Get HTTP client for auth requests."""

16

17

def oauth_request_token_url(self) -> str:

18

"""Get OAuth request token URL."""

19

20

def oauth_access_token_url(self) -> str:

21

"""Get OAuth access token URL."""

22

23

def oauth_authorize_url(self) -> str:

24

"""Get OAuth authorization URL."""

25

26

def oauth_consumer_key(self) -> str:

27

"""Get OAuth consumer key."""

28

29

def oauth_consumer_secret(self) -> str:

30

"""Get OAuth consumer secret."""

31

32

def oauth_get_user(self, access_token: str, callback):

33

"""Get user info with access token."""

34

35

def authenticate_redirect(self, callback_uri: str = None):

36

"""Start OAuth authentication flow."""

37

38

def get_authenticated_user(self, callback):

39

"""Complete OAuth authentication."""

40

```

41

42

### OAuth 2.0 Support

43

44

Abstract base class for OAuth 2.0 authentication flows with authorization code grant.

45

46

```python { .api }

47

class OAuth2Mixin:

48

"""Abstract implementation of OAuth 2.0."""

49

50

def get_auth_http_client(self):

51

"""Get HTTP client for auth requests."""

52

53

def oauth2_request_token_url(self) -> str:

54

"""Get OAuth2 token request URL."""

55

56

def oauth2_authorize_url(self) -> str:

57

"""Get OAuth2 authorization URL."""

58

59

def oauth2_client_id(self) -> str:

60

"""Get OAuth2 client ID."""

61

62

def oauth2_client_secret(self) -> str:

63

"""Get OAuth2 client secret."""

64

65

def oauth2_scope(self) -> str:

66

"""Get OAuth2 scope."""

67

68

def oauth2_access_token_url(self) -> str:

69

"""Get OAuth2 access token URL."""

70

71

def authorize_redirect(self, redirect_uri: str = None, client_id: str = None, client_secret: str = None, extra_params=None, scope: str = None, response_type: str = "code"):

72

"""

73

Start OAuth2 authorization flow.

74

75

Args:

76

redirect_uri: Redirect URI after authorization

77

client_id: OAuth2 client ID

78

client_secret: OAuth2 client secret

79

extra_params: Additional parameters

80

scope: OAuth2 scope

81

response_type: OAuth2 response type

82

"""

83

84

def get_authenticated_user(self, redirect_uri: str, client_id: str, client_secret: str, code: str, callback, extra_fields=None):

85

"""

86

Complete OAuth2 authentication.

87

88

Args:

89

redirect_uri: Redirect URI

90

client_id: OAuth2 client ID

91

client_secret: OAuth2 client secret

92

code: Authorization code

93

callback: Completion callback

94

extra_fields: Additional fields to request

95

"""

96

```

97

98

### OpenID Support

99

100

OpenID authentication with Attribute Exchange support.

101

102

```python { .api }

103

class OpenIdMixin:

104

"""Abstract implementation of OpenID and Attribute Exchange."""

105

106

def authenticate_redirect(self, callback_uri: str = None, ax_attrs: List[str] = None):

107

"""

108

Start OpenID authentication.

109

110

Args:

111

callback_uri: Callback URI

112

ax_attrs: Attribute Exchange attributes to request

113

"""

114

115

def get_authenticated_user(self, callback, http_client=None):

116

"""

117

Complete OpenID authentication.

118

119

Args:

120

callback: Completion callback

121

http_client: HTTP client for requests

122

"""

123

124

def get_auth_http_client(self):

125

"""Get HTTP client for auth requests."""

126

```

127

128

### Google OAuth2

129

130

Google-specific OAuth2 implementation with Google API integration.

131

132

```python { .api }

133

class GoogleOAuth2Mixin(OAuth2Mixin):

134

"""Google OAuth2 authentication."""

135

136

_OAUTH_AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth"

137

_OAUTH_ACCESS_TOKEN_URL = "https://accounts.google.com/o/oauth2/token"

138

_OAUTH_NO_CALLBACKS = False

139

140

def get_google_oauth_settings(self) -> Dict[str, str]:

141

"""

142

Get Google OAuth settings.

143

144

Returns:

145

Dict with google_oauth client_id and client_secret

146

"""

147

148

def oauth2_client_id(self) -> str:

149

"""Get Google OAuth2 client ID."""

150

151

def oauth2_client_secret(self) -> str:

152

"""Get Google OAuth2 client secret."""

153

154

def oauth2_scope(self) -> str:

155

"""Get Google OAuth2 scope."""

156

157

def oauth2_authorize_url(self) -> str:

158

"""Get Google OAuth2 authorization URL."""

159

160

def oauth2_access_token_url(self) -> str:

161

"""Get Google OAuth2 access token URL."""

162

```

163

164

### Facebook Graph API

165

166

Facebook Graph API authentication and user data access.

167

168

```python { .api }

169

class FacebookGraphMixin(OAuth2Mixin):

170

"""Facebook Graph API authentication."""

171

172

_OAUTH_AUTHORIZE_URL = "https://www.facebook.com/dialog/oauth"

173

_OAUTH_ACCESS_TOKEN_URL = "https://graph.facebook.com/oauth/access_token"

174

_OAUTH_NO_CALLBACKS = False

175

176

def facebook_request(self, path: str, callback, access_token: str = None, post_args=None, **args):

177

"""

178

Make Facebook Graph API request.

179

180

Args:

181

path: API path

182

callback: Response callback

183

access_token: Access token

184

post_args: POST arguments

185

**args: Additional arguments

186

"""

187

188

def oauth2_client_id(self) -> str:

189

"""Get Facebook app ID."""

190

191

def oauth2_client_secret(self) -> str:

192

"""Get Facebook app secret."""

193

194

def oauth2_scope(self) -> str:

195

"""Get Facebook OAuth scope."""

196

197

def oauth2_authorize_url(self) -> str:

198

"""Get Facebook OAuth authorization URL."""

199

200

def oauth2_access_token_url(self) -> str:

201

"""Get Facebook OAuth access token URL."""

202

```

203

204

### Twitter OAuth

205

206

Twitter-specific OAuth 1.0a implementation.

207

208

```python { .api }

209

class TwitterMixin(OAuthMixin):

210

"""Twitter OAuth authentication."""

211

212

_OAUTH_REQUEST_TOKEN_URL = "https://api.twitter.com/oauth/request_token"

213

_OAUTH_ACCESS_TOKEN_URL = "https://api.twitter.com/oauth/access_token"

214

_OAUTH_AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize"

215

_OAUTH_AUTHENTICATE_URL = "https://api.twitter.com/oauth/authenticate"

216

_OAUTH_NO_CALLBACKS = False

217

218

def twitter_request(self, path: str, callback, access_token: dict = None, post_args=None, **args):

219

"""

220

Make Twitter API request.

221

222

Args:

223

path: API path

224

callback: Response callback

225

access_token: Access token dict

226

post_args: POST arguments

227

**args: Additional arguments

228

"""

229

230

def oauth_consumer_key(self) -> str:

231

"""Get Twitter consumer key."""

232

233

def oauth_consumer_secret(self) -> str:

234

"""Get Twitter consumer secret."""

235

236

def oauth_request_token_url(self) -> str:

237

"""Get Twitter request token URL."""

238

239

def oauth_access_token_url(self) -> str:

240

"""Get Twitter access token URL."""

241

242

def oauth_authorize_url(self) -> str:

243

"""Get Twitter authorization URL."""

244

```

245

246

## Usage Examples

247

248

### Google OAuth2 Authentication

249

250

```python

251

import tornado.web

252

import tornado.auth

253

254

class GoogleAuth(tornado.web.RequestHandler, tornado.auth.GoogleOAuth2Mixin):

255

def get_google_oauth_settings(self):

256

return {

257

'google_oauth': {

258

'client_id': 'your-client-id',

259

'client_secret': 'your-client-secret'

260

}

261

}

262

263

async def get(self):

264

if self.get_argument('code', False):

265

# Handle OAuth callback

266

user = await self.get_authenticated_user(

267

redirect_uri='http://localhost:8888/auth/google',

268

code=self.get_argument('code')

269

)

270

271

if user:

272

self.write(f"Hello, {user['name']}!")

273

else:

274

self.write("Authentication failed")

275

else:

276

# Start OAuth flow

277

self.authorize_redirect(

278

redirect_uri='http://localhost:8888/auth/google',

279

client_id=self.get_google_oauth_settings()['google_oauth']['client_id'],

280

scope=['profile', 'email'],

281

response_type='code'

282

)

283

284

app = tornado.web.Application([

285

(r"/auth/google", GoogleAuth),

286

])

287

```

288

289

### Facebook Authentication

290

291

```python

292

import tornado.web

293

import tornado.auth

294

295

class FacebookAuth(tornado.web.RequestHandler, tornado.auth.FacebookGraphMixin):

296

@tornado.web.asynchronous

297

def get(self):

298

if self.get_argument("code", False):

299

self.get_authenticated_user(

300

redirect_uri='http://localhost:8888/auth/facebook',

301

client_id='your-app-id',

302

client_secret='your-app-secret',

303

code=self.get_argument("code"),

304

callback=self.on_auth

305

)

306

else:

307

self.authorize_redirect(

308

redirect_uri='http://localhost:8888/auth/facebook',

309

client_id='your-app-id',

310

extra_params={"scope": "read_stream,offline_access"}

311

)

312

313

def on_auth(self, user):

314

if user:

315

self.write(f"Hello, {user['name']}!")

316

else:

317

self.write("Authentication failed")

318

self.finish()

319

320

app = tornado.web.Application([

321

(r"/auth/facebook", FacebookAuth),

322

])

323

```

324

325

### Twitter Authentication

326

327

```python

328

import tornado.web

329

import tornado.auth

330

331

class TwitterAuth(tornado.web.RequestHandler, tornado.auth.TwitterMixin):

332

@tornado.web.asynchronous

333

def get(self):

334

if self.get_argument("oauth_token", None):

335

self.get_authenticated_user(self.on_auth)

336

else:

337

self.authenticate_redirect(callback_uri='http://localhost:8888/auth/twitter')

338

339

def on_auth(self, user):

340

if user:

341

self.write(f"Hello, {user['username']}!")

342

else:

343

self.write("Authentication failed")

344

self.finish()

345

346

app = tornado.web.Application([

347

(r"/auth/twitter", TwitterAuth),

348

])

349

```

350

351

## Types

352

353

```python { .api }

354

# OAuth token types

355

OAuthToken = Dict[str, str]

356

OAuth2Token = Dict[str, Any]

357

358

# User info type

359

UserInfo = Dict[str, Any]

360

361

# OAuth callback type

362

OAuthCallback = Callable[[UserInfo], None]

363

364

# HTTP client type for auth

365

AuthHTTPClient = tornado.httpclient.AsyncHTTPClient

366

```

367

368

## Exceptions

369

370

```python { .api }

371

class AuthError(Exception):

372

"""Base exception for authentication errors."""

373

374

def __init__(self, message: str):

375

"""

376

Initialize auth error.

377

378

Args:

379

message: Error message

380

"""

381

```