Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions comrade-client/google.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<title>Google Login</title>
<!-- Add Google OAuth script -->
<script src="https://accounts.google.com/gsi/client" async defer></script>
</head>
<body>
<!-- Google Sign-In button -->
<div id="g_id_onload"
data-client_id="{{ client_id }}"
data-callback="handleCredentialResponse">
</div>
<div class="g_id_signin"
data-type="standard"
data-size="large"
data-theme="outline"
data-text="sign_in_with"
data-shape="rectangular"
data-logo_alignment="left">
</div>

<script>
function handleCredentialResponse(response) {
// Send the token to your backend
fetch('/api/google-login/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
access_token: response.credential
})
})
.then(response => response.json())
.then(data => {
if (data.token) {
// Store the API token
localStorage.setItem('api_token', data.token);
console.log('Successfully logged in!');
console.log('API Token:', data.token);

// You can redirect to another page or update the UI here
// window.location.href = '/some-other-page';
}
})
.catch(error => {
console.error('Error:', error);
});
}
</script>
</body>
</html>
20 changes: 20 additions & 0 deletions comrade/clear_friends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'comrade.settings')
django.setup()

from comrade_core.models import User

def clear_friends():
# Clear all friend relationships
for user in User.objects.all():
print(f"Clearing friends for {user.username}")
user.friends.clear()
user.friend_requests_sent.clear()
user.friend_requests_received.clear()

print("Successfully cleared all friend relationships")

if __name__ == "__main__":
clear_friends()
103 changes: 97 additions & 6 deletions comrade/comrade/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import os
from pathlib import Path
import socket

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
Expand All @@ -26,9 +27,14 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ["knowing-massive-macaw.ngrok-free.app", "localhost", "127.0.0.1"]
ALLOWED_HOSTS = [
'localhost',
'127.0.0.1',
'934c-77-240-102-76.ngrok-free.app',
]

SITE_ID = 1
SITE_URL = 'https://934c-77-240-102-76.ngrok-free.app'

# Application definition

Expand Down Expand Up @@ -69,6 +75,7 @@

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
}
Expand All @@ -82,7 +89,32 @@
},
}

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
"http://localhost:8000",
"http://127.0.0.1:8000",
"https://accounts.google.com",
"https://934c-77-240-102-76.ngrok-free.app"
]
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]

ROOT_URLCONF = "comrade.urls"

Expand Down Expand Up @@ -115,10 +147,28 @@

HEADLESS_TOKEN_STRATEGY = "comrade.token_strategy.ComradeTokenStrategy"

CSRF_TRUSTED_ORIGINS = ["https://knowing-massive-macaw.ngrok-free.app"]
# Get local IP address for OAuth
def get_local_ip():
try:
# Create a socket to get the local IP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
local_ip = s.getsockname()[0]
s.close()
return local_ip
except:
return "127.0.0.1"

LOCAL_IP = get_local_ip()

CSRF_TRUSTED_ORIGINS = [
'http://localhost:8000',
'http://127.0.0.1:8000',
'https://934c-77-240-102-76.ngrok-free.app',
]

LOGIN_URL = "/accounts/login/"
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "http"
LOGIN_URL = '/login/'
ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https'


WSGI_APPLICATION = "comrade.wsgi.application"
Expand Down Expand Up @@ -177,4 +227,45 @@

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

AUTH_USER_MODEL = "comrade_core.User"
AUTH_USER_MODEL = "comrade_core.User"

# Social Account Settings
SOCIALACCOUNT_PROVIDERS = {
'google': {
'APP': {
'client_id': '838713168413-ntjqd2o22eihod384btlheuc07g5glai.apps.googleusercontent.com',
'secret': '',
'key': ''
},
'SCOPE': [
'profile',
'email',
],
'AUTH_PARAMS': {
'access_type': 'online',
'prompt': 'select_account'
}
}
}

# AllAuth Settings
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'none'
SOCIALACCOUNT_EMAIL_VERIFICATION = 'none'
SOCIALACCOUNT_QUERY_EMAIL = True
ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https'
ACCOUNT_LOGOUT_ON_GET = True

# Login/Logout URLs
LOGIN_REDIRECT_URL = '/map/'
LOGOUT_REDIRECT_URL = '/login/'

