Compare commits

...

2 commits

Author SHA1 Message Date
2542e3f05e
change some stuff 2024-08-19 14:05:38 +02:00
16af80ac0c
readme 2024-08-19 12:07:15 +02:00
9 changed files with 133 additions and 136 deletions

View file

@ -1,62 +1,10 @@
# rwws
# rwws - RealWeather Web Server
This project uses Quarkus, the Supersonic Subatomic Java Framework.
This contacts APIs instead of the servers because we scrape some and we don't want to draw attention
If you want to learn more about Quarkus, please visit its website: <https://quarkus.io/>.
### Usage
See `RUNNING.md`[^1]
## Running the application in dev mode
---
You can run your application in dev mode that enables live coding using:
```shell script
./mvnw compile quarkus:dev
```
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at <http://localhost:8080/q/dev/>.
## Packaging and running the application
The application can be packaged using:
```shell script
./mvnw package
```
It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.
Be aware that its not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
If you want to build an _über-jar_, execute the following command:
```shell script
./mvnw package -Dquarkus.package.jar.type=uber-jar
```
The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
## Creating a native executable
You can create a native executable using:
```shell script
./mvnw package -Dnative
```
Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
```shell script
./mvnw package -Dnative -Dquarkus.native.container-build=true
```
You can then execute your native executable with: `./target/rwws-1.0.0-SNAPSHOT-runner`
If you want to learn more about building native executables, please consult <https://quarkus.io/guides/maven-tooling>.
## Provided Code
### REST
Easily start your REST Web Services
[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)
[^1]: This is the default Quarkus readme that I wish was available online

62
RUNNING.md Normal file
View file

@ -0,0 +1,62 @@
# rwws
This project uses Quarkus, the Supersonic Subatomic Java Framework.
If you want to learn more about Quarkus, please visit its website: <https://quarkus.io/>.
## Running the application in dev mode
You can run your application in dev mode that enables live coding using:
```shell script
./mvnw compile quarkus:dev
```
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at <http://localhost:8080/q/dev/>.
## Packaging and running the application
The application can be packaged using:
```shell script
./mvnw package
```
It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.
Be aware that its not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
If you want to build an _über-jar_, execute the following command:
```shell script
./mvnw package -Dquarkus.package.jar.type=uber-jar
```
The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
## Creating a native executable
You can create a native executable using:
```shell script
./mvnw package -Dnative
```
Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
```shell script
./mvnw package -Dnative -Dquarkus.native.container-build=true
```
You can then execute your native executable with: `./target/rwws-1.0.0-SNAPSHOT-runner`
If you want to learn more about building native executables, please consult <https://quarkus.io/guides/maven-tooling>.
## Provided Code
### REST
Easily start your REST Web Services
[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)

View file

