Files
atakanozbancom/README.md
T
Atakan Doğan Özban e97a71e5b2 Add password hashing, user settings with 2FA, and project image lightbox.
Hardens auth with PBKDF2, lockouts, local QR setup, and safer embeds while moving account security under the username menu.
2026-07-17 18:49:34 +02:00

138 lines
6.3 KiB
Markdown

# atakanozban.com
The source code for my personal portfolio website: an ASP.NET MVC 5 site with a small
custom admin panel for managing projects, affiliate links, social icons and the site
wallpaper, plus English/Turkish localization.
## Features
- Public site: home, about, my projects (with an image/iframe carousel per project),
affiliate links, dynamic social icons in the footer, and a changeable background wallpaper.
- Admin panel (`/admin`) protected by Forms Authentication:
- My Projects (bilingual posts + media carousel)
- Affiliate Links (bilingual cards with logos)
- Social Icons (footer icons)
- Wallpaper (site-wide background image)
- Optional TOTP two-factor authentication (Security page)
- My Projects: create/edit posts with EN/TR translations and a media manager
(upload images or embed iframes, drag-free reordering via a sort order field).
- Affiliate Links: create/edit links with a logo, title, description and EN/TR translations.
- Social Icons: manage the icon row shown in the site footer (Font Awesome classes + URLs).
- Wallpaper: upload a new background image for the whole site, or reset to the default.
- Security: optional TOTP two-factor authentication (Google Authenticator / Authy / etc.).
- Image uploads everywhere support both the regular file picker **and** pasting an
image straight from the clipboard (Ctrl+V).
- Public my-projects images open in a larger lightbox when clicked.
- English / Turkish localization via `.resx` resource files and a culture cookie.
## Tech stack
- ASP.NET MVC 5 / .NET Framework 4.7.2
- Entity Framework 6 (Code First, but with automatic migrations disabled — see
[Database setup](#database-setup) below)
- Microsoft SQL Server
- Bootstrap 5.3.3 and Font Awesome 6 (loaded from CDN)
## Prerequisites
- Windows with [Visual Studio 2019+](https://visualstudio.microsoft.com/) (the ".NET desktop
development" / "ASP.NET and web development" workload) or MSBuild + IIS/IIS Express
- SQL Server (LocalDB, SQL Server Express, or a full instance)
- (Optional) An FTP/hosting environment if you want to deploy it somewhere other than IIS Express
## Getting started
### 1. Clone and restore packages
```bash
git clone <this-repo-url>
cd atakanozbancom
```
Open `atakanozbancom.sln` in Visual Studio. NuGet packages will restore automatically on
build (or run `nuget restore atakanozbancom.sln` from a Developer Command Prompt).
### 2. Database setup
This project uses EF6 Code First **with `Database.SetInitializer<Context>(null)`**, meaning
Entity Framework will never create or alter tables for you — the schema is managed by hand.
1. Create an empty database (SQL Server Management Studio, Azure Data Studio, or `sqlcmd`):
```sql
CREATE DATABASE atakanozbancomdb;
```
2. Run [`database/schema.sql`](database/schema.sql) against that database. It creates every
table the app needs (admins, projects, affiliate links, social icons, site settings) and
inserts one seed admin account (`admin` / `change-this-password`).
3. **Change that seed password** (see [Security notes](#security-notes) — logins currently
compare passwords as plain text, so don't reuse a real password here).
### 3. Configure `Web.config`
Open `Web.config` and update the `connectionStrings` section to point at your SQL Server
instance:
```xml
<connectionStrings>
<add name="Context" connectionString="Data Source=YOUR_SERVER\INSTANCE;Initial Catalog=atakanozbancomdb;Integrated Security=true;" providerName="System.Data.SqlClient" />
</connectionStrings>
```
Then generate your own `<machineKey />` (see the comment above `<customErrors>` in
`Web.config` for a couple of ways to do this) and paste it into `<system.web>`. This keeps
authentication cookies and ViewState valid across app restarts/deployments — don't skip it,
and don't reuse a sample key you find online.
### 4. Run it
Press F5 in Visual Studio (or `Ctrl+F5` to skip the debugger). The site starts at the URL
shown in the IIS Express system tray icon / Visual Studio's toolbar. Log in at `/login`
with the admin account you created above, then manage content from `/admin`.
## Project structure
```
Controllers/ MVC controllers (public site + admin panel)
Models/classes/ Entity Framework models, view models, helpers
Views/ Razor views, organized by controller
App_GlobalResources/ English (.resx) and Turkish (.tr-TR.resx) translation strings
App_Start/ Routing, bundling and filter configuration
Content/uploads/ User-uploaded images (logos, project media, wallpaper) — gitignored
database/schema.sql Full database schema + seed admin account
web_atakanozbancom/ Static assets (CSS/JS/images) for the public site
```
## Uploaded content
Anything uploaded through the admin panel (project media, affiliate link logos, the
wallpaper) is written to folders under `Content/uploads/`. Those folders are tracked with
a `.gitkeep` placeholder but their contents are gitignored, since uploaded files are
runtime data, not source code.
## Security notes
This project was open-sourced as a personal portfolio/reference, not as a hardened
multi-tenant product. A few things worth knowing if you deploy your own copy or build on it:
- Optional **TOTP 2FA** and **password change** live under Admin → username menu → User Settings.
Existing installs can run `database/add-2fa.sql` then `database/harden-auth.sql`.
- Passwords are stored with **PBKDF2-SHA256** (`PasswordHasher`). On first successful login after
upgrade, any leftover plaintext password is rehashed automatically.
- **Passwords used to be stored in plain text.** If you fork an old clone, force a password change
and rotate machine keys before going live.
- The admin panel already includes `[Authorize]` on every management action and
`[ValidateAntiForgeryToken]` on every state-changing POST, so it's protected against CSRF
once you're logged in — but access is still gated by a single shared admin login rather
than per-user accounts/roles.
- File uploads are restricted to an image extension allowlist (`.jpg`, `.jpeg`, `.png`,
`.webp`, `.gif`) — SVG is intentionally excluded since it can carry executable script.
- User-entered descriptions are HTML-encoded before rendering; a small `[text](https://...)`
markdown-style syntax is the only way to add links, via `DescriptionFormatter`.
## License
MIT — see [LICENSE](LICENSE).