# CSRF Settings
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = False
CSRF_USE_SESSIONS = False
CSRF_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_DOMAIN = None
15 changes: 8 additions & 7 deletions comrade/comrade/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
"""

from django.contrib import admin
from django.urls import include, path
from rest_framework import routers
from django.urls import path, include
from comrade_core import views

urlpatterns = [
path("", include("comrade_core.urls")),
path("admin/", admin.site.urls),
path("api-auth/", include("rest_framework.urls")),
path("accounts/", include("allauth.urls")),
path("_allauth/", include("allauth.headless.urls")),
path('admin/', admin.site.urls),
path('', include('comrade_core.urls')), # Include all comrade_core URLs
path('accounts/', include('allauth.urls')), # allauth URLs for social auth
path('login/', views.login_page, name='login_page'), # Keep our custom login page
path('map/', views.map, name='map'),
path('api/user/info/', views.get_user_info, name='get_user_info'),
]
92 changes: 75 additions & 17 deletions comrade/comrade_core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm

from .models import Skill, Task, User
from .models import Skill, Task, User, LocationConfig, Rating, Review


class UserChangeForm(UserChangeForm):
Expand All @@ -12,30 +12,88 @@ class Meta(UserChangeForm.Meta):

class ComradeUserAdmin(UserAdmin):
form = UserChangeForm
fieldsets = UserAdmin.fieldsets + ((None, {"fields": ("skills",)}),)
list_display = ['username', 'email', 'location_sharing_level']
list_filter = ['location_sharing_level', 'is_staff', 'is_active']
search_fields = ['username', 'email', 'first_name', 'last_name']

# Add custom fields to the default UserAdmin fieldsets
fieldsets = UserAdmin.fieldsets + (
('Location', {
'fields': (
'latitude', 'longitude', 'location_sharing_level',
'location_share_with'
)
}),
('Skills & Friends', {
'fields': (
'skills', 'friends', 'friend_requests_sent'
)
}),
)
filter_horizontal = ('skills', 'friends', 'friend_requests_sent', 'location_share_with')


class TaskAdmin(admin.ModelAdmin):
list_display = [
"name",
"owner",
"state",
"lat",
"lon",
"respawn",
"respawn_time",
"base_value",
"criticality",
"contribution",
'name', 'state', 'owner', 'assignee', 'lat', 'lon',
'respawn', 'respawn_time', 'base_value', 'criticality',
'contribution', 'minutes'
]
list_filter = ["state", "respawn", "criticality"]
search_fields = ["name", "description"]
list_filter = ['state', 'respawn', 'criticality', 'owner', 'assignee']
search_fields = ['name', 'description']
filter_horizontal = ('skill_read', 'skill_write', 'skill_execute')
fieldsets = (
('Basic Info', {
'fields': ('name', 'description')
}),
('Permissions', {
'fields': ('skill_read', 'skill_write', 'skill_execute')
}),
('Task State', {
'fields': ('state', 'owner', 'assignee')
}),
('Location', {
'fields': ('lat', 'lon')
}),
('Respawn Settings', {
'fields': ('respawn', 'respawn_time')
}),
('Values', {
'fields': ('base_value', 'criticality', 'contribution', 'minutes')
}),
('Time Tracking', {
'fields': ('datetime_start', 'datetime_finish')
})
)


class SkillInline(admin.StackedInline):
model = Skill
class SkillAdmin(admin.ModelAdmin):
list_display = ['name']
search_fields = ['name']


class LocationConfigAdmin(admin.ModelAdmin):
list_display = ['max_distance_km', 'last_updated']
readonly_fields = ['last_updated']


class RatingAdmin(admin.ModelAdmin):
list_display = ['task', 'happiness', 'time']
list_filter = ['task']
search_fields = ['task__name']
fields = ['task', 'happiness', 'time']


class ReviewAdmin(admin.ModelAdmin):
list_display = ['task', 'done']
list_filter = ['task']
search_fields = ['task__name']
fields = ['task', 'done']


admin.site.register(User, ComradeUserAdmin)
admin.site.register(Task, TaskAdmin)
admin.site.register(Skill)
admin.site.register(Skill, SkillAdmin)
admin.site.register(LocationConfig, LocationConfigAdmin)
admin.site.register(Rating, RatingAdmin)
admin.site.register(Review, ReviewAdmin)
Loading