| 517 | |
| 518 | |
| 519 | class _Authentication(object): |
| 520 | __slots__ = ["access_token", "client_access_token", "_authenticated", "_wrong_attempts"] |
| 521 | |
| 522 | def __init__(self): |
| 523 | # A token to be send in the command line or through the settrace api -- when such token |
| 524 | # is given, the first message sent to the IDE must pass the same token to authenticate. |
| 525 | # Note that if a disconnect is sent, the same message must be resent to authenticate. |
| 526 | self.access_token = None |
| 527 | |
| 528 | # This token is the one that the client requires to accept a connection from pydevd |
| 529 | # (it's stored here and just passed back when required, it's not used internally |
| 530 | # for anything else). |
| 531 | self.client_access_token = None |
| 532 | |
| 533 | self._authenticated = None |
| 534 | |
| 535 | self._wrong_attempts = 0 |
| 536 | |
| 537 | def is_authenticated(self): |
| 538 | if self._authenticated is None: |
| 539 | return self.access_token is None |
| 540 | return self._authenticated |
| 541 | |
| 542 | def login(self, access_token): |
| 543 | if self._wrong_attempts >= 10: # A user can fail to authenticate at most 10 times. |
| 544 | return |
| 545 | |
| 546 | self._authenticated = access_token == self.access_token |
| 547 | if not self._authenticated: |
| 548 | self._wrong_attempts += 1 |
| 549 | else: |
| 550 | self._wrong_attempts = 0 |
| 551 | |
| 552 | def logout(self): |
| 553 | self._authenticated = None |
| 554 | self._wrong_attempts = 0 |
| 555 | |
| 556 | |
| 557 | class PyDB(object): |