| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- """
- Tests for authentication module
- """
- import pytest
- import json
- from app import db
- from app.models import User
- @pytest.fixture
- def test_user(app):
- """Create a test user"""
- with app.app_context():
- user = User(
- username='testuser',
- email='test@example.com',
- role='user'
- )
- user.set_password('testpassword123')
- db.session.add(user)
- db.session.commit()
-
- # Return user data (not the object, as it will be detached)
- return {
- 'id': user.id,
- 'username': user.username,
- 'email': user.email,
- 'role': user.role
- }
- @pytest.fixture
- def admin_user(app):
- """Create an admin user"""
- with app.app_context():
- user = User(
- username='adminuser',
- email='admin@example.com',
- role='admin'
- )
- user.set_password('adminpassword123')
- db.session.add(user)
- db.session.commit()
-
- return {
- 'id': user.id,
- 'username': user.username,
- 'email': user.email,
- 'role': user.role
- }
- class TestLogin:
- """Tests for login endpoint"""
-
- def test_login_success(self, client, test_user):
- """Test successful login"""
- response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'testuser',
- 'password': 'testpassword123'
- }),
- content_type='application/json'
- )
-
- assert response.status_code == 200
- data = json.loads(response.data)
- assert 'token' in data
- assert 'refresh_token' in data
- assert 'user' in data
- assert data['user']['username'] == 'testuser'
-
- def test_login_invalid_password(self, client, test_user):
- """Test login with invalid password"""
- response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'testuser',
- 'password': 'wrongpassword'
- }),
- content_type='application/json'
- )
-
- assert response.status_code == 401
- data = json.loads(response.data)
- assert 'error' in data
-
- def test_login_missing_fields(self, client):
- """Test login with missing fields"""
- response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'testuser'
- }),
- content_type='application/json'
- )
-
- assert response.status_code == 400
- data = json.loads(response.data)
- assert 'error' in data
- class TestGetCurrentUser:
- """Tests for get current user endpoint"""
-
- def test_get_current_user_success(self, client, test_user):
- """Test getting current user with valid token"""
- # First login to get token
- login_response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'testuser',
- 'password': 'testpassword123'
- }),
- content_type='application/json'
- )
- token = json.loads(login_response.data)['token']
-
- # Get current user
- response = client.get('/api/auth/me',
- headers={'Authorization': f'Bearer {token}'}
- )
-
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['username'] == 'testuser'
-
- def test_get_current_user_no_token(self, client):
- """Test getting current user without token"""
- response = client.get('/api/auth/me')
-
- assert response.status_code == 401
- class TestRefreshToken:
- """Tests for token refresh endpoint"""
-
- def test_refresh_token_success(self, client, test_user):
- """Test successful token refresh"""
- # First login to get tokens
- login_response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'testuser',
- 'password': 'testpassword123'
- }),
- content_type='application/json'
- )
- refresh_token = json.loads(login_response.data)['refresh_token']
-
- # Refresh token
- response = client.post('/api/auth/refresh',
- data=json.dumps({
- 'refresh_token': refresh_token
- }),
- content_type='application/json'
- )
-
- assert response.status_code == 200
- data = json.loads(response.data)
- assert 'access_token' in data
-
- def test_refresh_token_invalid(self, client):
- """Test refresh with invalid token"""
- response = client.post('/api/auth/refresh',
- data=json.dumps({
- 'refresh_token': 'invalid_token'
- }),
- content_type='application/json'
- )
-
- assert response.status_code == 401
- class TestLogout:
- """Tests for logout endpoint"""
-
- def test_logout_success(self, client, test_user):
- """Test successful logout"""
- # First login to get token
- login_response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'testuser',
- 'password': 'testpassword123'
- }),
- content_type='application/json'
- )
- token = json.loads(login_response.data)['token']
-
- # Logout
- response = client.post('/api/auth/logout',
- headers={'Authorization': f'Bearer {token}'}
- )
-
- assert response.status_code == 200
- @pytest.fixture
- def power_user(app):
- """Create a power user"""
- with app.app_context():
- user = User(
- username='poweruser',
- email='power@example.com',
- role='power_user'
- )
- user.set_password('powerpassword123')
- db.session.add(user)
- db.session.commit()
-
- return {
- 'id': user.id,
- 'username': user.username,
- 'email': user.email,
- 'role': user.role
- }
- class TestRBAC:
- """Tests for role-based access control"""
-
- def test_admin_access(self, client, admin_user):
- """Test admin can access admin-only endpoints"""
- # Login as admin
- login_response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'adminuser',
- 'password': 'adminpassword123'
- }),
- content_type='application/json'
- )
- token = json.loads(login_response.data)['token']
-
- # Admin should be able to access user list (admin endpoint)
- response = client.get('/api/users',
- headers={'Authorization': f'Bearer {token}'}
- )
-
- # Should not return 403 (may return 200 or other status depending on implementation)
- assert response.status_code != 403
-
- def test_regular_user_denied_admin_access(self, client, test_user):
- """Test regular user cannot access admin-only endpoints"""
- # Login as regular user
- login_response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'testuser',
- 'password': 'testpassword123'
- }),
- content_type='application/json'
- )
- token = json.loads(login_response.data)['token']
-
- # Regular user should be denied access to admin endpoints
- response = client.get('/api/users',
- headers={'Authorization': f'Bearer {token}'}
- )
-
- assert response.status_code == 403
-
- def test_power_user_access(self, client, power_user):
- """Test power user can access power_user endpoints"""
- # Login as power user
- login_response = client.post('/api/auth/login',
- data=json.dumps({
- 'username': 'poweruser',
- 'password': 'powerpassword123'
- }),
- content_type='application/json'
- )
- token = json.loads(login_response.data)['token']
-
- # Power user should be able to access credentials list
- response = client.get('/api/credentials',
- headers={'Authorization': f'Bearer {token}'}
- )
-
- # Should not return 403
- assert response.status_code != 403
|