@ -16,11 +16,11 @@ public class Startup {
AccountService accountService;
@Transactional
public void loadUsers(@Observes StartupEvent event) {
public void loadUsers(@Observes StartupEvent ignoredEvent) {
Account.deleteAll();
byte[] adminKey = new byte[18];
UserManager.add(adminKey, "admin");
accountService.add(adminKey, "admin");
System.out.println("Admin user created: " + Base64.getEncoder().encodeToString(adminKey));
}
}

View file

@ -1,65 +0,0 @@
package eu.m724;
import eu.m724.orm.AccessKey;
import eu.m724.orm.AccessLimits;
import eu.m724.orm.Account;
import jakarta.transaction.Transactional;
import java.security.SecureRandom;
import java.util.Base64;
// TODO figure out all this maybe move to account service
public class UserManager {
private static final SecureRandom random = new SecureRandom();
/**
* creates an account with the specified key
* @param masterKey the desired master key
*/
@Transactional
public static void add(byte[] masterKey, String role) {
Account account = new Account();
account.masterKey = masterKey;
account.role = role;
account.persist();
}
/**
* creates an account with random key
* the account's role is "user"
* @return base64 encoded key
*/
public static String create() {
return create("user");
}
/**
* creates an account with random key
* @param role new account's role
* @return base64 encoded key
*/
public static String create(String role) {
byte[] key = new byte[18]; // 144 bits of entropy
random.nextBytes(key);
add(key, role);
return Base64.getEncoder().encodeToString(key);
}
/**
* generates an access key for this account
* @return base64 encoded access key
*/
public static String createMaster(Account account, AccessLimits accessLimits) {
byte[] key = new byte[18];
random.nextBytes(key);
AccessKey accessKey = new AccessKey();
accessKey.key = key;
accessKey.account = account;
accessKey.accessLimits = accessLimits;
accessKey.persist();
return Base64.getEncoder().encodeToString(key);
}
}

View file

@ -1,5 +1,6 @@
package eu.m724;
import eu.m724.auth.master.AccountService;
import eu.m724.orm.Account;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.annotation.security.RolesAllowed;
@ -17,11 +18,14 @@ public class UsersResource {
@Inject
SecurityIdentity securityIdentity;
@Inject
AccountService accountService;
@GET
@Path("/create")
@RolesAllowed("admin")
public JsonObject createAccount() {
String masterKey = UserManager.create();
String masterKey = accountService.create("user");
return Json.createObjectBuilder()
.add("masterKey", masterKey)

View file

@ -1,13 +1,18 @@
package eu.m724.auth.master;
import eu.m724.orm.AccessKey;
import eu.m724.orm.AccessLimits;
import eu.m724.orm.Account;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.transaction.Transactional;
import java.security.SecureRandom;
import java.util.Base64;
@ApplicationScoped
public class AccountService {
private final SecureRandom random = new SecureRandom();
/**
* find a master user by key
* @param key base64 encoded key
@ -18,9 +23,53 @@ public class AccountService {
if (key == null) return null;
try {
return Account.find("masterKey", Base64.getDecoder().decode(key)).firstResult();
return Account.find("masterKey", (Object) Base64.getDecoder().decode(key)).firstResult();
} catch (IllegalArgumentException e) {
return null;
}
}
// TODO maybe move some of these methods somewhere else and reconsider making them static
/**
* creates an account with the specified key
* @param masterKey the desired master key
*/
@Transactional
public void add(byte[] masterKey, String role) {
Account account = new Account();
account.masterKey = masterKey;
account.role = role;
account.persist();
}
/**
* creates an account with random key
* @param role new account's role
* @return base64 encoded key
*/
public String create(String role) {
byte[] key = new byte[18]; // 144 bits of entropy
random.nextBytes(key);
add(key, role);
return Base64.getEncoder().encodeToString(key);
}
/**
* generates an access key for an account
* @return base64 encoded access key
*/
public String createAccessKey(Account account, AccessLimits accessLimits) {
byte[] key = new byte[18];
random.nextBytes(key);
AccessKey accessKey = new AccessKey();
accessKey.key = key;
accessKey.account = account;
accessKey.accessLimits = accessLimits;
accessKey.persist();
return Base64.getEncoder().encodeToString(key);
}
}

View file

@ -2,7 +2,6 @@ package eu.m724.orm;
import io.quarkus.hibernate.orm.panache.PanacheEntity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
//@Entity
public class AccessKey extends PanacheEntity {
@ -20,6 +19,5 @@ public class AccessKey extends PanacheEntity {
/**
* access limits of this key
*/
@OneToOne
public AccessLimits accessLimits;
}

View file

@ -2,13 +2,10 @@ package eu.m724.orm;
import io.quarkus.hibernate.orm.panache.PanacheEntity;
import jakarta.persistence.Column;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Entity;
//@Entity
@Entity
public class AccessLimits extends PanacheEntity {
@OneToOne
public AccessKey accessKey;
/**
* label of these limits, displayed to user and used to identify the limits
*/

View file

@ -4,6 +4,10 @@ import io.quarkus.hibernate.orm.panache.PanacheEntity;
import io.quarkus.security.jpa.Roles;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
// TODO organize all this like work on variable names move functions etc
@ -12,8 +16,8 @@ public class Account extends PanacheEntity {
@Column(unique = true)
public byte[] masterKey;
//@OneToMany
//public List<AccessKey> accessKeys = new ArrayList<>();
@OneToMany
public List<AccessKey> accessKeys = new ArrayList<>();
@Roles
public String role = "user";