putplace 0.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of putplace might be problematic. Click here for more details.
- putplace/__init__.py +5 -0
- putplace/auth.py +279 -0
- putplace/config.py +167 -0
- putplace/database.py +387 -0
- putplace/main.py +3048 -0
- putplace/models.py +179 -0
- putplace/ppclient.py +586 -0
- putplace/ppserver.py +453 -0
- putplace/scripts/__init__.py +1 -0
- putplace/scripts/create_api_key.py +119 -0
- putplace/storage.py +456 -0
- putplace/user_auth.py +52 -0
- putplace/version.py +6 -0
- putplace-0.4.1.dist-info/METADATA +346 -0
- putplace-0.4.1.dist-info/RECORD +17 -0
- putplace-0.4.1.dist-info/WHEEL +4 -0
- putplace-0.4.1.dist-info/entry_points.txt +3 -0
putplace/models.py
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""Data models for file metadata and authentication."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FileMetadata(BaseModel):
|
|
10
|
+
"""File metadata document."""
|
|
11
|
+
|
|
12
|
+
model_config = ConfigDict(
|
|
13
|
+
json_schema_extra={
|
|
14
|
+
"example": {
|
|
15
|
+
"filepath": "/var/log/app.log",
|
|
16
|
+
"hostname": "server01",
|
|
17
|
+
"ip_address": "192.168.1.100",
|
|
18
|
+
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
19
|
+
"file_size": 2048,
|
|
20
|
+
"file_mode": 33188,
|
|
21
|
+
"file_uid": 1000,
|
|
22
|
+
"file_gid": 1000,
|
|
23
|
+
"file_mtime": 1609459200.0,
|
|
24
|
+
"file_atime": 1609459200.0,
|
|
25
|
+
"file_ctime": 1609459200.0,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
filepath: str = Field(..., description="Full path to the file")
|
|
31
|
+
hostname: str = Field(..., description="Hostname where the file is located")
|
|
32
|
+
ip_address: str = Field(..., description="IP address of the host")
|
|
33
|
+
sha256: str = Field(..., description="SHA256 hash of the file", min_length=64, max_length=64)
|
|
34
|
+
|
|
35
|
+
# File stat information
|
|
36
|
+
file_size: int = Field(..., description="File size in bytes", ge=0)
|
|
37
|
+
file_mode: int = Field(..., description="File mode (permissions)")
|
|
38
|
+
file_uid: int = Field(..., description="User ID of file owner")
|
|
39
|
+
file_gid: int = Field(..., description="Group ID of file owner")
|
|
40
|
+
file_mtime: float = Field(..., description="Modification time (Unix timestamp)")
|
|
41
|
+
file_atime: float = Field(..., description="Access time (Unix timestamp)")
|
|
42
|
+
file_ctime: float = Field(..., description="Change/creation time (Unix timestamp)")
|
|
43
|
+
|
|
44
|
+
# File content tracking
|
|
45
|
+
has_file_content: bool = Field(default=False, description="Whether server has the actual file content")
|
|
46
|
+
file_uploaded_at: Optional[datetime] = Field(None, description="When file content was uploaded")
|
|
47
|
+
storage_path: Optional[str] = Field(None, description="Full path where file content is stored (local path or S3 URI)")
|
|
48
|
+
|
|
49
|
+
# User tracking (who uploaded this file)
|
|
50
|
+
uploaded_by_user_id: Optional[str] = Field(None, description="User ID who uploaded this file")
|
|
51
|
+
uploaded_by_api_key_id: Optional[str] = Field(None, description="API key ID used to upload this file")
|
|
52
|
+
|
|
53
|
+
# Metadata timestamp
|
|
54
|
+
created_at: datetime = Field(default_factory=datetime.utcnow, description="Database record timestamp")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class FileMetadataResponse(FileMetadata):
|
|
58
|
+
"""Response model with MongoDB ID."""
|
|
59
|
+
|
|
60
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
61
|
+
|
|
62
|
+
id: Optional[str] = Field(None, alias="_id", description="MongoDB document ID")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class FileMetadataUploadResponse(FileMetadataResponse):
|
|
66
|
+
"""Response model that includes upload requirement information."""
|
|
67
|
+
|
|
68
|
+
upload_required: bool = Field(..., description="Whether client needs to upload file content")
|
|
69
|
+
upload_url: Optional[str] = Field(None, description="URL to upload file content (if required)")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Authentication models
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class APIKeyCreate(BaseModel):
|
|
76
|
+
"""Request model for creating a new API key."""
|
|
77
|
+
|
|
78
|
+
name: str = Field(..., description="Name/identifier for this API key", min_length=1, max_length=100)
|
|
79
|
+
description: Optional[str] = Field(None, description="Optional description of the key's purpose")
|
|
80
|
+
|
|
81
|
+
model_config = ConfigDict(
|
|
82
|
+
json_schema_extra={
|
|
83
|
+
"example": {
|
|
84
|
+
"name": "production-server-01",
|
|
85
|
+
"description": "API key for production server #1"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class APIKeyResponse(BaseModel):
|
|
92
|
+
"""Response model for API key creation (includes the actual key)."""
|
|
93
|
+
|
|
94
|
+
api_key: str = Field(..., description="The API key - SAVE THIS! It won't be shown again.")
|
|
95
|
+
id: str = Field(..., alias="_id", description="API key ID")
|
|
96
|
+
name: str = Field(..., description="Name of the API key")
|
|
97
|
+
description: Optional[str] = Field(None, description="Description")
|
|
98
|
+
created_at: datetime = Field(..., description="When the key was created")
|
|
99
|
+
is_active: bool = Field(..., description="Whether the key is active")
|
|
100
|
+
|
|
101
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class APIKeyInfo(BaseModel):
|
|
105
|
+
"""Information about an API key (without the actual key)."""
|
|
106
|
+
|
|
107
|
+
id: str = Field(..., alias="_id", description="API key ID")
|
|
108
|
+
name: str = Field(..., description="Name of the API key")
|
|
109
|
+
description: Optional[str] = Field(None, description="Description")
|
|
110
|
+
created_at: datetime = Field(..., description="When the key was created")
|
|
111
|
+
last_used_at: Optional[datetime] = Field(None, description="When the key was last used")
|
|
112
|
+
is_active: bool = Field(..., description="Whether the key is active")
|
|
113
|
+
|
|
114
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# User authentication models
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class UserCreate(BaseModel):
|
|
121
|
+
"""Request model for user registration."""
|
|
122
|
+
|
|
123
|
+
username: str = Field(..., description="Username", min_length=3, max_length=50)
|
|
124
|
+
email: str = Field(..., description="Email address")
|
|
125
|
+
password: str = Field(..., description="Password", min_length=8)
|
|
126
|
+
full_name: Optional[str] = Field(None, description="Full name")
|
|
127
|
+
|
|
128
|
+
model_config = ConfigDict(
|
|
129
|
+
json_schema_extra={
|
|
130
|
+
"example": {
|
|
131
|
+
"username": "johndoe",
|
|
132
|
+
"email": "john@example.com",
|
|
133
|
+
"password": "securepassword123",
|
|
134
|
+
"full_name": "John Doe"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class UserLogin(BaseModel):
|
|
141
|
+
"""Request model for user login."""
|
|
142
|
+
|
|
143
|
+
username: str = Field(..., description="Username")
|
|
144
|
+
password: str = Field(..., description="Password")
|
|
145
|
+
|
|
146
|
+
model_config = ConfigDict(
|
|
147
|
+
json_schema_extra={
|
|
148
|
+
"example": {
|
|
149
|
+
"username": "johndoe",
|
|
150
|
+
"password": "securepassword123"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class User(BaseModel):
|
|
157
|
+
"""User model (without password)."""
|
|
158
|
+
|
|
159
|
+
id: Optional[str] = Field(None, alias="_id", description="User ID")
|
|
160
|
+
username: str = Field(..., description="Username")
|
|
161
|
+
email: str = Field(..., description="Email address")
|
|
162
|
+
full_name: Optional[str] = Field(None, description="Full name")
|
|
163
|
+
is_active: bool = Field(default=True, description="Whether the user account is active")
|
|
164
|
+
created_at: datetime = Field(default_factory=datetime.utcnow, description="When the user was created")
|
|
165
|
+
|
|
166
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class Token(BaseModel):
|
|
170
|
+
"""JWT token response."""
|
|
171
|
+
|
|
172
|
+
access_token: str = Field(..., description="JWT access token")
|
|
173
|
+
token_type: str = Field(default="bearer", description="Token type")
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class TokenData(BaseModel):
|
|
177
|
+
"""Data stored in JWT token."""
|
|
178
|
+
|
|
179
|
+
username: Optional[str] = None
|