Files
ServerKit/backend/app/models/source_connection.py
T
Juan Denis 96db8df5ad Add GitHub source connections & repo picker
Introduce source provider connections to allow OAuth-backed GitHub repository selection and authenticated cloning. Backend: add SourceConnection model, SettingsService keys for GitHub OAuth, and a SourceConnectionService that handles OAuth flow, token storage (encrypted), repo/branch listing, and authenticated clone URL generation. Expose new API blueprint under /api/v1/source-connections with endpoints for status, authorize, callback, repos, branches, disconnect, and admin config. Update app creation flow to accept source_connection_id and repository_full_name, use authenticated clone URLs for cloning/deploy, and sanitize clone errors to show public repo URLs. Frontend: add SourceConnectionsTab UI, source connection callback route/component, extend App routes, and revamp New Service page to support connecting GitHub, picking repositories/branches, or using a manual git remote; update API client and styles accordingly. Note: database migration will be required to create the source_connections table and admins must configure GitHub client ID/secret.
2026-05-03 06:54:29 -04:00

43 lines
1.8 KiB
Python

from datetime import datetime
from app import db
class SourceConnection(db.Model):
"""External source-code provider connection for repository imports."""
__tablename__ = 'source_connections'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
provider = db.Column(db.String(40), nullable=False, index=True)
provider_account_id = db.Column(db.String(120), nullable=True, index=True)
provider_username = db.Column(db.String(120), nullable=True)
display_name = db.Column(db.String(180), nullable=True)
avatar_url = db.Column(db.String(500), nullable=True)
access_token_encrypted = db.Column(db.Text, nullable=False)
scope = db.Column(db.String(500), nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
last_used_at = db.Column(db.DateTime, nullable=True)
user = db.relationship('User', backref=db.backref('source_connections', lazy='dynamic'))
__table_args__ = (
db.UniqueConstraint('user_id', 'provider', name='uq_source_connection_user_provider'),
)
def to_dict(self):
return {
'id': self.id,
'provider': self.provider,
'provider_account_id': self.provider_account_id,
'provider_username': self.provider_username,
'display_name': self.display_name,
'avatar_url': self.avatar_url,
'scope': self.scope,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None,
'last_used_at': self.last_used_at.isoformat() if self.last_used_at else None,
}